Added ability to load remote configuration files. [#525]
This commit is contained in:
@@ -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)
|
* [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)
|
* [Message edits and deletes](https://github.com/42wim/matterbridge/wiki/Features#message-edits-and-deletes)
|
||||||
* Preserves threading when possible
|
* Preserves threading when possible
|
||||||
|
* Remote configuration files
|
||||||
* [Attachment / files handling](https://github.com/42wim/matterbridge/wiki/Features#attachment--files-handling)
|
* [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)
|
* [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)
|
* [Private groups](https://github.com/42wim/matterbridge/wiki/Features#private-groups)
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -41,7 +43,9 @@ func New(cfg *bridge.Config) bridge.Bridger {
|
|||||||
return key == b.GetString("Token"), nil
|
return key == b.GetString("Token"), nil
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
e.GET("/api/health", b.handleHealthcheck)
|
e.GET("/api/health", b.handleHealthcheck)
|
||||||
|
e.PUT("/api/reload", b.handleConfigReload)
|
||||||
e.GET("/api/messages", b.handleMessages)
|
e.GET("/api/messages", b.handleMessages)
|
||||||
e.GET("/api/stream", b.handleStream)
|
e.GET("/api/stream", b.handleStream)
|
||||||
e.POST("/api/message", b.handlePostMessage)
|
e.POST("/api/message", b.handlePostMessage)
|
||||||
@@ -82,6 +86,40 @@ func (b *Api) handleHealthcheck(c echo.Context) error {
|
|||||||
return c.String(http.StatusOK, "OK")
|
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 {
|
func (b *Api) handlePostMessage(c echo.Context) error {
|
||||||
message := config.Message{}
|
message := config.Message{}
|
||||||
if err := c.Bind(&message); err != nil {
|
if err := c.Bind(&message); err != nil {
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ func (b *Bridge) joinChannels(channels map[string]config.ChannelInfo, exists map
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Bridge) GetConfigFile() string {
|
||||||
|
return b.Config.GetConfigFile()
|
||||||
|
}
|
||||||
|
|
||||||
func (b *Bridge) GetBool(key string) bool {
|
func (b *Bridge) GetBool(key string) bool {
|
||||||
if b.Config.GetBool(b.Account + "." + key) {
|
if b.Config.GetBool(b.Account + "." + key) {
|
||||||
return b.Config.GetBool(b.Account + "." + key)
|
return b.Config.GetBool(b.Account + "." + key)
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ type Protocol struct {
|
|||||||
Buffer int // api
|
Buffer int // api
|
||||||
Charset string // irc
|
Charset string // irc
|
||||||
ColorNicks bool // only irc for now
|
ColorNicks bool // only irc for now
|
||||||
|
ConfigURL string // api
|
||||||
Debug bool // general
|
Debug bool // general
|
||||||
DebugLevel int // only for irc now
|
DebugLevel int // only for irc now
|
||||||
EditSuffix string // mattermost, slack, discord, telegram, gitter
|
EditSuffix string // mattermost, slack, discord, telegram, gitter
|
||||||
@@ -172,6 +173,7 @@ type ConfigValues struct {
|
|||||||
General Protocol
|
General Protocol
|
||||||
Gateway []Gateway
|
Gateway []Gateway
|
||||||
SameChannelGateway []SameChannelGateway
|
SameChannelGateway []SameChannelGateway
|
||||||
|
ConfigFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@@ -196,6 +198,9 @@ func NewConfig(cfgfile string) *Config {
|
|||||||
viper.OnConfigChange(func(e fsnotify.Event) {
|
viper.OnConfigChange(func(e fsnotify.Event) {
|
||||||
flog.Println("Config file changed:", e.Name)
|
flog.Println("Config file changed:", e.Name)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mycfg.v.Set("ConfigFile", cfgfile)
|
||||||
|
mycfg.ConfigValues = &cfg
|
||||||
return mycfg
|
return mycfg
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,6 +234,10 @@ func NewConfigFromString(input []byte) *Config {
|
|||||||
return mycfg
|
return mycfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) GetConfigFile() string {
|
||||||
|
return c.v.GetString("ConfigFile")
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Config) GetBool(key string) bool {
|
func (c *Config) GetBool(key string) bool {
|
||||||
c.RLock()
|
c.RLock()
|
||||||
defer c.RUnlock()
|
defer c.RUnlock()
|
||||||
|
|||||||
Reference in New Issue
Block a user