mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-06-16 14:15:07 +03:00
save peers RIVM-31
This commit is contained in:
parent
d68d3db702
commit
0b54277ece
7 changed files with 164 additions and 165 deletions
|
@ -1,14 +1,12 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
@ -17,13 +15,10 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"golang.org/x/text/encoding/unicode"
|
|
||||||
|
|
||||||
"github.com/gologme/log"
|
"github.com/gologme/log"
|
||||||
gsyslog "github.com/hashicorp/go-syslog"
|
gsyslog "github.com/hashicorp/go-syslog"
|
||||||
"github.com/hjson/hjson-go"
|
"github.com/hjson/hjson-go"
|
||||||
"github.com/kardianos/minwinsvc"
|
"github.com/kardianos/minwinsvc"
|
||||||
"github.com/mitchellh/mapstructure"
|
|
||||||
|
|
||||||
//"github.com/RiV-chain/RiV-mesh/src/address"
|
//"github.com/RiV-chain/RiV-mesh/src/address"
|
||||||
"github.com/RiV-chain/RiV-mesh/src/admin"
|
"github.com/RiV-chain/RiV-mesh/src/admin"
|
||||||
|
@ -44,77 +39,6 @@ type node struct {
|
||||||
admin *admin.AdminSocket
|
admin *admin.AdminSocket
|
||||||
}
|
}
|
||||||
|
|
||||||
func readConfig(log *log.Logger, useconf bool, useconffile string, normaliseconf bool) *config.NodeConfig {
|
|
||||||
// Use a configuration file. If -useconf, the configuration will be read
|
|
||||||
// from stdin. If -useconffile, the configuration will be read from the
|
|
||||||
// filesystem.
|
|
||||||
var conf []byte
|
|
||||||
var err error
|
|
||||||
if useconffile != "" {
|
|
||||||
// Read the file from the filesystem
|
|
||||||
conf, err = os.ReadFile(useconffile)
|
|
||||||
} else {
|
|
||||||
// Read the file from stdin.
|
|
||||||
conf, err = io.ReadAll(os.Stdin)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
// If there's a byte order mark - which Windows 10 is now incredibly fond of
|
|
||||||
// throwing everywhere when it's converting things into UTF-16 for the hell
|
|
||||||
// of it - remove it and decode back down into UTF-8. This is necessary
|
|
||||||
// because hjson doesn't know what to do with UTF-16 and will panic
|
|
||||||
if bytes.Equal(conf[0:2], []byte{0xFF, 0xFE}) ||
|
|
||||||
bytes.Equal(conf[0:2], []byte{0xFE, 0xFF}) {
|
|
||||||
utf := unicode.UTF16(unicode.BigEndian, unicode.UseBOM)
|
|
||||||
decoder := utf.NewDecoder()
|
|
||||||
conf, err = decoder.Bytes(conf)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Generate a new configuration - this gives us a set of sane defaults -
|
|
||||||
// then parse the configuration we loaded above on top of it. The effect
|
|
||||||
// of this is that any configuration item that is missing from the provided
|
|
||||||
// configuration will use a sane default.
|
|
||||||
cfg := defaults.GenerateConfig()
|
|
||||||
var dat map[string]interface{}
|
|
||||||
if err := hjson.Unmarshal(conf, &dat); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
// Sanitise the config
|
|
||||||
confJson, err := json.Marshal(dat)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal(confJson, &cfg); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
// Overlay our newly mapped configuration onto the autoconf node config that
|
|
||||||
// we generated above.
|
|
||||||
if err = mapstructure.Decode(dat, &cfg); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return cfg
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a new configuration and returns it in HJSON format. This is used
|
|
||||||
// with -genconf.
|
|
||||||
func doGenconf(isjson bool) string {
|
|
||||||
cfg := defaults.GenerateConfig()
|
|
||||||
var bs []byte
|
|
||||||
var err error
|
|
||||||
if isjson {
|
|
||||||
bs, err = json.MarshalIndent(cfg, "", " ")
|
|
||||||
} else {
|
|
||||||
bs, err = hjson.Marshal(cfg)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return string(bs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setLogLevel(loglevel string, logger *log.Logger) {
|
func setLogLevel(loglevel string, logger *log.Logger) {
|
||||||
levels := [...]string{"error", "warn", "info", "debug", "trace"}
|
levels := [...]string{"error", "warn", "info", "debug", "trace"}
|
||||||
loglevel = strings.ToLower(loglevel)
|
loglevel = strings.ToLower(loglevel)
|
||||||
|
@ -229,7 +153,10 @@ func run(args yggArgs, ctx context.Context) {
|
||||||
cfg = defaults.GenerateConfig()
|
cfg = defaults.GenerateConfig()
|
||||||
case args.useconffile != "" || args.useconf:
|
case args.useconffile != "" || args.useconf:
|
||||||
// Read the configuration from either stdin or from the filesystem
|
// Read the configuration from either stdin or from the filesystem
|
||||||
cfg = readConfig(logger, args.useconf, args.useconffile, args.normaliseconf)
|
cfg, err = defaults.ReadConfig(args.useconffile)
|
||||||
|
if err != nil {
|
||||||
|
panic("Configuration file load error: " + err.Error())
|
||||||
|
}
|
||||||
// If the -normaliseconf option was specified then remarshal the above
|
// If the -normaliseconf option was specified then remarshal the above
|
||||||
// configuration and print it back to stdout. This lets the user update
|
// configuration and print it back to stdout. This lets the user update
|
||||||
// their configuration file with newly mapped names (like above) or to
|
// their configuration file with newly mapped names (like above) or to
|
||||||
|
@ -249,7 +176,7 @@ func run(args yggArgs, ctx context.Context) {
|
||||||
}
|
}
|
||||||
case args.genconf:
|
case args.genconf:
|
||||||
// Generate a new configuration and print it to stdout.
|
// Generate a new configuration and print it to stdout.
|
||||||
fmt.Println(doGenconf(args.confjson))
|
fmt.Println(defaults.Genconf(args.confjson))
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
// No flags were provided, therefore print the list of flags to stdout.
|
// No flags were provided, therefore print the list of flags to stdout.
|
||||||
|
@ -391,7 +318,7 @@ func run(args yggArgs, ctx context.Context) {
|
||||||
logger.Infof("Your IPv6 address is %s", address.String())
|
logger.Infof("Your IPv6 address is %s", address.String())
|
||||||
logger.Infof("Your IPv6 subnet is %s", subnet.String())
|
logger.Infof("Your IPv6 subnet is %s", subnet.String())
|
||||||
// Start HTTP server
|
// Start HTTP server
|
||||||
n.admin.StartHttpServer(cfg)
|
n.admin.StartHttpServer(args.useconffile, cfg)
|
||||||
// Block until we are told to shut down.
|
// Block until we are told to shut down.
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -68,8 +68,13 @@ img {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
max-width: 690px;
|
||||||
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
td.fi {
|
td.fi {
|
||||||
|
|
|
@ -4,6 +4,7 @@ var $$ = clazz => document.getElementsByClassName(clazz)
|
||||||
function setPingValue(peer, value) {
|
function setPingValue(peer, value) {
|
||||||
var cellText;
|
var cellText;
|
||||||
var peerCell = $(peer);
|
var peerCell = $(peer);
|
||||||
|
if (!peerCell) return;
|
||||||
var peerTable = $("peer_list");
|
var peerTable = $("peer_list");
|
||||||
if (value === "-1") {
|
if (value === "-1") {
|
||||||
var peerAddress = $("label_" + peer);
|
var peerAddress = $("label_" + peer);
|
||||||
|
@ -148,7 +149,7 @@ function showWindow(text) {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Riv-Save-Config': 'true',
|
'Riv-Save-Config': 'true',
|
||||||
},
|
},
|
||||||
body: JSON.stringify({"peers": peer_list}),
|
body: JSON.stringify(peer_list),
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
|
@ -315,6 +316,7 @@ ui.updateSelfInfo = () =>
|
||||||
ui.getSelfInfo()
|
ui.getSelfInfo()
|
||||||
.then((info) => {
|
.then((info) => {
|
||||||
$("ipv6").innerText = info.address;
|
$("ipv6").innerText = info.address;
|
||||||
|
$("subnet").innerText = info.subnet;
|
||||||
$("pub_key").innerText = info.key;
|
$("pub_key").innerText = info.key;
|
||||||
$("priv_key").innerText = info.private_key;
|
$("priv_key").innerText = info.private_key;
|
||||||
$("ipv6").innerText = info.address;
|
$("ipv6").innerText = info.address;
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/RiV-chain/RiV-mesh/src/defaults"
|
"github.com/RiV-chain/RiV-mesh/src/defaults"
|
||||||
"github.com/hjson/hjson-go"
|
|
||||||
"github.com/webview/webview"
|
"github.com/webview/webview"
|
||||||
"golang.org/x/text/encoding/unicode"
|
|
||||||
|
|
||||||
"github.com/docopt/docopt-go"
|
"github.com/docopt/docopt-go"
|
||||||
)
|
)
|
||||||
|
@ -46,35 +43,10 @@ func main() {
|
||||||
w.SetSize(690, 920, webview.HintFixed)
|
w.SetSize(690, 920, webview.HintFixed)
|
||||||
|
|
||||||
if confui.IndexHtml == "" {
|
if confui.IndexHtml == "" {
|
||||||
confui.IndexHtml = getEndpoint()
|
confui.IndexHtml = defaults.GetHttpEndpoint("http://localhost:19019")
|
||||||
}
|
|
||||||
if confui.IndexHtml == "" {
|
|
||||||
confui.IndexHtml = "http://localhost:19019"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Opening: %v", confui.IndexHtml)
|
log.Printf("Opening: %v", confui.IndexHtml)
|
||||||
w.Navigate(confui.IndexHtml)
|
w.Navigate(confui.IndexHtml)
|
||||||
w.Run()
|
w.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEndpoint() string {
|
|
||||||
if config, err := os.ReadFile(defaults.GetDefaults().DefaultConfigFile); err == nil {
|
|
||||||
if bytes.Equal(config[0:2], []byte{0xFF, 0xFE}) ||
|
|
||||||
bytes.Equal(config[0:2], []byte{0xFE, 0xFF}) {
|
|
||||||
utf := unicode.UTF16(unicode.BigEndian, unicode.UseBOM)
|
|
||||||
decoder := utf.NewDecoder()
|
|
||||||
config, err = decoder.Bytes(config)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var dat map[string]interface{}
|
|
||||||
if err := hjson.Unmarshal(config, &dat); err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if ep, ok := dat["HttpAddress"].(string); ok && (ep != "none" && ep != "") {
|
|
||||||
return ep
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
|
|
||||||
"github.com/RiV-chain/RiV-mesh/src/config"
|
"github.com/RiV-chain/RiV-mesh/src/config"
|
||||||
"github.com/RiV-chain/RiV-mesh/src/core"
|
"github.com/RiV-chain/RiV-mesh/src/core"
|
||||||
|
"github.com/RiV-chain/RiV-mesh/src/defaults"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Add authentication
|
// TODO: Add authentication
|
||||||
|
@ -246,7 +247,7 @@ func (a *AdminSocket) SetupAdminHandlers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start runs http server
|
// Start runs http server
|
||||||
func (a *AdminSocket) StartHttpServer(nc *config.NodeConfig) {
|
func (a *AdminSocket) StartHttpServer(configFn string, nc *config.NodeConfig) {
|
||||||
if nc.HttpAddress != "none" && nc.HttpAddress != "" && nc.WwwRoot != "none" && nc.WwwRoot != "" {
|
if nc.HttpAddress != "none" && nc.HttpAddress != "" && nc.WwwRoot != "none" && nc.WwwRoot != "" {
|
||||||
u, err := url.Parse(nc.HttpAddress)
|
u, err := url.Parse(nc.HttpAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -275,6 +276,46 @@ func (a *AdminSocket) StartHttpServer(nc *config.NodeConfig) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
http.HandleFunc("/api/peers", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/api/peers", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var handleDelete = func() error {
|
||||||
|
err := a.core.RemovePeers()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var handlePost = func() error {
|
||||||
|
var peers []string
|
||||||
|
err := json.NewDecoder(r.Body).Decode(&peers)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, peer := range peers {
|
||||||
|
if err := a.core.AddPeer(peer, ""); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(configFn) > 0 {
|
||||||
|
saveHeaders := r.Header["Riv-Save-Config"]
|
||||||
|
if len(saveHeaders) > 0 && saveHeaders[0] == "true" {
|
||||||
|
cfg, err := defaults.ReadConfig(configFn)
|
||||||
|
if err == nil {
|
||||||
|
cfg.Peers = peers
|
||||||
|
err := defaults.WriteConfig(configFn, cfg)
|
||||||
|
if err != nil {
|
||||||
|
a.log.Errorln("Config file read error:", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
a.log.Errorln("Config file read error:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case "GET":
|
case "GET":
|
||||||
w.Header().Add("Content-Type", "application/json")
|
w.Header().Add("Content-Type", "application/json")
|
||||||
|
@ -290,61 +331,17 @@ func (a *AdminSocket) StartHttpServer(nc *config.NodeConfig) {
|
||||||
}
|
}
|
||||||
fmt.Fprint(w, string(b[:]))
|
fmt.Fprint(w, string(b[:]))
|
||||||
case "POST":
|
case "POST":
|
||||||
req := &AddPeersRequest{}
|
handlePost()
|
||||||
res := &AddPeersResponse{}
|
|
||||||
|
|
||||||
err := json.NewDecoder(r.Body).Decode(&req)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := a.addPeersHandler(req, res); err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(res)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), 503)
|
|
||||||
}
|
|
||||||
w.Header().Add("Content-Type", "application/json")
|
|
||||||
fmt.Fprint(w, string(b[:]))
|
|
||||||
case "PUT":
|
case "PUT":
|
||||||
err := a.core.RemovePeers()
|
if handleDelete() == nil {
|
||||||
if err != nil {
|
if handlePost() == nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, "No content", http.StatusNoContent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
req := &AddPeersRequest{}
|
|
||||||
res := &AddPeersResponse{}
|
|
||||||
|
|
||||||
err = json.NewDecoder(r.Body).Decode(&req)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := a.addPeersHandler(req, res); err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(res)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), 503)
|
|
||||||
}
|
|
||||||
w.Header().Add("Content-Type", "application/json")
|
|
||||||
fmt.Fprint(w, string(b[:]))
|
|
||||||
//TODO save peers
|
|
||||||
// saveHeaders := r.Header["Riv-Save-Config"]
|
|
||||||
// if len(saveHeaders) > 0 && saveHeaders[0] == "true" {
|
|
||||||
// nc.Peers =
|
|
||||||
// }
|
|
||||||
case "DELETE":
|
case "DELETE":
|
||||||
err := a.core.RemovePeers()
|
if handleDelete() == nil {
|
||||||
if err != nil {
|
http.Error(w, "No content", http.StatusNoContent)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
}
|
}
|
||||||
http.Error(w, "No content", http.StatusNoContent)
|
|
||||||
default:
|
default:
|
||||||
http.Error(w, "Method Not Allowed", 405)
|
http.Error(w, "Method Not Allowed", 405)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,16 @@
|
||||||
package defaults
|
package defaults
|
||||||
|
|
||||||
import "github.com/RiV-chain/RiV-mesh/src/config"
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/RiV-chain/RiV-mesh/src/config"
|
||||||
|
"github.com/hjson/hjson-go"
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
|
"golang.org/x/text/encoding/unicode"
|
||||||
|
)
|
||||||
|
|
||||||
type MulticastInterfaceConfig = config.MulticastInterfaceConfig
|
type MulticastInterfaceConfig = config.MulticastInterfaceConfig
|
||||||
type NetworkDomainConfig = config.NetworkDomainConfig
|
type NetworkDomainConfig = config.NetworkDomainConfig
|
||||||
|
@ -77,3 +87,89 @@ func GenerateConfig() *config.NodeConfig {
|
||||||
|
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Genconf(isjson bool) string {
|
||||||
|
cfg := GenerateConfig()
|
||||||
|
var bs []byte
|
||||||
|
if isjson {
|
||||||
|
bs, _ = json.MarshalIndent(cfg, "", " ")
|
||||||
|
} else {
|
||||||
|
bs, _ = hjson.Marshal(cfg)
|
||||||
|
}
|
||||||
|
return string(bs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadConfig(useconffile string) (*config.NodeConfig, error) {
|
||||||
|
// Use a configuration file. If -useconf, the configuration will be read
|
||||||
|
// from stdin. If -useconffile, the configuration will be read from the
|
||||||
|
// filesystem.
|
||||||
|
var conf []byte
|
||||||
|
var err error
|
||||||
|
if useconffile != "" {
|
||||||
|
// Read the file from the filesystem
|
||||||
|
conf, err = os.ReadFile(useconffile)
|
||||||
|
} else {
|
||||||
|
// Read the file from stdin.
|
||||||
|
conf, err = io.ReadAll(os.Stdin)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// If there's a byte order mark - which Windows 10 is now incredibly fond of
|
||||||
|
// throwing everywhere when it's converting things into UTF-16 for the hell
|
||||||
|
// of it - remove it and decode back down into UTF-8. This is necessary
|
||||||
|
// because hjson doesn't know what to do with UTF-16 and will panic
|
||||||
|
if bytes.Equal(conf[0:2], []byte{0xFF, 0xFE}) ||
|
||||||
|
bytes.Equal(conf[0:2], []byte{0xFE, 0xFF}) {
|
||||||
|
utf := unicode.UTF16(unicode.BigEndian, unicode.UseBOM)
|
||||||
|
decoder := utf.NewDecoder()
|
||||||
|
conf, err = decoder.Bytes(conf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Generate a new configuration - this gives us a set of sane defaults -
|
||||||
|
// then parse the configuration we loaded above on top of it. The effect
|
||||||
|
// of this is that any configuration item that is missing from the provided
|
||||||
|
// configuration will use a sane default.
|
||||||
|
cfg := GenerateConfig()
|
||||||
|
var dat map[string]interface{}
|
||||||
|
if err := hjson.Unmarshal(conf, &dat); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Sanitise the config
|
||||||
|
confJson, err := json.Marshal(dat)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(confJson, &cfg); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Overlay our newly mapped configuration onto the autoconf node config that
|
||||||
|
// we generated above.
|
||||||
|
if err = mapstructure.Decode(dat, &cfg); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteConfig(confFn string, cfg *config.NodeConfig) error {
|
||||||
|
bs, err := hjson.Marshal(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = os.WriteFile(confFn, bs, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetHttpEndpoint(defaultEndpoint string) string {
|
||||||
|
if config, err := ReadConfig(GetDefaults().DefaultConfigFile); err == nil {
|
||||||
|
if ep := config.HttpAddress; ep != "none" && ep != "" {
|
||||||
|
return ep
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultEndpoint
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue