mirror of
https://github.com/jenkinsci/kubernetes-operator.git
synced 2026-10-18 23:40:31 +02:00
lint with golangci-lint
This commit is contained in:
@@ -16,7 +16,7 @@ var (
|
||||
regex = regexp.MustCompile("(<application-desc main-class=\"hudson.remoting.jnlp.Main\"><argument>)(?P<secret>[a-z0-9]*)")
|
||||
)
|
||||
|
||||
// Jenkins defines Jenkins API
|
||||
// Jenkins defines Jenkins API.
|
||||
type Jenkins interface {
|
||||
GenerateToken(userName, tokenName string) (*UserToken, error)
|
||||
Info() (*gojenkins.ExecutorResponse, error)
|
||||
@@ -62,7 +62,7 @@ type jenkins struct {
|
||||
gojenkins.Jenkins
|
||||
}
|
||||
|
||||
// JenkinsAPIConnectionSettings is struct that handle information about Jenkins API connection
|
||||
// JenkinsAPIConnectionSettings is struct that handle information about Jenkins API connection.
|
||||
type JenkinsAPIConnectionSettings struct {
|
||||
Hostname string
|
||||
Port int
|
||||
@@ -86,7 +86,7 @@ func (t *setBearerToken) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
return t.transport().RoundTrip(r)
|
||||
}
|
||||
|
||||
// CreateOrUpdateJob creates or updates a job from config
|
||||
// CreateOrUpdateJob creates or updates a job from config.
|
||||
func (jenkins *jenkins) CreateOrUpdateJob(config, jobName string) (job *gojenkins.Job, created bool, err error) {
|
||||
// create or update
|
||||
job, err = jenkins.GetJob(jobName)
|
||||
@@ -102,7 +102,7 @@ func (jenkins *jenkins) CreateOrUpdateJob(config, jobName string) (job *gojenkin
|
||||
return job, false, errors.WithStack(err)
|
||||
}
|
||||
|
||||
// BuildJenkinsAPIUrl returns Jenkins API URL
|
||||
// BuildJenkinsAPIUrl returns Jenkins API URL.
|
||||
func (j JenkinsAPIConnectionSettings) BuildJenkinsAPIUrl(serviceName string, serviceNamespace string, servicePort int32, serviceNodePort int32) string {
|
||||
if j.Hostname == "" && j.Port == 0 {
|
||||
return fmt.Sprintf("http://%s.%s:%d", serviceName, serviceNamespace, servicePort)
|
||||
@@ -115,7 +115,7 @@ func (j JenkinsAPIConnectionSettings) BuildJenkinsAPIUrl(serviceName string, ser
|
||||
return fmt.Sprintf("http://%s:%d", j.Hostname, j.Port)
|
||||
}
|
||||
|
||||
// Validate validates jenkins API connection settings
|
||||
// Validate validates jenkins API connection settings.
|
||||
func (j JenkinsAPIConnectionSettings) Validate() error {
|
||||
if j.Port > 0 && j.UseNodePort {
|
||||
return errors.New("can't use service port and nodePort both. Please use port or nodePort")
|
||||
@@ -132,12 +132,12 @@ func (j JenkinsAPIConnectionSettings) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewUserAndPasswordAuthorization creates Jenkins API client with user and password authorization
|
||||
// NewUserAndPasswordAuthorization creates Jenkins API client with user and password authorization.
|
||||
func NewUserAndPasswordAuthorization(url, userName, passwordOrToken string) (Jenkins, error) {
|
||||
return newClient(url, userName, passwordOrToken)
|
||||
}
|
||||
|
||||
// NewBearerTokenAuthorization creates Jenkins API client with bearer token authorization
|
||||
// NewBearerTokenAuthorization creates Jenkins API client with bearer token authorization.
|
||||
func NewBearerTokenAuthorization(url, token string) (Jenkins, error) {
|
||||
return newClient(url, "", token)
|
||||
}
|
||||
@@ -194,10 +194,11 @@ func isNotFoundError(err error) bool {
|
||||
|
||||
func (jenkins *jenkins) GetNodeSecret(name string) (string, error) {
|
||||
var content string
|
||||
_, err := jenkins.Requester.GetXML(fmt.Sprintf("/computer/%s/slave-agent.jnlp", name), &content, nil)
|
||||
r, err := jenkins.Requester.GetXML(fmt.Sprintf("/computer/%s/slave-agent.jnlp", name), &content, nil)
|
||||
if err != nil {
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
match := regex.FindStringSubmatch(content)
|
||||
if match == nil {
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/bndr/gojenkins"
|
||||
"github.com/golang/mock/gomock"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// MockJenkins is a mock of Jenkins interface
|
||||
|
||||
@@ -48,6 +48,7 @@ func (jenkins *jenkins) executeScript(script string, verifier string) (string, e
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "couldn't execute groovy script, logs '%s'", output)
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
if r.StatusCode != http.StatusOK {
|
||||
return output, errors.Errorf("invalid status code '%d', logs '%s'", r.StatusCode, output)
|
||||
|
||||
@@ -11,6 +11,8 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const script = "some groovy code"
|
||||
|
||||
func Test_ExecuteScript(t *testing.T) {
|
||||
verifier := "verifier-text"
|
||||
t.Run("logs have verifier text", func(t *testing.T) {
|
||||
@@ -34,7 +36,6 @@ func Test_ExecuteScript(t *testing.T) {
|
||||
BasicAuth: &gojenkins.BasicAuth{Username: "unused", Password: "unused"},
|
||||
}
|
||||
|
||||
script := "some groovy code"
|
||||
logs, err := jenkinsClient.executeScript(script, verifier)
|
||||
assert.NoError(t, err, logs)
|
||||
})
|
||||
@@ -60,7 +61,6 @@ func Test_ExecuteScript(t *testing.T) {
|
||||
BasicAuth: &gojenkins.BasicAuth{Username: "unused", Password: "unused"},
|
||||
}
|
||||
|
||||
script := "some groovy code"
|
||||
logs, err := jenkinsClient.executeScript(script, verifier)
|
||||
assert.EqualError(t, err, "script execution failed", logs)
|
||||
assert.Equal(t, response, logs)
|
||||
@@ -82,7 +82,6 @@ func Test_ExecuteScript(t *testing.T) {
|
||||
BasicAuth: &gojenkins.BasicAuth{Username: "unused", Password: "unused"},
|
||||
}
|
||||
|
||||
script := "some groovy code"
|
||||
logs, err := jenkinsClient.executeScript(script, verifier)
|
||||
assert.EqualError(t, err, "invalid status code '500', logs ''", logs)
|
||||
})
|
||||
|
||||
@@ -35,10 +35,10 @@ func (jenkins *jenkins) GenerateToken(userName, tokenName string) (*UserToken, e
|
||||
endpoint := token.base
|
||||
data := map[string]string{"newTokenName": tokenName}
|
||||
r, err := jenkins.Requester.Post(endpoint, nil, token.raw, data)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "couldn't generate API token")
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
if r.StatusCode == http.StatusOK {
|
||||
if token.raw.Status == "ok" {
|
||||
|
||||
@@ -200,7 +200,7 @@ func triggerBackup(ticker *time.Ticker, k8sClient k8s.Client, logger logr.Logger
|
||||
logger.V(log.VWarn).Info(fmt.Sprintf("backup trigger, error when fetching CR: %s", err))
|
||||
}
|
||||
if jenkins.Status.LastBackup == jenkins.Status.PendingBackup {
|
||||
jenkins.Status.PendingBackup = jenkins.Status.PendingBackup + 1
|
||||
jenkins.Status.PendingBackup++
|
||||
err = k8sClient.Update(context.TODO(), jenkins)
|
||||
if err != nil {
|
||||
logger.V(log.VWarn).Info(fmt.Sprintf("backup trigger, error when updating CR: %s", err))
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
func (r *ReconcileJenkinsBaseConfiguration) compareContainers(expected corev1.Container, actual corev1.Container) (messages []string, verbose []string) {
|
||||
if !reflect.DeepEqual(expected.Args, actual.Args) {
|
||||
messages = append(messages, "Arguments have changed")
|
||||
verbose = append(messages, fmt.Sprintf("Arguments have changed to '%+v' in container '%s'", expected.Args, expected.Name))
|
||||
verbose = append(verbose, fmt.Sprintf("Arguments have changed to '%+v' in container '%s'", expected.Args, expected.Name))
|
||||
}
|
||||
if !reflect.DeepEqual(expected.Command, actual.Command) {
|
||||
messages = append(messages, "Command has changed")
|
||||
|
||||
@@ -194,7 +194,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsMasterPod(meta metav1.O
|
||||
}
|
||||
if r.Configuration.Jenkins.Spec.Backup.MakeBackupBeforePodDeletion && !r.Configuration.Jenkins.Status.BackupDoneBeforePodDeletion {
|
||||
if r.Configuration.Jenkins.Status.LastBackup == r.Configuration.Jenkins.Status.PendingBackup {
|
||||
r.Configuration.Jenkins.Status.PendingBackup = r.Configuration.Jenkins.Status.PendingBackup + 1
|
||||
r.Configuration.Jenkins.Status.PendingBackup++
|
||||
}
|
||||
if err = backupAndRestore.Backup(true); err != nil {
|
||||
return reconcile.Result{}, err
|
||||
|
||||
@@ -4,13 +4,13 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/bndr/gojenkins"
|
||||
"github.com/golang/mock/gomock"
|
||||
"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"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
||||
"github.com/bndr/gojenkins"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
)
|
||||
|
||||
|
||||
func TestCompareContainerVolumeMounts(t *testing.T) {
|
||||
t.Run("happy with service account", func(t *testing.T) {
|
||||
expectedContainer := corev1.Container{
|
||||
|
||||
@@ -172,12 +172,12 @@ GlobalConfiguration.all().get(GlobalJobDslSecurityConfiguration.class).useScript
|
||||
GlobalConfiguration.all().get(GlobalJobDslSecurityConfiguration.class).save()
|
||||
`
|
||||
|
||||
// GetBaseConfigurationConfigMapName returns name of Kubernetes config map used to base configuration
|
||||
// GetBaseConfigurationConfigMapName returns name of Kubernetes config map used to base configuration.
|
||||
func GetBaseConfigurationConfigMapName(jenkins *v1alpha2.Jenkins) string {
|
||||
return fmt.Sprintf("%s-base-configuration-%s", constants.OperatorName, jenkins.ObjectMeta.Name)
|
||||
}
|
||||
|
||||
// NewBaseConfigurationConfigMap builds Kubernetes config map used to base configuration
|
||||
// NewBaseConfigurationConfigMap builds Kubernetes config map used to base configuration.
|
||||
func NewBaseConfigurationConfigMap(meta metav1.ObjectMeta, jenkins *v1alpha2.Jenkins) (*corev1.ConfigMap, error) {
|
||||
meta.Name = GetBaseConfigurationConfigMapName(jenkins)
|
||||
jenkinsServiceFQDN, err := GetJenkinsHTTPServiceFQDN(jenkins)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"k8s.io/api/rbac/v1"
|
||||
v1 "k8s.io/api/rbac/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
||||
@@ -11,26 +11,27 @@ import (
|
||||
|
||||
//RouteKind the kind name for route
|
||||
const RouteKind = "Route"
|
||||
var isRouteAPIAvailable = false
|
||||
var routeAPIChecked = false
|
||||
|
||||
var isRouteAPIAvailable = false
|
||||
var routeAPIChecked = false
|
||||
|
||||
// UpdateRoute returns new route matching the service
|
||||
func UpdateRoute(actual routev1.Route,jenkins *v1alpha2.Jenkins) routev1.Route {
|
||||
func UpdateRoute(actual routev1.Route, jenkins *v1alpha2.Jenkins) routev1.Route {
|
||||
actualTargetService := actual.Spec.To
|
||||
serviceName := GetJenkinsHTTPServiceName(jenkins)
|
||||
if( actualTargetService.Name != serviceName ) {
|
||||
if actualTargetService.Name != serviceName {
|
||||
actual.Spec.To.Name = serviceName
|
||||
}
|
||||
port := jenkins.Spec.Service.Port
|
||||
if( actual.Spec.Port.TargetPort.IntVal != port){
|
||||
if actual.Spec.Port.TargetPort.IntVal != port {
|
||||
actual.Spec.Port.TargetPort = intstr.FromInt(int(port))
|
||||
}
|
||||
return actual
|
||||
}
|
||||
|
||||
//IsRouteAPIAvailable tells if the Route API is installed and discoverable
|
||||
func IsRouteAPIAvailable(clientSet *kubernetes.Clientset) (bool) {
|
||||
if (routeAPIChecked){
|
||||
func IsRouteAPIAvailable(clientSet *kubernetes.Clientset) bool {
|
||||
if routeAPIChecked {
|
||||
return isRouteAPIAvailable
|
||||
}
|
||||
gv := schema.GroupVersion{
|
||||
|
||||
@@ -2,6 +2,7 @@ package resources
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants"
|
||||
"github.com/operator-framework/operator-sdk/pkg/k8sutil"
|
||||
@@ -12,6 +13,7 @@ import (
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//ServiceKind the kind name for Service
|
||||
const ServiceKind = "Service"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package base
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
||||
@@ -15,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
// createRoute takes the ServiceName and Creates the Route based on it
|
||||
func (r *ReconcileJenkinsBaseConfiguration) createRoute(meta metav1.ObjectMeta, serviceName string, config *v1alpha2.Jenkins) error{
|
||||
func (r *ReconcileJenkinsBaseConfiguration) createRoute(meta metav1.ObjectMeta, serviceName string, config *v1alpha2.Jenkins) error {
|
||||
route := routev1.Route{}
|
||||
name := fmt.Sprintf("%s-%s", config.ObjectMeta.Name, config.ObjectMeta.Namespace)
|
||||
err := r.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: meta.Namespace}, &route)
|
||||
|
||||
@@ -21,6 +21,8 @@ import (
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
)
|
||||
|
||||
const defaultNamespace = "default"
|
||||
|
||||
func TestValidatePlugins(t *testing.T) {
|
||||
log.SetupLogger(true)
|
||||
baseReconcileLoop := New(configuration.Configuration{}, log.Log, client.JenkinsAPIConnectionSettings{})
|
||||
@@ -557,7 +559,6 @@ func TestValidateContainerVolumeMounts(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateConfigMapVolume(t *testing.T) {
|
||||
namespace := "default"
|
||||
t.Run("optional", func(t *testing.T) {
|
||||
optional := true
|
||||
volume := corev1.Volume{
|
||||
@@ -580,8 +581,8 @@ func TestValidateConfigMapVolume(t *testing.T) {
|
||||
})
|
||||
t.Run("happy, required", func(t *testing.T) {
|
||||
optional := false
|
||||
configMap := corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: "configmap-name"}}
|
||||
jenkins := &v1alpha2.Jenkins{ObjectMeta: metav1.ObjectMeta{Namespace: namespace}}
|
||||
configMap := corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: defaultNamespace, Name: "configmap-name"}}
|
||||
jenkins := &v1alpha2.Jenkins{ObjectMeta: metav1.ObjectMeta{Namespace: defaultNamespace}}
|
||||
volume := corev1.Volume{
|
||||
Name: "volume-name",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
@@ -608,8 +609,8 @@ func TestValidateConfigMapVolume(t *testing.T) {
|
||||
})
|
||||
t.Run("missing configmap", func(t *testing.T) {
|
||||
optional := false
|
||||
configMap := corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: "configmap-name"}}
|
||||
jenkins := &v1alpha2.Jenkins{ObjectMeta: metav1.ObjectMeta{Namespace: namespace}}
|
||||
configMap := corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Namespace: defaultNamespace, Name: "configmap-name"}}
|
||||
jenkins := &v1alpha2.Jenkins{ObjectMeta: metav1.ObjectMeta{Namespace: defaultNamespace}}
|
||||
volume := corev1.Volume{
|
||||
Name: "volume-name",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
@@ -636,7 +637,6 @@ func TestValidateConfigMapVolume(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateSecretVolume(t *testing.T) {
|
||||
namespace := "default"
|
||||
t.Run("optional", func(t *testing.T) {
|
||||
optional := true
|
||||
volume := corev1.Volume{
|
||||
@@ -659,8 +659,8 @@ func TestValidateSecretVolume(t *testing.T) {
|
||||
})
|
||||
t.Run("happy, required", func(t *testing.T) {
|
||||
optional := false
|
||||
secret := corev1.Secret{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: "secret-name"}}
|
||||
jenkins := &v1alpha2.Jenkins{ObjectMeta: metav1.ObjectMeta{Namespace: namespace}}
|
||||
secret := corev1.Secret{ObjectMeta: metav1.ObjectMeta{Namespace: defaultNamespace, Name: "secret-name"}}
|
||||
jenkins := &v1alpha2.Jenkins{ObjectMeta: metav1.ObjectMeta{Namespace: defaultNamespace}}
|
||||
volume := corev1.Volume{
|
||||
Name: "volume-name",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
@@ -685,8 +685,8 @@ func TestValidateSecretVolume(t *testing.T) {
|
||||
})
|
||||
t.Run("missing secret", func(t *testing.T) {
|
||||
optional := false
|
||||
secret := corev1.Secret{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: "secret-name"}}
|
||||
jenkins := &v1alpha2.Jenkins{ObjectMeta: metav1.ObjectMeta{Namespace: namespace}}
|
||||
secret := corev1.Secret{ObjectMeta: metav1.ObjectMeta{Namespace: defaultNamespace, Name: "secret-name"}}
|
||||
jenkins := &v1alpha2.Jenkins{ObjectMeta: metav1.ObjectMeta{Namespace: defaultNamespace}}
|
||||
volume := corev1.Volume{
|
||||
Name: "volume-name",
|
||||
VolumeSource: corev1.VolumeSource{
|
||||
@@ -710,12 +710,11 @@ func TestValidateSecretVolume(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestValidateCustomization(t *testing.T) {
|
||||
namespace := "default"
|
||||
secretName := "secretName"
|
||||
configMapName := "configmap-name"
|
||||
jenkins := &v1alpha2.Jenkins{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: namespace,
|
||||
Namespace: defaultNamespace,
|
||||
},
|
||||
}
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
@@ -739,7 +738,7 @@ func TestValidateCustomization(t *testing.T) {
|
||||
secret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: secretName,
|
||||
Namespace: namespace,
|
||||
Namespace: defaultNamespace,
|
||||
},
|
||||
}
|
||||
fakeClient := fake.NewFakeClient()
|
||||
@@ -764,13 +763,13 @@ func TestValidateCustomization(t *testing.T) {
|
||||
configMap := &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: configMapName,
|
||||
Namespace: namespace,
|
||||
Namespace: defaultNamespace,
|
||||
},
|
||||
}
|
||||
secret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: secretName,
|
||||
Namespace: namespace,
|
||||
Namespace: defaultNamespace,
|
||||
},
|
||||
}
|
||||
fakeClient := fake.NewFakeClient()
|
||||
@@ -797,7 +796,7 @@ func TestValidateCustomization(t *testing.T) {
|
||||
configMap := &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: configMapName,
|
||||
Namespace: namespace,
|
||||
Namespace: defaultNamespace,
|
||||
},
|
||||
}
|
||||
fakeClient := fake.NewFakeClient()
|
||||
@@ -822,7 +821,7 @@ func TestValidateCustomization(t *testing.T) {
|
||||
secret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: secretName,
|
||||
Namespace: namespace,
|
||||
Namespace: defaultNamespace,
|
||||
},
|
||||
}
|
||||
fakeClient := fake.NewFakeClient()
|
||||
|
||||
@@ -7,10 +7,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
||||
jenkinsclient "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/notifications/event"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/notifications/reason"
|
||||
jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client"
|
||||
stackerr "github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -166,7 +166,7 @@ func (c *Configuration) GetJenkinsMasterContainer() *v1alpha2.Container {
|
||||
|
||||
// GetJenkinsClient gets jenkins client from a configuration
|
||||
func (c *Configuration) GetJenkinsClient() (jenkinsclient.Jenkins, error) {
|
||||
switch c.Jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy {
|
||||
switch c.Jenkins.Spec.JenkinsAPISettings.AuthorizationStrategy {
|
||||
case v1alpha2.ServiceAccountAuthorizationStrategy:
|
||||
return c.GetJenkinsClientFromServiceAccount()
|
||||
case v1alpha2.CreateUserAuthorizationStrategy:
|
||||
@@ -189,7 +189,7 @@ func (c *Configuration) getJenkinsAPIUrl() (string, error) {
|
||||
}
|
||||
jenkinsURL := c.JenkinsAPIConnectionSettings.BuildJenkinsAPIUrl(service.Name, service.Namespace, service.Spec.Ports[0].Port, service.Spec.Ports[0].NodePort)
|
||||
if prefix, ok := GetJenkinsOpts(*c.Jenkins)["prefix"]; ok {
|
||||
jenkinsURL = jenkinsURL + prefix
|
||||
jenkinsURL += prefix
|
||||
}
|
||||
return jenkinsURL, nil
|
||||
}
|
||||
@@ -289,4 +289,4 @@ func GetJenkinsOpts(jenkins v1alpha2.Jenkins) map[string]string {
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package configuration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
@@ -2,9 +2,10 @@ package seedjobs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
||||
jenkinsclient "github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/client"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration"
|
||||
@@ -24,6 +25,8 @@ import (
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
)
|
||||
|
||||
const agentSecret = "test-secret"
|
||||
|
||||
func jenkinsCustomResource() *v1alpha2.Jenkins {
|
||||
return &v1alpha2.Jenkins{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -81,7 +84,6 @@ func TestEnsureSeedJobs(t *testing.T) {
|
||||
err = fakeClient.Create(ctx, jenkins)
|
||||
assert.NoError(t, err)
|
||||
|
||||
agentSecret := "test-secret"
|
||||
testNode := &gojenkins.Node{
|
||||
Raw: &gojenkins.NodeResponse{
|
||||
DisplayName: AgentName,
|
||||
@@ -123,7 +125,6 @@ func TestEnsureSeedJobs(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
defer ctrl.Finish()
|
||||
|
||||
agentSecret := "test-secret"
|
||||
jenkins := jenkinsCustomResource()
|
||||
jenkins.Spec.SeedJobs = []v1alpha2.SeedJob{}
|
||||
|
||||
@@ -174,7 +175,6 @@ func TestCreateAgent(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
defer ctrl.Finish()
|
||||
|
||||
agentSecret := "test-secret"
|
||||
jenkins := jenkinsCustomResource()
|
||||
|
||||
jenkinsClient := jenkinsclient.NewMockJenkins(ctrl)
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
|
||||
stackerr "github.com/pkg/errors"
|
||||
"github.com/robfig/cron"
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
@@ -20,9 +20,10 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
)
|
||||
|
||||
const configurationType = "test-conf-type"
|
||||
|
||||
func TestGroovy_EnsureSingle(t *testing.T) {
|
||||
log.SetupLogger(true)
|
||||
configurationType := "test-conf-type"
|
||||
emptyCustomization := v1alpha2.Customization{}
|
||||
hash := "hash"
|
||||
groovyScript := "groovy-script"
|
||||
@@ -246,7 +247,6 @@ func TestGroovy_EnsureSingle(t *testing.T) {
|
||||
assert.Equal(t, thirdGroovyScriptHash, jenkins.Status.AppliedGroovyScripts[2].Hash)
|
||||
assert.Equal(t, source, jenkins.Status.AppliedGroovyScripts[2].Source)
|
||||
assert.Equal(t, thirdGroovyScriptName, jenkins.Status.AppliedGroovyScripts[2].Name)
|
||||
|
||||
})
|
||||
t.Run("execute two groovy scripts with same names in two config maps", func(t *testing.T) {
|
||||
jenkins := &v1alpha2.Jenkins{
|
||||
@@ -349,7 +349,6 @@ func TestGroovy_EnsureSingle(t *testing.T) {
|
||||
|
||||
func TestGroovy_Ensure(t *testing.T) {
|
||||
log.SetupLogger(true)
|
||||
configurationType := "test-conf-type"
|
||||
groovyScript := "groovy-script"
|
||||
groovyScriptName := "groovy-script-name.groovy"
|
||||
ctx := context.TODO()
|
||||
@@ -615,7 +614,6 @@ func TestGroovy_Ensure(t *testing.T) {
|
||||
func TestGroovy_isGroovyScriptAlreadyApplied(t *testing.T) {
|
||||
log.SetupLogger(true)
|
||||
emptyCustomization := v1alpha2.Customization{}
|
||||
configurationType := "test-conf-type"
|
||||
|
||||
t.Run("found", func(t *testing.T) {
|
||||
jenkins := &v1alpha2.Jenkins{
|
||||
|
||||
@@ -51,7 +51,7 @@ func Add(mgr manager.Manager, jenkinsAPIConnectionSettings jenkinsclient.Jenkins
|
||||
return add(mgr, reconciler)
|
||||
}
|
||||
|
||||
// newReconciler returns a new reconcile.Reconciler
|
||||
// newReconciler returns a new reconcile.Reconciler.
|
||||
func newReconciler(mgr manager.Manager, jenkinsAPIConnectionSettings jenkinsclient.JenkinsAPIConnectionSettings, clientSet kubernetes.Clientset, config rest.Config, notificationEvents *chan event.Event) reconcile.Reconciler {
|
||||
return &ReconcileJenkins{
|
||||
client: mgr.GetClient(),
|
||||
@@ -63,7 +63,7 @@ func newReconciler(mgr manager.Manager, jenkinsAPIConnectionSettings jenkinsclie
|
||||
}
|
||||
}
|
||||
|
||||
// add adds a new Controller to mgr with r as the reconcile.Reconciler
|
||||
// add adds a new Controller to mgr with r as the reconcile.Reconciler.
|
||||
func add(mgr manager.Manager, r reconcile.Reconciler) error {
|
||||
// Create a new controller
|
||||
c, err := controller.New("jenkins-controller", mgr, controller.Options{Reconciler: r})
|
||||
@@ -111,7 +111,7 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
|
||||
|
||||
var _ reconcile.Reconciler = &ReconcileJenkins{}
|
||||
|
||||
// ReconcileJenkins reconciles a Jenkins object
|
||||
// ReconcileJenkins reconciles a Jenkins object.
|
||||
type ReconcileJenkins struct {
|
||||
client client.Client
|
||||
scheme *runtime.Scheme
|
||||
@@ -121,7 +121,7 @@ type ReconcileJenkins struct {
|
||||
notificationEvents *chan event.Event
|
||||
}
|
||||
|
||||
// Reconcile it's a main reconciliation loop which maintain desired state based on Jenkins.Spec
|
||||
// Reconcile it's a main reconciliation loop which maintain desired state based on Jenkins.Spec.
|
||||
func (r *ReconcileJenkins) Reconcile(request reconcile.Request) (reconcile.Result, error) {
|
||||
reconcileFailLimit := uint64(10)
|
||||
logger := r.buildLogger(request.Name)
|
||||
@@ -167,10 +167,8 @@ func (r *ReconcileJenkins) Reconcile(request reconcile.Request) (reconcile.Resul
|
||||
|
||||
if log.Debug {
|
||||
logger.V(log.VWarn).Info(fmt.Sprintf("Reconcile loop failed: %+v", err))
|
||||
} else {
|
||||
if err.Error() != fmt.Sprintf("Operation cannot be fulfilled on jenkins.jenkins.io \"%s\": the object has been modified; please apply your changes to the latest version and try again", request.Name) {
|
||||
logger.V(log.VWarn).Info(fmt.Sprintf("Reconcile loop failed: %s", err))
|
||||
}
|
||||
} else if err.Error() != fmt.Sprintf("Operation cannot be fulfilled on jenkins.jenkins.io \"%s\": the object has been modified; please apply your changes to the latest version and try again", request.Name) {
|
||||
logger.V(log.VWarn).Info(fmt.Sprintf("Reconcile loop failed: %s", err))
|
||||
}
|
||||
|
||||
if groovyErr, ok := err.(*jenkinsclient.GroovyScriptExecutionFailed); ok {
|
||||
@@ -227,12 +225,12 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg
|
||||
}
|
||||
|
||||
config := configuration.Configuration{
|
||||
Client: r.client,
|
||||
ClientSet: r.clientSet,
|
||||
Notifications: r.notificationEvents,
|
||||
Jenkins: jenkins,
|
||||
Scheme: r.scheme,
|
||||
Config: &r.config,
|
||||
Client: r.client,
|
||||
ClientSet: r.clientSet,
|
||||
Notifications: r.notificationEvents,
|
||||
Jenkins: jenkins,
|
||||
Scheme: r.scheme,
|
||||
Config: &r.config,
|
||||
JenkinsAPIConnectionSettings: r.jenkinsAPIConnectionSettings,
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ import (
|
||||
// Phase defines the context where notification has been generated: base or user.
|
||||
type Phase string
|
||||
|
||||
// StatusColor is useful for better UX
|
||||
// StatusColor is useful for better UX.
|
||||
type StatusColor string
|
||||
|
||||
// LoggingLevel is type for selecting different logging levels
|
||||
// LoggingLevel is type for selecting different logging levels.
|
||||
type LoggingLevel string
|
||||
|
||||
// Event contains event details which will be sent as a notification
|
||||
// Event contains event details which will be sent as a notification.
|
||||
type Event struct {
|
||||
Jenkins v1alpha2.Jenkins
|
||||
Phase Phase
|
||||
|
||||
@@ -30,11 +30,12 @@ const (
|
||||
|
||||
// NotificationTitle converts NotificationLevel enum to string
|
||||
func NotificationTitle(event event.Event) string {
|
||||
if event.Level == v1alpha2.NotificationLevelInfo {
|
||||
switch event.Level {
|
||||
case v1alpha2.NotificationLevelInfo:
|
||||
return InfoTitleText
|
||||
} else if event.Level == v1alpha2.NotificationLevelWarning {
|
||||
case v1alpha2.NotificationLevelWarning:
|
||||
return WarnTitleText
|
||||
} else {
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,66 +11,66 @@ const (
|
||||
HumanSource Source = "human"
|
||||
)
|
||||
|
||||
// Reason is interface that let us know why operator sent notification
|
||||
// Reason is interface that let us know why operator sent notification.
|
||||
type Reason interface {
|
||||
Short() []string
|
||||
Verbose() []string
|
||||
HasMessages() bool
|
||||
}
|
||||
|
||||
// Undefined is base or untraceable reason
|
||||
// Undefined is base or untraceable reason.
|
||||
type Undefined struct {
|
||||
source Source
|
||||
short []string
|
||||
verbose []string
|
||||
}
|
||||
|
||||
// PodRestart defines the reason why Jenkins master pod restarted
|
||||
// PodRestart defines the reason why Jenkins master pod restarted.
|
||||
type PodRestart struct {
|
||||
Undefined
|
||||
}
|
||||
|
||||
// PodCreation informs that pod is being created
|
||||
// PodCreation informs that pod is being created.
|
||||
type PodCreation struct {
|
||||
Undefined
|
||||
}
|
||||
|
||||
// ReconcileLoopFailed defines the reason why the reconcile loop failed
|
||||
// ReconcileLoopFailed defines the reason why the reconcile loop failed.
|
||||
type ReconcileLoopFailed struct {
|
||||
Undefined
|
||||
}
|
||||
|
||||
// GroovyScriptExecutionFailed defines the reason why the groovy script execution failed
|
||||
// GroovyScriptExecutionFailed defines the reason why the groovy script execution failed.
|
||||
type GroovyScriptExecutionFailed struct {
|
||||
Undefined
|
||||
}
|
||||
|
||||
// BaseConfigurationFailed defines the reason why base configuration phase failed
|
||||
// BaseConfigurationFailed defines the reason why base configuration phase failed.
|
||||
type BaseConfigurationFailed struct {
|
||||
Undefined
|
||||
}
|
||||
|
||||
// BaseConfigurationComplete informs that base configuration is valid and complete
|
||||
// BaseConfigurationComplete informs that base configuration is valid and complete.
|
||||
type BaseConfigurationComplete struct {
|
||||
Undefined
|
||||
}
|
||||
|
||||
// UserConfigurationFailed defines the reason why user configuration phase failed
|
||||
// UserConfigurationFailed defines the reason why user configuration phase failed.
|
||||
type UserConfigurationFailed struct {
|
||||
Undefined
|
||||
}
|
||||
|
||||
// UserConfigurationComplete informs that user configuration is valid and complete
|
||||
// UserConfigurationComplete informs that user configuration is valid and complete.
|
||||
type UserConfigurationComplete struct {
|
||||
Undefined
|
||||
}
|
||||
|
||||
// NewUndefined returns new instance of Undefined
|
||||
// NewUndefined returns new instance of Undefined.
|
||||
func NewUndefined(source Source, short []string, verbose ...string) *Undefined {
|
||||
return &Undefined{source: source, short: short, verbose: checkIfVerboseEmpty(short, verbose)}
|
||||
}
|
||||
|
||||
// NewPodRestart returns new instance of PodRestart
|
||||
// NewPodRestart returns new instance of PodRestart.
|
||||
func NewPodRestart(source Source, short []string, verbose ...string) *PodRestart {
|
||||
restartPodMessage := fmt.Sprintf("Jenkins master pod restarted by %s:", source)
|
||||
if len(short) == 1 {
|
||||
@@ -94,7 +94,7 @@ func NewPodRestart(source Source, short []string, verbose ...string) *PodRestart
|
||||
}
|
||||
}
|
||||
|
||||
// NewPodCreation returns new instance of PodCreation
|
||||
// NewPodCreation returns new instance of PodCreation.
|
||||
func NewPodCreation(source Source, short []string, verbose ...string) *PodCreation {
|
||||
return &PodCreation{
|
||||
Undefined{
|
||||
@@ -105,7 +105,7 @@ func NewPodCreation(source Source, short []string, verbose ...string) *PodCreati
|
||||
}
|
||||
}
|
||||
|
||||
// NewReconcileLoopFailed returns new instance of ReconcileLoopFailed
|
||||
// NewReconcileLoopFailed returns new instance of ReconcileLoopFailed.
|
||||
func NewReconcileLoopFailed(source Source, short []string, verbose ...string) *ReconcileLoopFailed {
|
||||
return &ReconcileLoopFailed{
|
||||
Undefined{
|
||||
@@ -116,7 +116,7 @@ func NewReconcileLoopFailed(source Source, short []string, verbose ...string) *R
|
||||
}
|
||||
}
|
||||
|
||||
// NewGroovyScriptExecutionFailed returns new instance of GroovyScriptExecutionFailed
|
||||
// NewGroovyScriptExecutionFailed returns new instance of GroovyScriptExecutionFailed.
|
||||
func NewGroovyScriptExecutionFailed(source Source, short []string, verbose ...string) *GroovyScriptExecutionFailed {
|
||||
return &GroovyScriptExecutionFailed{
|
||||
Undefined{
|
||||
@@ -127,7 +127,7 @@ func NewGroovyScriptExecutionFailed(source Source, short []string, verbose ...st
|
||||
}
|
||||
}
|
||||
|
||||
// NewBaseConfigurationFailed returns new instance of BaseConfigurationFailed
|
||||
// NewBaseConfigurationFailed returns new instance of BaseConfigurationFailed.
|
||||
func NewBaseConfigurationFailed(source Source, short []string, verbose ...string) *BaseConfigurationFailed {
|
||||
return &BaseConfigurationFailed{
|
||||
Undefined{
|
||||
@@ -138,7 +138,7 @@ func NewBaseConfigurationFailed(source Source, short []string, verbose ...string
|
||||
}
|
||||
}
|
||||
|
||||
// NewBaseConfigurationComplete returns new instance of BaseConfigurationComplete
|
||||
// NewBaseConfigurationComplete returns new instance of BaseConfigurationComplete.
|
||||
func NewBaseConfigurationComplete(source Source, short []string, verbose ...string) *BaseConfigurationComplete {
|
||||
return &BaseConfigurationComplete{
|
||||
Undefined{
|
||||
@@ -149,7 +149,7 @@ func NewBaseConfigurationComplete(source Source, short []string, verbose ...stri
|
||||
}
|
||||
}
|
||||
|
||||
// NewUserConfigurationFailed returns new instance of UserConfigurationFailed
|
||||
// NewUserConfigurationFailed returns new instance of UserConfigurationFailed.
|
||||
func NewUserConfigurationFailed(source Source, short []string, verbose ...string) *UserConfigurationFailed {
|
||||
return &UserConfigurationFailed{
|
||||
Undefined{
|
||||
@@ -160,7 +160,7 @@ func NewUserConfigurationFailed(source Source, short []string, verbose ...string
|
||||
}
|
||||
}
|
||||
|
||||
// NewUserConfigurationComplete returns new instance of UserConfigurationComplete
|
||||
// NewUserConfigurationComplete returns new instance of UserConfigurationComplete.
|
||||
func NewUserConfigurationComplete(source Source, short []string, verbose ...string) *UserConfigurationComplete {
|
||||
return &UserConfigurationComplete{
|
||||
Undefined{
|
||||
@@ -171,20 +171,20 @@ func NewUserConfigurationComplete(source Source, short []string, verbose ...stri
|
||||
}
|
||||
}
|
||||
|
||||
// Source is enum type that informs us what triggered notification
|
||||
// Source is enum type that informs us what triggered notification.
|
||||
type Source string
|
||||
|
||||
// Short is list of reasons
|
||||
// Short is list of reasons.
|
||||
func (p Undefined) Short() []string {
|
||||
return p.short
|
||||
}
|
||||
|
||||
// Verbose is list of reasons with details
|
||||
// Verbose is list of reasons with details.
|
||||
func (p Undefined) Verbose() []string {
|
||||
return p.verbose
|
||||
}
|
||||
|
||||
// HasMessages checks if there is any message
|
||||
// HasMessages checks if there is any message.
|
||||
func (p Undefined) HasMessages() bool {
|
||||
return len(p.short) > 0 || len(p.verbose) > 0
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ func TestUndefined_HasMessages(t *testing.T) {
|
||||
podRestart := NewUndefined(KubernetesSource, []string{}, []string{}...)
|
||||
assert.False(t, podRestart.HasMessages())
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestPodRestartPrepend(t *testing.T) {
|
||||
|
||||
@@ -19,12 +19,12 @@ import (
|
||||
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
// Provider is the communication service handler
|
||||
// Provider is the communication service handler.
|
||||
type Provider interface {
|
||||
Send(event event.Event) error
|
||||
}
|
||||
|
||||
// Listen listens for incoming events and send it as notifications
|
||||
// Listen listens for incoming events and send it as notifications.
|
||||
func Listen(events chan event.Event, k8sEvent k8sevent.Recorder, k8sClient k8sclient.Client) {
|
||||
httpClient := http.Client{}
|
||||
for e := range events {
|
||||
@@ -44,16 +44,16 @@ func Listen(events chan event.Event, k8sEvent k8sevent.Recorder, k8sClient k8scl
|
||||
for _, notificationConfig := range e.Jenkins.Spec.Notifications {
|
||||
var err error
|
||||
var provider Provider
|
||||
|
||||
if notificationConfig.Slack != nil {
|
||||
switch {
|
||||
case notificationConfig.Slack != nil:
|
||||
provider = slack.New(k8sClient, notificationConfig, httpClient)
|
||||
} else if notificationConfig.Teams != nil {
|
||||
case notificationConfig.Teams != nil:
|
||||
provider = msteams.New(k8sClient, notificationConfig, httpClient)
|
||||
} else if notificationConfig.Mailgun != nil {
|
||||
case notificationConfig.Mailgun != nil:
|
||||
provider = mailgun.New(k8sClient, notificationConfig)
|
||||
} else if notificationConfig.SMTP != nil {
|
||||
case notificationConfig.SMTP != nil:
|
||||
provider = smtp.New(k8sClient, notificationConfig)
|
||||
} else {
|
||||
default:
|
||||
logger.V(log.VWarn).Info(fmt.Sprintf("Unknown notification service `%+v`", notificationConfig))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -23,25 +23,25 @@ const (
|
||||
defaultColor = "#c8c8c8"
|
||||
)
|
||||
|
||||
// Slack is a Slack notification service
|
||||
// Slack is a Slack notification service.
|
||||
type Slack struct {
|
||||
httpClient http.Client
|
||||
k8sClient k8sclient.Client
|
||||
config v1alpha2.Notification
|
||||
}
|
||||
|
||||
// New returns instance of Slack
|
||||
// New returns instance of Slack.
|
||||
func New(k8sClient k8sclient.Client, config v1alpha2.Notification, httpClient http.Client) *Slack {
|
||||
return &Slack{k8sClient: k8sClient, config: config, httpClient: httpClient}
|
||||
}
|
||||
|
||||
// Message is representation of json message
|
||||
// Message is representation of json message.
|
||||
type Message struct {
|
||||
Text string `json:"text"`
|
||||
Attachments []Attachment `json:"attachments"`
|
||||
}
|
||||
|
||||
// Attachment is representation of json attachment
|
||||
// Attachment is representation of json attachment.
|
||||
type Attachment struct {
|
||||
Fallback string `json:"fallback"`
|
||||
Color event.StatusColor `json:"color"`
|
||||
@@ -117,7 +117,7 @@ func (s Slack) generateMessage(e event.Event) Message {
|
||||
return sm
|
||||
}
|
||||
|
||||
// Send is function for sending directly to API
|
||||
// Send is function for sending directly to API.
|
||||
func (s Slack) Send(e event.Event) error {
|
||||
secret := &corev1.Secret{}
|
||||
selector := s.config.Slack.WebHookURLSecretKeySelector
|
||||
|
||||
@@ -47,13 +47,13 @@ const (
|
||||
</html>`
|
||||
)
|
||||
|
||||
// SMTP is Simple Mail Transport Protocol used for sending emails
|
||||
// SMTP is Simple Mail Transport Protocol used for sending emails.
|
||||
type SMTP struct {
|
||||
k8sClient k8sclient.Client
|
||||
config v1alpha2.Notification
|
||||
}
|
||||
|
||||
// New returns instance of SMTP
|
||||
// New returns instance of SMTP.
|
||||
func New(k8sClient k8sclient.Client, config v1alpha2.Notification) *SMTP {
|
||||
return &SMTP{k8sClient: k8sClient, config: config}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ func (s SMTP) generateMessage(e event.Event) *gomail.Message {
|
||||
return message
|
||||
}
|
||||
|
||||
// Send is function for sending notification by SMTP server
|
||||
// Send is function for sending notification by SMTP server.
|
||||
func (s SMTP) Send(e event.Event) error {
|
||||
usernameSecret := &corev1.Secret{}
|
||||
passwordSecret := &corev1.Secret{}
|
||||
|
||||
@@ -37,6 +37,8 @@ const (
|
||||
fromHeader = "From"
|
||||
toHeader = "To"
|
||||
subjectHeader = "Subject"
|
||||
|
||||
nilConst = "nil"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -106,11 +108,12 @@ func (s *testSession) Data(r io.Reader) error {
|
||||
}
|
||||
|
||||
for i := range headers {
|
||||
if headers[i][1] == fromHeader && headers[i][2] != testFrom {
|
||||
switch {
|
||||
case headers[i][1] == fromHeader && headers[i][2] != testFrom:
|
||||
return fmt.Errorf("`From` header is not equal: '%s', expected '%s'", headers[i][2], testFrom)
|
||||
} else if headers[i][1] == toHeader && headers[i][2] != testTo {
|
||||
case headers[i][1] == toHeader && headers[i][2] != testTo:
|
||||
return fmt.Errorf("`To` header is not equal: '%s', expected '%s'", headers[i][2], testTo)
|
||||
} else if headers[i][1] == subjectHeader && headers[i][2] != testSubject {
|
||||
case headers[i][1] == subjectHeader && headers[i][2] != testSubject:
|
||||
return fmt.Errorf("`Subject` header is not equal: '%s', expected '%s'", headers[i][2], testSubject)
|
||||
}
|
||||
}
|
||||
@@ -242,13 +245,13 @@ func TestGenerateMessage(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("with nils", func(t *testing.T) {
|
||||
crName := "nil"
|
||||
crName := nilConst
|
||||
phase := event.PhaseBase
|
||||
level := v1alpha2.NotificationLevelInfo
|
||||
res := reason.NewUndefined(reason.KubernetesSource, []string{"nil"}, []string{"nil"}...)
|
||||
res := reason.NewUndefined(reason.KubernetesSource, []string{nilConst}, []string{nilConst}...)
|
||||
|
||||
from := "nil"
|
||||
to := "nil"
|
||||
from := nilConst
|
||||
to := nilConst
|
||||
|
||||
e := event.Event{
|
||||
Jenkins: v1alpha2.Jenkins{
|
||||
|
||||
@@ -10,7 +10,7 @@ const (
|
||||
workflowJobPlugin = "workflow-job:2.38"
|
||||
)
|
||||
|
||||
// basePluginsList contains plugins to install by operator
|
||||
// basePluginsList contains plugins to install by operator.
|
||||
var basePluginsList = []Plugin{
|
||||
Must(New(kubernetesPlugin)),
|
||||
Must(New(workflowJobPlugin)),
|
||||
@@ -21,7 +21,7 @@ var basePluginsList = []Plugin{
|
||||
Must(New(kubernetesCredentialsProviderPlugin)),
|
||||
}
|
||||
|
||||
// BasePlugins returns list of plugins to install by operator
|
||||
// BasePlugins returns list of plugins to install by operator.
|
||||
func BasePlugins() []Plugin {
|
||||
return basePluginsList
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Plugin represents jenkins plugin
|
||||
// Plugin represents jenkins plugin.
|
||||
type Plugin struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
@@ -29,7 +29,7 @@ var (
|
||||
DownloadURLPattern = regexp.MustCompile(`https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)`)
|
||||
)
|
||||
|
||||
// New creates plugin from string, for example "name-of-plugin:0.0.1"
|
||||
// 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 {
|
||||
@@ -48,7 +48,7 @@ func New(nameWithVersion string) (*Plugin, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewPlugin creates plugin from name and version, for example "name-of-plugin:0.0.1"
|
||||
// NewPlugin creates plugin from name and version, for example "name-of-plugin:0.0.1".
|
||||
func NewPlugin(name, version, downloadURL string) (*Plugin, error) {
|
||||
if err := validatePlugin(name, version, downloadURL); err != nil {
|
||||
return nil, err
|
||||
@@ -76,7 +76,7 @@ func validatePlugin(name, version, downloadURL string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Must returns plugin from pointer and throws panic when error is set
|
||||
// Must returns plugin from pointer and throws panic when error is set.
|
||||
func Must(plugin *Plugin, err error) Plugin {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -85,7 +85,7 @@ func Must(plugin *Plugin, err error) Plugin {
|
||||
return *plugin
|
||||
}
|
||||
|
||||
// VerifyDependencies checks if all plugins have compatible versions
|
||||
// VerifyDependencies checks if all plugins have compatible versions.
|
||||
func VerifyDependencies(values ...map[Plugin][]Plugin) []string {
|
||||
var messages []string
|
||||
// key - plugin name, value array of versions
|
||||
|
||||
Reference in New Issue
Block a user