Small code improvements

This commit is contained in:
Tomasz Sęk 2019-08-19 16:56:17 +02:00
parent 64f6fa68eb
commit 89c46a1720
No known key found for this signature in database
GPG Key ID: DC356D23F6A644D0
15 changed files with 118 additions and 110 deletions

View File

@ -32,4 +32,3 @@ spec:
fieldPath: metadata.name fieldPath: metadata.name
- name: OPERATOR_NAME - name: OPERATOR_NAME
value: "jenkins-operator" value: "jenkins-operator"

View File

@ -424,7 +424,7 @@ spec:
- name: JENKINS_HOME - name: JENKINS_HOME
value: /jenkins-home value: /jenkins-home
- name: BACKUP_COUNT - name: BACKUP_COUNT
value: "2" # keep only the 2 most recent backups value: "3" # keep only the 2 most recent backups
image: virtuslab/jenkins-operator-backup-pvc:v0.0.5 # look at backup/pvc directory image: virtuslab/jenkins-operator-backup-pvc:v0.0.5 # look at backup/pvc directory
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
volumeMounts: volumeMounts:

View File

@ -569,7 +569,7 @@ spec:
- name: JENKINS_HOME - name: JENKINS_HOME
value: /jenkins-home value: /jenkins-home
- name: BACKUP_COUNT - name: BACKUP_COUNT
value: "2" # keep only the 2 most recent backups value: "3" # keep only the 2 most recent backups
image: virtuslab/jenkins-operator-backup-pvc:v0.0.5 # look at backup/pvc directory image: virtuslab/jenkins-operator-backup-pvc:v0.0.5 # look at backup/pvc directory
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
volumeMounts: volumeMounts:

View File

@ -17,8 +17,8 @@ type JenkinsSpec struct {
// +optional // +optional
SeedJobs []SeedJob `json:"seedJobs,omitempty"` SeedJobs []SeedJob `json:"seedJobs,omitempty"`
// Notifications defines services which are used to inform about Jenkins status // Notifications defines list of a services which are used to inform about Jenkins status
// Can be used to integrate chat services like Slack or Email services like Mailgun // Can be used to integrate chat services like Slack, Microsoft MicrosoftTeams or Mailgun
Notifications []Notification `json:"notifications,omitempty"` Notifications []Notification `json:"notifications,omitempty"`
// Service is Kubernetes service of Jenkins master HTTP pod // Service is Kubernetes service of Jenkins master HTTP pod
@ -54,29 +54,40 @@ type JenkinsSpec struct {
ConfigurationAsCode ConfigurationAsCode `json:"configurationAsCode,omitempty"` ConfigurationAsCode ConfigurationAsCode `json:"configurationAsCode,omitempty"`
} }
// Notification is info sending service about Jenkins Operator // NotificationLogLevel defines logging level of Notification
type NotificationLogLevel string
const (
// NotificationLogLevelWarning - Only Warnings
NotificationLogLevelWarning NotificationLogLevel = "warning"
// NotificationLogLevelInfo - Only info
NotificationLogLevelInfo NotificationLogLevel = "info"
)
// Notification is a service configuration used to send notifications about Jenkins status
type Notification struct { type Notification struct {
LoggingLevel JenkinsNotificationLogLevel `json:"loggingLevel"` LoggingLevel NotificationLogLevel `json:"loggingLevel"`
Verbose bool `json:"verbose"` Verbose bool `json:"verbose"`
Name string `json:"name"` Name string `json:"name"`
Slack Slack `json:"slack,omitempty"` Slack *Slack `json:"slack,omitempty"`
Teams Teams `json:"teams,omitempty"` Teams *MicrosoftTeams `json:"teams,omitempty"`
Mailgun Mailgun `json:"mailgun,omitempty"` Mailgun *Mailgun `json:"mailgun,omitempty"`
} }
// Slack is handler for Slack // Slack is handler for Slack notification channel
type Slack struct { type Slack struct {
// The web hook URL to Slack App // The web hook URL to Slack App
URLSecretKeySelector SecretKeySelector `json:"urlSecretKeySelector"` WebHookURLSecretKeySelector SecretKeySelector `json:"webHookURLSecretKeySelector"`
} }
// Teams is handler for Microsoft Teams // MicrosoftTeams is handler for Microsoft MicrosoftTeams notification channel
type Teams struct { type MicrosoftTeams struct {
// The web hook URL to Teams App // The web hook URL to MicrosoftTeams App
URLSecretKeySelector SecretKeySelector `json:"urlSecretKeySelector"` WebHookURLSecretKeySelector SecretKeySelector `json:"webHookURLSecretKeySelector"`
} }
// Mailgun is handler for Mailgun email service // Mailgun is handler for Mailgun email service notification channel
type Mailgun struct { type Mailgun struct {
Domain string `json:"domain"` Domain string `json:"domain"`
APIKeySecretKeySelector SecretKeySelector `json:"apiKeySecretKeySelector"` APIKeySecretKeySelector SecretKeySelector `json:"apiKeySecretKeySelector"`
@ -87,9 +98,9 @@ type Mailgun struct {
// SecretKeySelector selects a key of a Secret. // SecretKeySelector selects a key of a Secret.
type SecretKeySelector struct { type SecretKeySelector struct {
// The name of the secret in the pod's namespace to select from. // The name of the secret in the pod's namespace to select from.
corev1.LocalObjectReference `json:",inline" protobuf:"bytes,1,opt,name=localObjectReference"` corev1.LocalObjectReference `json:"secret"`
// The key of the secret to select from. Must be a valid secret key. // The key of the secret to select from. Must be a valid secret key.
Key string `json:"key" protobuf:"bytes,2,opt,name=key"` Key string `json:"key"`
} }
// Container defines Kubernetes container attributes // Container defines Kubernetes container attributes
@ -485,17 +496,6 @@ const (
UsernamePasswordCredentialType JenkinsCredentialType = "usernamePassword" UsernamePasswordCredentialType JenkinsCredentialType = "usernamePassword"
) )
// JenkinsNotificationLogLevel defines type of Notification feature frequency of sending logger entries
type JenkinsNotificationLogLevel string
const (
// LogLevelWarning - Only Warnings
LogLevelWarning JenkinsNotificationLogLevel = "warning"
// LogLevelInfo - Only info
LogLevelInfo JenkinsNotificationLogLevel = "info"
)
// AllowedJenkinsCredentialMap contains all allowed Jenkins credentials types // AllowedJenkinsCredentialMap contains all allowed Jenkins credentials types
var AllowedJenkinsCredentialMap = map[string]string{ var AllowedJenkinsCredentialMap = map[string]string{
string(NoJenkinsCredentialCredentialType): "", string(NoJenkinsCredentialCredentialType): "",

View File

@ -369,7 +369,9 @@ func (in *JenkinsSpec) DeepCopyInto(out *JenkinsSpec) {
if in.Notifications != nil { if in.Notifications != nil {
in, out := &in.Notifications, &out.Notifications in, out := &in.Notifications, &out.Notifications
*out = make([]Notification, len(*in)) *out = make([]Notification, len(*in))
copy(*out, *in) for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
} }
in.Service.DeepCopyInto(&out.Service) in.Service.DeepCopyInto(&out.Service)
in.SlaveService.DeepCopyInto(&out.SlaveService) in.SlaveService.DeepCopyInto(&out.SlaveService)
@ -452,12 +454,41 @@ func (in *Mailgun) DeepCopy() *Mailgun {
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MicrosoftTeams) DeepCopyInto(out *MicrosoftTeams) {
*out = *in
out.WebHookURLSecretKeySelector = in.WebHookURLSecretKeySelector
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MicrosoftTeams.
func (in *MicrosoftTeams) DeepCopy() *MicrosoftTeams {
if in == nil {
return nil
}
out := new(MicrosoftTeams)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Notification) DeepCopyInto(out *Notification) { func (in *Notification) DeepCopyInto(out *Notification) {
*out = *in *out = *in
out.Slack = in.Slack if in.Slack != nil {
out.Teams = in.Teams in, out := &in.Slack, &out.Slack
out.Mailgun = in.Mailgun *out = new(Slack)
**out = **in
}
if in.Teams != nil {
in, out := &in.Teams, &out.Teams
*out = new(MicrosoftTeams)
**out = **in
}
if in.Mailgun != nil {
in, out := &in.Mailgun, &out.Mailgun
*out = new(Mailgun)
**out = **in
}
return return
} }
@ -591,7 +622,7 @@ func (in *Service) DeepCopy() *Service {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Slack) DeepCopyInto(out *Slack) { func (in *Slack) DeepCopyInto(out *Slack) {
*out = *in *out = *in
out.URLSecretKeySelector = in.URLSecretKeySelector out.WebHookURLSecretKeySelector = in.WebHookURLSecretKeySelector
return return
} }
@ -604,20 +635,3 @@ func (in *Slack) DeepCopy() *Slack {
in.DeepCopyInto(out) in.DeepCopyInto(out)
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Teams) DeepCopyInto(out *Teams) {
*out = *in
out.URLSecretKeySelector = in.URLSecretKeySelector
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Teams.
func (in *Teams) DeepCopy() *Teams {
if in == nil {
return nil
}
out := new(Teams)
in.DeepCopyInto(out)
return out
}

View File

@ -127,14 +127,14 @@ func (r *ReconcileJenkinsBaseConfiguration) Reconcile() (reconcile.Result, jenki
return result, jenkinsClient, err return result, jenkinsClient, err
} }
// GetJenkinsOpts put container JENKINS_OPTS env parameters in map and returns it // GetJenkinsOpts gets JENKINS_OPTS env parameter, parses it's values and returns it as a map`
func GetJenkinsOpts(jenkins *v1alpha2.Jenkins) map[string]string { func GetJenkinsOpts(jenkins v1alpha2.Jenkins) map[string]string {
envs := jenkins.Spec.Master.Containers[0].Env envs := jenkins.Spec.Master.Containers[0].Env
jenkinsOpts := make(map[string]string) jenkinsOpts := make(map[string]string)
for k, v := range envs { for key, value := range envs {
if v.Name == "JENKINS_OPTS" { if value.Name == "JENKINS_OPTS" {
jenkinsOptsEnv := envs[k] jenkinsOptsEnv := envs[key]
jenkinsOptsWithDashes := jenkinsOptsEnv.Value jenkinsOptsWithDashes := jenkinsOptsEnv.Value
if len(jenkinsOptsWithDashes) == 0 { if len(jenkinsOptsWithDashes) == 0 {
return nil return nil
@ -781,7 +781,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient(meta metav1.Obje
jenkinsURL, err := jenkinsclient.BuildJenkinsAPIUrl( jenkinsURL, err := jenkinsclient.BuildJenkinsAPIUrl(
r.jenkins.ObjectMeta.Namespace, resources.GetJenkinsHTTPServiceName(r.jenkins), r.jenkins.Spec.Service.Port, r.local, r.minikube) r.jenkins.ObjectMeta.Namespace, resources.GetJenkinsHTTPServiceName(r.jenkins), r.jenkins.Spec.Service.Port, r.local, r.minikube)
if prefix, ok := GetJenkinsOpts(r.jenkins)["prefix"]; ok { if prefix, ok := GetJenkinsOpts(*r.jenkins)["prefix"]; ok {
jenkinsURL = jenkinsURL + prefix jenkinsURL = jenkinsURL + prefix
} }

View File

@ -16,7 +16,7 @@ import (
func TestGetJenkinsOpts(t *testing.T) { func TestGetJenkinsOpts(t *testing.T) {
t.Run("JENKINS_OPTS is uninitialized", func(t *testing.T) { t.Run("JENKINS_OPTS is uninitialized", func(t *testing.T) {
jenkins := &v1alpha2.Jenkins{ jenkins := v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{ Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{ Master: v1alpha2.JenkinsMaster{
Containers: []v1alpha2.Container{ Containers: []v1alpha2.Container{
@ -35,7 +35,7 @@ func TestGetJenkinsOpts(t *testing.T) {
}) })
t.Run("JENKINS_OPTS is empty", func(t *testing.T) { t.Run("JENKINS_OPTS is empty", func(t *testing.T) {
jenkins := &v1alpha2.Jenkins{ jenkins := v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{ Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{ Master: v1alpha2.JenkinsMaster{
Containers: []v1alpha2.Container{ Containers: []v1alpha2.Container{
@ -54,7 +54,7 @@ func TestGetJenkinsOpts(t *testing.T) {
}) })
t.Run("JENKINS_OPTS have --prefix argument ", func(t *testing.T) { t.Run("JENKINS_OPTS have --prefix argument ", func(t *testing.T) {
jenkins := &v1alpha2.Jenkins{ jenkins := v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{ Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{ Master: v1alpha2.JenkinsMaster{
Containers: []v1alpha2.Container{ Containers: []v1alpha2.Container{
@ -77,7 +77,7 @@ func TestGetJenkinsOpts(t *testing.T) {
}) })
t.Run("JENKINS_OPTS have --prefix and --httpPort argument", func(t *testing.T) { t.Run("JENKINS_OPTS have --prefix and --httpPort argument", func(t *testing.T) {
jenkins := &v1alpha2.Jenkins{ jenkins := v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{ Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{ Master: v1alpha2.JenkinsMaster{
Containers: []v1alpha2.Container{ Containers: []v1alpha2.Container{
@ -103,7 +103,7 @@ func TestGetJenkinsOpts(t *testing.T) {
}) })
t.Run("JENKINS_OPTS have --httpPort argument", func(t *testing.T) { t.Run("JENKINS_OPTS have --httpPort argument", func(t *testing.T) {
jenkins := &v1alpha2.Jenkins{ jenkins := v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{ Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{ Master: v1alpha2.JenkinsMaster{
Containers: []v1alpha2.Container{ Containers: []v1alpha2.Container{
@ -126,7 +126,7 @@ func TestGetJenkinsOpts(t *testing.T) {
}) })
t.Run("JENKINS_OPTS have --httpPort=--8080 argument", func(t *testing.T) { t.Run("JENKINS_OPTS have --httpPort=--8080 argument", func(t *testing.T) {
jenkins := &v1alpha2.Jenkins{ jenkins := v1alpha2.Jenkins{
Spec: v1alpha2.JenkinsSpec{ Spec: v1alpha2.JenkinsSpec{
Master: v1alpha2.JenkinsMaster{ Master: v1alpha2.JenkinsMaster{
Containers: []v1alpha2.Container{ Containers: []v1alpha2.Container{

View File

@ -231,9 +231,9 @@ func NewJenkinsMasterContainer(jenkins *v1alpha2.Jenkins) corev1.Container {
}, },
}, },
SecurityContext: jenkinsContainer.SecurityContext, SecurityContext: jenkinsContainer.SecurityContext,
Env: envs, Env: envs,
Resources: jenkinsContainer.Resources, Resources: jenkinsContainer.Resources,
VolumeMounts: append(GetJenkinsMasterContainerBaseVolumeMounts(jenkins), jenkinsContainer.VolumeMounts...), VolumeMounts: append(GetJenkinsMasterContainerBaseVolumeMounts(jenkins), jenkinsContainer.VolumeMounts...),
} }
} }

View File

@ -61,40 +61,42 @@ func (r *ReconcileJenkinsBaseConfiguration) Validate(jenkins *v1alpha2.Jenkins)
} }
func (r *ReconcileJenkinsBaseConfiguration) validateImagePullSecrets() (bool, error) { func (r *ReconcileJenkinsBaseConfiguration) validateImagePullSecrets() (bool, error) {
var err error
for _, sr := range r.jenkins.Spec.Master.ImagePullSecrets { for _, sr := range r.jenkins.Spec.Master.ImagePullSecrets {
valid, err := r.validateImagePullSecret(sr.Name) valid, err := r.validateImagePullSecret(sr.Name)
if err != nil || !valid { if err != nil {
return false, err
}
if !valid {
return false, nil return false, nil
} }
} }
return true, err return true, nil
} }
func (r *ReconcileJenkinsBaseConfiguration) validateImagePullSecret(name string) (bool, error) { func (r *ReconcileJenkinsBaseConfiguration) validateImagePullSecret(secretName string) (bool, error) {
secret := &corev1.Secret{} secret := &corev1.Secret{}
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: r.jenkins.ObjectMeta.Namespace}, secret) err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: secretName, Namespace: r.jenkins.ObjectMeta.Namespace}, secret)
if err != nil && apierrors.IsNotFound(err) { if err != nil && apierrors.IsNotFound(err) {
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret %s not found defined in spec.master.imagePullSecrets", name)) r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret %s not found defined in spec.master.imagePullSecrets", secretName))
return false, nil return false, nil
} else if err != nil && !apierrors.IsNotFound(err) { } else if err != nil && !apierrors.IsNotFound(err) {
return false, stackerr.WithStack(err) return false, stackerr.WithStack(err)
} }
if secret.Data["docker-server"] == nil { if secret.Data["docker-server"] == nil {
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-server' key.", name)) r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-server' key.", secretName))
return false, nil return false, nil
} }
if secret.Data["docker-username"] == nil { if secret.Data["docker-username"] == nil {
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-username' key.", name)) r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-username' key.", secretName))
return false, nil return false, nil
} }
if secret.Data["docker-password"] == nil { if secret.Data["docker-password"] == nil {
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-password' key.", name)) r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-password' key.", secretName))
return false, nil return false, nil
} }
if secret.Data["docker-email"] == nil { if secret.Data["docker-email"] == nil {
r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-email' key.", name)) r.logger.V(log.VWarn).Info(fmt.Sprintf("Secret '%s' defined in spec.master.imagePullSecrets doesn't have 'docker-email' key.", secretName))
return false, nil return false, nil
} }

View File

@ -40,16 +40,16 @@ const content = `
</body> </body>
</html>` </html>`
// MailGun is service for sending emails // MailGun is a sending emails notification service
type MailGun struct { type MailGun struct {
k8sClient k8sclient.Client k8sClient k8sclient.Client
} }
func (m MailGun) getStatusColor(logLevel LoggingLevel) StatusColor { func (m MailGun) getStatusColor(logLevel v1alpha2.NotificationLogLevel) StatusColor {
switch logLevel { switch logLevel {
case LogInfo: case v1alpha2.NotificationLogLevelInfo:
return "blue" return "blue"
case LogWarn: case v1alpha2.NotificationLogLevelWarning:
return "red" return "red"
default: default:
return "gray" return "gray"

View File

@ -14,7 +14,7 @@ import (
k8sclient "sigs.k8s.io/controller-runtime/pkg/client" k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
) )
// Teams is Microsoft Teams Service // Teams is a Microsoft MicrosoftTeams notification service
type Teams struct { type Teams struct {
k8sClient k8sclient.Client k8sClient k8sclient.Client
} }
@ -40,11 +40,11 @@ type TeamsFact struct {
Value string `json:"value"` Value string `json:"value"`
} }
func (t Teams) getStatusColor(logLevel LoggingLevel) StatusColor { func (t Teams) getStatusColor(logLevel v1alpha2.NotificationLogLevel) StatusColor {
switch logLevel { switch logLevel {
case LogInfo: case v1alpha2.NotificationLogLevelInfo:
return "439FE0" return "439FE0"
case LogWarn: case v1alpha2.NotificationLogLevelWarning:
return "E81123" return "E81123"
default: default:
return "C8C8C8" return "C8C8C8"
@ -55,7 +55,7 @@ func (t Teams) getStatusColor(logLevel LoggingLevel) StatusColor {
func (t Teams) Send(event Event, config v1alpha2.Notification) error { func (t Teams) Send(event Event, config v1alpha2.Notification) error {
secret := &corev1.Secret{} secret := &corev1.Secret{}
selector := config.Teams.URLSecretKeySelector selector := config.Teams.WebHookURLSecretKeySelector
err := t.k8sClient.Get(context.TODO(), types.NamespacedName{Name: selector.Name, Namespace: event.Jenkins.Namespace}, secret) err := t.k8sClient.Get(context.TODO(), types.NamespacedName{Name: selector.Name, Namespace: event.Jenkins.Namespace}, secret)
if err != nil { if err != nil {

View File

@ -84,8 +84,8 @@ func TestTeams_Send(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
err = teams.Send(event, v1alpha2.Notification{ err = teams.Send(event, v1alpha2.Notification{
Teams: v1alpha2.Teams{ Teams: &v1alpha2.MicrosoftTeams{
URLSecretKeySelector: v1alpha2.SecretKeySelector{ WebHookURLSecretKeySelector: v1alpha2.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{ LocalObjectReference: corev1.LocalObjectReference{
Name: testSecretName, Name: testSecretName,
}, },

View File

@ -12,12 +12,6 @@ import (
) )
const ( const (
// LogWarn is warning log entry
LogWarn LoggingLevel = "warn"
// LogInfo is info log entry
LogInfo LoggingLevel = "info"
titleText = "Operator reconciled." titleText = "Operator reconciled."
messageFieldName = "Message" messageFieldName = "Message"
loggingLevelFieldName = "Logging Level" loggingLevelFieldName = "Logging Level"
@ -33,7 +27,7 @@ var (
testNamespace = "default" testNamespace = "default"
testMessage = "test-message" testMessage = "test-message"
testMessageVerbose = "detail-test-message" testMessageVerbose = "detail-test-message"
testLoggingLevel = LogWarn testLoggingLevel = v1alpha2.NotificationLogLevelWarning
client = http.Client{} client = http.Client{}
) )
@ -48,7 +42,7 @@ type LoggingLevel string
type Event struct { type Event struct {
Jenkins v1alpha2.Jenkins Jenkins v1alpha2.Jenkins
ConfigurationType string ConfigurationType string
LogLevel LoggingLevel LogLevel v1alpha2.NotificationLogLevel
Message string Message string
MessageVerbose string MessageVerbose string
} }
@ -65,11 +59,11 @@ func Listen(events chan Event, k8sClient k8sclient.Client) {
var err error var err error
var svc service var svc service
if notificationConfig.Slack != (v1alpha2.Slack{}) { if notificationConfig.Slack != nil {
svc = Slack{k8sClient: k8sClient} svc = Slack{k8sClient: k8sClient}
} else if notificationConfig.Teams != (v1alpha2.Teams{}) { } else if notificationConfig.Teams != nil {
svc = Teams{k8sClient: k8sClient} svc = Teams{k8sClient: k8sClient}
} else if notificationConfig.Mailgun != (v1alpha2.Mailgun{}) { } else if notificationConfig.Mailgun != nil {
svc = MailGun{k8sClient: k8sClient} svc = MailGun{k8sClient: k8sClient}
} else { } else {
logger.V(log.VWarn).Info(fmt.Sprintf("Unexpected notification `%+v`", notificationConfig)) logger.V(log.VWarn).Info(fmt.Sprintf("Unexpected notification `%+v`", notificationConfig))
@ -93,7 +87,7 @@ func Listen(events chan Event, k8sClient k8sclient.Client) {
} }
func notify(svc service, event Event, manifest v1alpha2.Notification) error { func notify(svc service, event Event, manifest v1alpha2.Notification) error {
if event.LogLevel == LogInfo && string(manifest.LoggingLevel) == string(LogWarn) { if event.LogLevel == v1alpha2.NotificationLogLevelInfo && manifest.LoggingLevel == v1alpha2.NotificationLogLevelWarning {
return nil return nil
} }

View File

@ -14,7 +14,7 @@ import (
k8sclient "sigs.k8s.io/controller-runtime/pkg/client" k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
) )
// Slack is messaging service // Slack is a Slack notification service
type Slack struct { type Slack struct {
k8sClient k8sclient.Client k8sClient k8sclient.Client
} }
@ -43,11 +43,11 @@ type SlackField struct {
Short bool `json:"short"` Short bool `json:"short"`
} }
func (s Slack) getStatusColor(logLevel LoggingLevel) StatusColor { func (s Slack) getStatusColor(logLevel v1alpha2.NotificationLogLevel) StatusColor {
switch logLevel { switch logLevel {
case LogInfo: case v1alpha2.NotificationLogLevelInfo:
return "#439FE0" return "#439FE0"
case LogWarn: case v1alpha2.NotificationLogLevelWarning:
return "danger" return "danger"
default: default:
return "#c8c8c8" return "#c8c8c8"
@ -57,7 +57,7 @@ func (s Slack) getStatusColor(logLevel LoggingLevel) StatusColor {
// Send is function for sending directly to API // Send is function for sending directly to API
func (s Slack) Send(event Event, config v1alpha2.Notification) error { func (s Slack) Send(event Event, config v1alpha2.Notification) error {
secret := &corev1.Secret{} secret := &corev1.Secret{}
selector := config.Slack.URLSecretKeySelector selector := config.Slack.WebHookURLSecretKeySelector
err := s.k8sClient.Get(context.TODO(), types.NamespacedName{Name: selector.Name, Namespace: event.Jenkins.Namespace}, secret) err := s.k8sClient.Get(context.TODO(), types.NamespacedName{Name: selector.Name, Namespace: event.Jenkins.Namespace}, secret)
if err != nil { if err != nil {

View File

@ -84,8 +84,8 @@ func TestSlack_Send(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
err = slack.Send(event, v1alpha2.Notification{ err = slack.Send(event, v1alpha2.Notification{
Slack: v1alpha2.Slack{ Slack: &v1alpha2.Slack{
URLSecretKeySelector: v1alpha2.SecretKeySelector{ WebHookURLSecretKeySelector: v1alpha2.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{ LocalObjectReference: corev1.LocalObjectReference{
Name: testSecretName, Name: testSecretName,
}, },
@ -93,6 +93,5 @@ func TestSlack_Send(t *testing.T) {
}, },
}, },
}) })
assert.NoError(t, err) assert.NoError(t, err)
} }