Skip to content

Commit

Permalink
channels: Reorder methods according to plugin.Plugin
Browse files Browse the repository at this point in the history
The plugin.Plugin interface specifies the three methods required for the
channel plugin RPC API in their logical order. Considering that these
channels are the blueprint for external channel development, the order
of implementing channel plugins was changed to correspond to the
interface.

For all files, the main function has been moved to the top.

In addition, the Email.Send method received a documentation string
indicating that it implements the enmime.Sender interface, as it is not
directly called anywhere. Further, the Email.GetServer method got
inlined as it was only called from one other method.
  • Loading branch information
oxzi authored and julianbrost committed Jul 18, 2024
1 parent 9a48f92 commit 9864d0e
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 136 deletions.
163 changes: 81 additions & 82 deletions cmd/channels/email/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import (
"net/mail"
)

func main() {
plugin.RunPlugin(&Email{})
}

const (
EncryptionNone = "none"
EncryptionStartTLS = "starttls"
Expand All @@ -32,86 +36,6 @@ type Email struct {
Encryption string `json:"encryption"`
}

func main() {
plugin.RunPlugin(&Email{})
}

func (ch *Email) SendNotification(req *plugin.NotificationRequest) error {
var to []mail.Address
for _, address := range req.Contact.Addresses {
if address.Type == "email" {
to = append(to, mail.Address{Name: req.Contact.FullName, Address: address.Address})
}
}

if len(to) == 0 {
return fmt.Errorf("contact user %s does not have an e-mail address", req.Contact.FullName)
}

var msg bytes.Buffer
plugin.FormatMessage(&msg, req)

return enmime.Builder().
ToAddrs(to).
From(ch.SenderName, ch.SenderMail).
Subject(plugin.FormatSubject(req)).
Header("Message-Id", fmt.Sprintf("<%s-%s>", uuid.New().String(), ch.SenderMail)).
Text(msg.Bytes()).
Send(ch)
}

func (ch *Email) Send(reversePath string, recipients []string, msg []byte) error {
var (
client *smtp.Client
err error
)

switch ch.Encryption {
case EncryptionStartTLS:
client, err = smtp.DialStartTLS(ch.GetServer(), nil)
case EncryptionTLS:
client, err = smtp.DialTLS(ch.GetServer(), nil)
case EncryptionNone:
client, err = smtp.Dial(ch.GetServer())
default:
return fmt.Errorf("unsupported mail encryption type %q", ch.Encryption)
}
if err != nil {
return err
}
defer func() { _ = client.Close() }()

if ch.Password != "" {
if err = client.Auth(sasl.NewPlainClient("", ch.User, ch.Password)); err != nil {
return err
}
}

if err := client.SendMail(reversePath, recipients, bytes.NewReader(msg)); err != nil {
return err
}

return client.Quit()
}

func (ch *Email) SetConfig(jsonStr json.RawMessage) error {
err := plugin.PopulateDefaults(ch)
if err != nil {
return err
}

err = json.Unmarshal(jsonStr, ch)
if err != nil {
return fmt.Errorf("failed to load config: %s %w", jsonStr, err)
}

if (ch.User == "") != (ch.Password == "") {
return fmt.Errorf("user and password fields must both be set or empty")
}

return nil
}

func (ch *Email) GetInfo() *plugin.Info {
configAttrs := plugin.ConfigOptions{
{
Expand Down Expand Up @@ -197,6 +121,81 @@ func (ch *Email) GetInfo() *plugin.Info {
}
}

func (ch *Email) GetServer() string {
return net.JoinHostPort(ch.Host, ch.Port)
func (ch *Email) SetConfig(jsonStr json.RawMessage) error {
err := plugin.PopulateDefaults(ch)
if err != nil {
return err
}

err = json.Unmarshal(jsonStr, ch)
if err != nil {
return fmt.Errorf("failed to load config: %s %w", jsonStr, err)
}

if (ch.User == "") != (ch.Password == "") {
return fmt.Errorf("user and password fields must both be set or empty")
}

return nil
}

func (ch *Email) SendNotification(req *plugin.NotificationRequest) error {
var to []mail.Address
for _, address := range req.Contact.Addresses {
if address.Type == "email" {
to = append(to, mail.Address{Name: req.Contact.FullName, Address: address.Address})
}
}

if len(to) == 0 {
return fmt.Errorf("contact user %s does not have an e-mail address", req.Contact.FullName)
}

var msg bytes.Buffer
plugin.FormatMessage(&msg, req)

return enmime.Builder().
ToAddrs(to).
From(ch.SenderName, ch.SenderMail).
Subject(plugin.FormatSubject(req)).
Header("Message-Id", fmt.Sprintf("<%s-%s>", uuid.New().String(), ch.SenderMail)).
Text(msg.Bytes()).
Send(ch)
}

// Send implements the enmime.Sender interface.
func (ch *Email) Send(reversePath string, recipients []string, msg []byte) error {
var (
client *smtp.Client
err error
)

serverAddr := net.JoinHostPort(ch.Host, ch.Port)

switch ch.Encryption {
case EncryptionStartTLS:
client, err = smtp.DialStartTLS(serverAddr, nil)
case EncryptionTLS:
client, err = smtp.DialTLS(serverAddr, nil)
case EncryptionNone:
client, err = smtp.Dial(serverAddr)
default:
return fmt.Errorf("unsupported mail encryption type %q", ch.Encryption)
}
if err != nil {
return err
}
defer func() { _ = client.Close() }()

if ch.Password != "" {
if err = client.Auth(sasl.NewPlainClient("", ch.User, ch.Password)); err != nil {
return err
}
}

if err := client.SendMail(reversePath, recipients, bytes.NewReader(msg)); err != nil {
return err
}

return client.Quit()
}
100 changes: 50 additions & 50 deletions cmd/channels/rocketchat/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,62 @@ import (
"time"
)

func main() {
plugin.RunPlugin(&RocketChat{})
}

type RocketChat struct {
URL string `json:"url"`
UserID string `json:"user_id"`
Token string `json:"token"`
}

func main() {
plugin.RunPlugin(&RocketChat{})
func (ch *RocketChat) GetInfo() *plugin.Info {
configAttrs := plugin.ConfigOptions{
{
Name: "url",
Type: "string",
Label: map[string]string{
"en_US": "Rocket.Chat URL",
"de_DE": "Rocket.Chat URL",
},
Required: true,
},
{
Name: "user_id",
Type: "string",
Label: map[string]string{
"en_US": "User ID",
"de_DE": "Benutzer ID",
},
Required: true,
},
{
Name: "token",
Type: "secret",
Label: map[string]string{
"en_US": "Personal Access Token",
"de_DE": "Persönliches Zugangstoken",
},
Required: true,
},
}

return &plugin.Info{
Name: "Rocket.Chat",
Version: internal.Version.Version,
Author: "Icinga GmbH",
ConfigAttributes: configAttrs,
}
}

func (ch *RocketChat) SetConfig(jsonStr json.RawMessage) error {
err := plugin.PopulateDefaults(ch)
if err != nil {
return err
}

return json.Unmarshal(jsonStr, ch)
}

func (ch *RocketChat) SendNotification(req *plugin.NotificationRequest) error {
Expand Down Expand Up @@ -75,51 +123,3 @@ func (ch *RocketChat) SendNotification(req *plugin.NotificationRequest) error {

return nil
}

func (ch *RocketChat) SetConfig(jsonStr json.RawMessage) error {
err := plugin.PopulateDefaults(ch)
if err != nil {
return err
}

return json.Unmarshal(jsonStr, ch)
}

func (ch *RocketChat) GetInfo() *plugin.Info {
configAttrs := plugin.ConfigOptions{
{
Name: "url",
Type: "string",
Label: map[string]string{
"en_US": "Rocket.Chat URL",
"de_DE": "Rocket.Chat URL",
},
Required: true,
},
{
Name: "user_id",
Type: "string",
Label: map[string]string{
"en_US": "User ID",
"de_DE": "Benutzer ID",
},
Required: true,
},
{
Name: "token",
Type: "secret",
Label: map[string]string{
"en_US": "Personal Access Token",
"de_DE": "Persönliches Zugangstoken",
},
Required: true,
},
}

return &plugin.Info{
Name: "Rocket.Chat",
Version: internal.Version.Version,
Author: "Icinga GmbH",
ConfigAttributes: configAttrs,
}
}
8 changes: 4 additions & 4 deletions cmd/channels/webhook/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import (
"text/template"
)

func main() {
plugin.RunPlugin(&Webhook{})
}

type Webhook struct {
Method string `json:"method"`
URLTemplate string `json:"url_template"`
Expand Down Expand Up @@ -164,7 +168,3 @@ func (ch *Webhook) SendNotification(req *plugin.NotificationRequest) error {

return nil
}

func main() {
plugin.RunPlugin(&Webhook{})
}

0 comments on commit 9864d0e

Please sign in to comment.