From 6ecd65f0c983d619a656125342fb4448a359e0cd Mon Sep 17 00:00:00 2001 From: Patrick Connolly Date: Wed, 7 Nov 2018 22:24:35 +0800 Subject: [PATCH] Added ability to load remote configuration files. [#525] --- README.md | 1 + bridge/api/api.go | 38 ++++++++++++++++++++++++++++++++++++++ bridge/bridge.go | 4 ++++ bridge/config/config.go | 9 +++++++++ 4 files changed, 52 insertions(+) diff --git a/README.md b/README.md index 1bcbf974..3f31f533 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Minecraft server chat support via [MatterLink](https://github.com/elytra/MatterL * [Support multiple gateways(bridges) for your protocols](https://github.com/42wim/matterbridge/wiki/Features#support-multiple-gatewaysbridges-for-your-protocols) * [Message edits and deletes](https://github.com/42wim/matterbridge/wiki/Features#message-edits-and-deletes) * Preserves threading when possible +* Remote configuration files * [Attachment / files handling](https://github.com/42wim/matterbridge/wiki/Features#attachment--files-handling) * [Username and avatar spoofing](https://github.com/42wim/matterbridge/wiki/Features#username-and-avatar-spoofing) * [Private groups](https://github.com/42wim/matterbridge/wiki/Features#private-groups) diff --git a/bridge/api/api.go b/bridge/api/api.go index eef41a4a..daffd074 100644 --- a/bridge/api/api.go +++ b/bridge/api/api.go @@ -2,7 +2,9 @@ package api import ( "encoding/json" + "io/ioutil" "net/http" + "net/url" "sync" "time" @@ -41,7 +43,9 @@ func New(cfg *bridge.Config) bridge.Bridger { return key == b.GetString("Token"), nil })) } + e.GET("/api/health", b.handleHealthcheck) + e.PUT("/api/reload", b.handleConfigReload) e.GET("/api/messages", b.handleMessages) e.GET("/api/stream", b.handleStream) e.POST("/api/message", b.handlePostMessage) @@ -82,6 +86,40 @@ func (b *Api) handleHealthcheck(c echo.Context) error { return c.String(http.StatusOK, "OK") } +func (b *Api) handleConfigReload(c echo.Context) error { + cfgURL := b.GetString("ConfigURL") + if cfgURL == "" { + b.Log.Warning("Reload API triggered, but no config file url set.") + return c.String(http.StatusInternalServerError, "Internal Server Error") + } + + b.Log.Debugf("Reloading config from remote file: " + cfgURL) + _, err := url.ParseRequestURI(cfgURL) + if err != nil { + b.Log.Error("Malformed config file url: ", err) + return c.String(http.StatusInternalServerError, "Internal Server Error") + } + res, err := http.Get(cfgURL) + defer res.Body.Close() + if err != nil { + b.Log.Error("Failed to fetch remote config file: ", err) + return c.String(http.StatusInternalServerError, "Internal Server Error") + } + content, err := ioutil.ReadAll(res.Body) + if err != nil { + b.Log.Error("Error reading remote config file: ", err) + return c.String(http.StatusInternalServerError, "Internal Server Error") + } + cfgfile := b.GetConfigFile() + err = ioutil.WriteFile(cfgfile, content, 0644) + if err != nil { + b.Log.Error("Failed to write remote config file: ", err) + return c.String(http.StatusInternalServerError, "Internal Server Error") + } + + return c.String(http.StatusAccepted, "Accepted") +} + func (b *Api) handlePostMessage(c echo.Context) error { message := config.Message{} if err := c.Bind(&message); err != nil { diff --git a/bridge/bridge.go b/bridge/bridge.go index 0436eeb6..25e448fe 100644 --- a/bridge/bridge.go +++ b/bridge/bridge.go @@ -68,6 +68,10 @@ func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map return nil } +func (b *Bridge) GetConfigFile() string { + return b.Config.GetConfigFile() +} + func (b *Bridge) GetBool(key string) bool { if b.Config.GetBool(b.Account + "." + key) { return b.Config.GetBool(b.Account + "." + key) diff --git a/bridge/config/config.go b/bridge/config/config.go index bdf77f88..ea64809a 100644 --- a/bridge/config/config.go +++ b/bridge/config/config.go @@ -66,6 +66,7 @@ type Protocol struct { Buffer int // api Charset string // irc ColorNicks bool // only irc for now + ConfigURL string // api Debug bool // general DebugLevel int // only for irc now EditSuffix string // mattermost, slack, discord, telegram, gitter @@ -172,6 +173,7 @@ type ConfigValues struct { General Protocol Gateway []Gateway SameChannelGateway []SameChannelGateway + ConfigFile string } type Config struct { @@ -196,6 +198,9 @@ func NewConfig(cfgfile string) *Config { viper.OnConfigChange(func(e fsnotify.Event) { flog.Println("Config file changed:", e.Name) }) + + mycfg.v.Set("ConfigFile", cfgfile) + mycfg.ConfigValues = &cfg return mycfg } @@ -229,6 +234,10 @@ func NewConfigFromString(input []byte) *Config { return mycfg } +func (c *Config) GetConfigFile() string { + return c.v.GetString("ConfigFile") +} + func (c *Config) GetBool(key string) bool { c.RLock() defer c.RUnlock()