package smtp import ( "context" "crypto/tls" "fmt" "strings" "github.com/jenkinsci/kubernetes-operator/api/v1alpha2" "github.com/jenkinsci/kubernetes-operator/pkg/notifications/event" "github.com/jenkinsci/kubernetes-operator/pkg/notifications/provider" "github.com/pkg/errors" "gopkg.in/gomail.v2" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" k8sclient "sigs.k8s.io/controller-runtime/pkg/client" ) const ( mailSubject = "Jenkins Operator Notification" infoColor = "blue" warningColor = "red" defaultColor = "gray" content = `

%s

%s

CR name: %s
Phase: %s
Powered by Jenkins Operator <3
` ) // SMTP is Simple Mail Transport Protocol used for sending emails. type SMTP struct { k8sClient k8sclient.Client config v1alpha2.Notification } // New returns instance of SMTP. func New(k8sClient k8sclient.Client, config v1alpha2.Notification) *SMTP { return &SMTP{k8sClient: k8sClient, config: config} } func (s SMTP) generateMessage(e event.Event) *gomail.Message { var statusMessage strings.Builder var reasons string if s.config.Verbose { reasons = strings.TrimRight(strings.Join(e.Reason.Verbose(), "
  • "), "
  • ") } else { reasons = strings.TrimRight(strings.Join(e.Reason.Short(), "
  • "), "
  • ") } statusMessage.WriteString("") htmlMessage := fmt.Sprintf( content, s.getStatusColor(e.Level), provider.NotificationTitle(e), statusMessage.String(), e.Jenkins.Name, e.Phase, ) message := gomail.NewMessage() message.SetHeader("From", s.config.SMTP.From) message.SetHeader("To", s.config.SMTP.To) message.SetHeader("Subject", mailSubject) message.SetBody("text/html", htmlMessage) return message } // Send is function for sending notification by SMTP server. func (s SMTP) Send(e event.Event) error { usernameSecret := &corev1.Secret{} passwordSecret := &corev1.Secret{} usernameSelector := s.config.SMTP.UsernameSecretKeySelector passwordSelector := s.config.SMTP.PasswordSecretKeySelector err := s.k8sClient.Get(context.TODO(), types.NamespacedName{ Name: usernameSelector.Name, Namespace: e.Jenkins.Namespace, }, usernameSecret, ) if err != nil { return err } err = s.k8sClient.Get(context.TODO(), types.NamespacedName{ Name: passwordSelector.Name, Namespace: e.Jenkins.Namespace, }, passwordSecret, ) if err != nil { return err } usernameSecretValue := string(usernameSecret.Data[usernameSelector.Key]) if usernameSecretValue == "" { return errors.Errorf("SMTP username is empty in secret '%s/%s[%s]", e.Jenkins.Namespace, usernameSelector.Name, usernameSelector.Key) } passwordSecretValue := string(passwordSecret.Data[passwordSelector.Key]) if passwordSecretValue == "" { return errors.Errorf("SMTP password is empty in secret '%s/%s[%s]", e.Jenkins.Namespace, passwordSelector.Name, passwordSelector.Key) } mailer := gomail.NewDialer( s.config.SMTP.Server, s.config.SMTP.Port, usernameSecretValue, passwordSecretValue, ) mailer.TLSConfig = &tls.Config{InsecureSkipVerify: s.config.SMTP.TLSInsecureSkipVerify} message := s.generateMessage(e) if err := mailer.DialAndSend(message); err != nil { return err } return nil } func (s SMTP) getStatusColor(logLevel v1alpha2.NotificationLevel) event.StatusColor { switch logLevel { case v1alpha2.NotificationLevelInfo: return infoColor case v1alpha2.NotificationLevelWarning: return warningColor default: return defaultColor } }