Config: do not perform a copy after deserialization

This commit is contained in:
Alexandre Blazart 2023-10-23 22:14:08 +02:00
parent 126fcc3cfd
commit 6ee09c3994
No known key found for this signature in database
GPG Key ID: 7067AE298F0C655B
3 changed files with 50 additions and 72 deletions

View File

@ -21,8 +21,8 @@ type alertHandler struct {
func NewAlertHandler(config *Config, sender Sender) http.Handler {
return &alertHandler{
sender: sender,
firingTemplate: config.Firing,
resolvedTemplate: config.Resolved,
firingTemplate: config.Firing.ToTemplate(),
resolvedTemplate: config.Resolved.ToTemplate(),
format: config.Format,
}
}

View File

@ -2,47 +2,24 @@ package main
import (
"encoding/json"
"fmt"
"log"
"os"
"sort"
"strings"
"text/template"
)
// Config is the internal configuration type
type Config struct {
Listen string
Debug bool
StartupMessage string
Firing *template.Template
Resolved *template.Template
Format Format
XMPP ConfigXMPP
Debug bool `json:"debug"`
Listen string `json:"listen"`
StartupMessage string `json:"startup_message"`
Firing *ConfigTemplate `json:"firing"`
Resolved *ConfigTemplate `json:"resolved"`
Format Format `json:"format"`
XMPP ConfigXMPP `json:"xmpp"`
}
// ConfigXMPP is the configuration for XMPP connection
type ConfigXMPP struct {
OverrideServer string
User string
Password string
SendNotif []string
Status string
NoTLS bool
TLSInsecure bool
}
type internalConfig struct {
Debug bool `json:"debug"`
Listen string `json:"listen"`
StartupMessage string `json:"startup_message"`
Firing string `json:"firing"`
Resolved string `json:"resolved"`
Format string `json:"format"`
XMPP internalConfigXMPP `json:"xmpp"`
}
type internalConfigXMPP struct {
OverrideServer string `json:"override_server"`
User string `json:"user"`
Password string `json:"password"`
@ -60,59 +37,36 @@ func NewConfig(filename string) *Config {
}
defer fd.Close()
internalConfig := &internalConfig{
config := &Config{
Listen: ":9091",
XMPP: internalConfigXMPP{
XMPP: ConfigXMPP{
Status: "Monitoring",
},
}
if err := json.NewDecoder(fd).Decode(internalConfig); err != nil {
if err := json.NewDecoder(fd).Decode(config); err != nil {
log.Fatalln(err)
}
return internalConfig.parse()
return config
}
func (i *internalConfig) parse() *Config {
return &Config{
Debug: i.Debug,
Listen: i.Listen,
StartupMessage: i.StartupMessage,
Firing: parseTemplate(i.Firing),
Resolved: parseTemplate(i.Resolved),
Format: parseFormat(i.Format),
XMPP: i.XMPP.parse(),
}
}
// ConfigTemplate
func (i *internalConfigXMPP) parse() ConfigXMPP {
result := ConfigXMPP{
OverrideServer: i.OverrideServer,
User: i.User,
Password: i.Password,
SendNotif: i.SendNotif,
Status: i.Status,
NoTLS: i.NoTLS,
TLSInsecure: i.TLSInsecure,
}
sort.Strings(result.SendNotif)
return result
}
type ConfigTemplate template.Template
func parseTemplate(tmpl string) *template.Template {
if tmpl == "" {
return nil
func (c *ConfigTemplate) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
return template.Must(template.New("").Parse(tmpl))
templ, err := template.New("").Parse(s)
if err == nil {
*c = ConfigTemplate(*templ)
}
return err
}
func parseFormat(format string) Format {
switch strings.ToLower(format) {
case "", "text":
return Format_Text
case "html":
return Format_HTML
}
panic(fmt.Sprintf("unknown format: %s", format))
func (c *ConfigTemplate) ToTemplate() *template.Template {
return (*template.Template)(c)
}

View File

@ -1,5 +1,12 @@
package main
import (
"encoding/json"
"fmt"
"strings"
)
// Format
type Format int
const (
@ -18,6 +25,23 @@ func (f Format) String() string {
}
}
func (f *Format) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
switch strings.ToLower(s) {
case "", "text":
*f = Format_Text
case "html":
*f = Format_HTML
default:
return fmt.Errorf("unknown format: %s", s)
}
return nil
}
// SendCloser is the interface to send messages
type SendCloser interface {
Sender