RestAPI: support libp2p host parameters in configuration
This adds support for parameters to create a libp2p host in the REST API configuration: ID, PrivateKey and ListenMultiaddr. These parameters default to nil/empty and are ommited in the default configuration. They are only supposed to be used when the user wants the REST API to use a different libp2p host than a provided one (upcoming changes). Pnet protector not supported yet in this case. Underlying basic auth should cover that front. Will implement if someone has a usecase. License: MIT Signed-off-by: Hector Sanjuan <code@hector.link>
This commit is contained in:
parent
5956dce69f
commit
3b715041ac
|
@ -2,6 +2,7 @@ package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -10,6 +11,8 @@ import (
|
||||||
|
|
||||||
"github.com/ipfs/ipfs-cluster/config"
|
"github.com/ipfs/ipfs-cluster/config"
|
||||||
|
|
||||||
|
crypto "github.com/libp2p/go-libp2p-crypto"
|
||||||
|
peer "github.com/libp2p/go-libp2p-peer"
|
||||||
ma "github.com/multiformats/go-multiaddr"
|
ma "github.com/multiformats/go-multiaddr"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,7 +20,7 @@ const configKey = "restapi"
|
||||||
|
|
||||||
// These are the default values for Config
|
// These are the default values for Config
|
||||||
const (
|
const (
|
||||||
DefaultListenAddr = "/ip4/127.0.0.1/tcp/9094"
|
DefaultHTTPListenAddr = "/ip4/127.0.0.1/tcp/9094"
|
||||||
DefaultReadTimeout = 30 * time.Second
|
DefaultReadTimeout = 30 * time.Second
|
||||||
DefaultReadHeaderTimeout = 5 * time.Second
|
DefaultReadHeaderTimeout = 5 * time.Second
|
||||||
DefaultWriteTimeout = 60 * time.Second
|
DefaultWriteTimeout = 60 * time.Second
|
||||||
|
@ -30,18 +33,18 @@ const (
|
||||||
type Config struct {
|
type Config struct {
|
||||||
config.Saver
|
config.Saver
|
||||||
|
|
||||||
// Listen parameters for the the Cluster HTTP API component.
|
// Listen address for the HTTP REST API endpoint.
|
||||||
ListenAddr ma.Multiaddr
|
HTTPListenAddr ma.Multiaddr
|
||||||
|
|
||||||
// TLS configuration for the HTTP listener
|
// TLS configuration for the HTTP listener
|
||||||
TLS *tls.Config
|
TLS *tls.Config
|
||||||
|
|
||||||
// SSLCertFile is a path to a certificate file used to secure the HTTP
|
// pathSSLCertFile is a path to a certificate file used to secure the
|
||||||
// API endpoint. Leave empty to use plain HTTP instead.
|
// HTTP API endpoint. We track it so we can write it in the JSON.
|
||||||
pathSSLCertFile string
|
pathSSLCertFile string
|
||||||
|
|
||||||
// SSLKeyFile is a path to the private key corresponding to the
|
// pathSSLKeyFile is a path to the private key corresponding to the
|
||||||
// SSLCertFile.
|
// SSLKeyFile. We track it so we can write it in the JSON.
|
||||||
pathSSLKeyFile string
|
pathSSLKeyFile string
|
||||||
|
|
||||||
// Maximum duration before timing out reading a full request
|
// Maximum duration before timing out reading a full request
|
||||||
|
@ -57,20 +60,34 @@ type Config struct {
|
||||||
// kept idle before being reused
|
// kept idle before being reused
|
||||||
IdleTimeout time.Duration
|
IdleTimeout time.Duration
|
||||||
|
|
||||||
|
// Listen address for the Libp2p REST API endpoint.
|
||||||
|
Libp2pListenAddr ma.Multiaddr
|
||||||
|
|
||||||
|
// ID and PrivateKey are used to create a libp2p host if we
|
||||||
|
// want the API component to do it (not by default).
|
||||||
|
ID peer.ID
|
||||||
|
PrivateKey crypto.PrivKey
|
||||||
|
|
||||||
// BasicAuthCreds is a map of username-password pairs
|
// BasicAuthCreds is a map of username-password pairs
|
||||||
// which are authorized to use Basic Authentication
|
// which are authorized to use Basic Authentication
|
||||||
BasicAuthCreds map[string]string
|
BasicAuthCreds map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsonConfig struct {
|
type jsonConfig struct {
|
||||||
ListenMultiaddress string `json:"listen_multiaddress"`
|
ListenMultiaddress string `json:"listen_multiaddress"` // backwards compat
|
||||||
SSLCertFile string `json:"ssl_cert_file,omitempty"`
|
HTTPListenMultiaddress string `json:"http_listen_multiaddress"`
|
||||||
SSLKeyFile string `json:"ssl_key_file,omitempty"`
|
SSLCertFile string `json:"ssl_cert_file,omitempty"`
|
||||||
ReadTimeout string `json:"read_timeout"`
|
SSLKeyFile string `json:"ssl_key_file,omitempty"`
|
||||||
ReadHeaderTimeout string `json:"read_header_timeout"`
|
ReadTimeout string `json:"read_timeout"`
|
||||||
WriteTimeout string `json:"write_timeout"`
|
ReadHeaderTimeout string `json:"read_header_timeout"`
|
||||||
IdleTimeout string `json:"idle_timeout"`
|
WriteTimeout string `json:"write_timeout"`
|
||||||
BasicAuthCreds map[string]string `json:"basic_auth_credentials"`
|
IdleTimeout string `json:"idle_timeout"`
|
||||||
|
|
||||||
|
Libp2pListenMultiaddress string `json:"libp2p_listen_multiaddress,omitempty"`
|
||||||
|
ID string `json:"ID,omitempty"`
|
||||||
|
PrivateKey string `json:"PrivateKey,omitempty"`
|
||||||
|
|
||||||
|
BasicAuthCreds map[string]string `json:"basic_auth_credentials"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigKey returns a human-friendly identifier for this type of
|
// ConfigKey returns a human-friendly identifier for this type of
|
||||||
|
@ -81,14 +98,22 @@ func (cfg *Config) ConfigKey() string {
|
||||||
|
|
||||||
// Default initializes this Config with working values.
|
// Default initializes this Config with working values.
|
||||||
func (cfg *Config) Default() error {
|
func (cfg *Config) Default() error {
|
||||||
listen, _ := ma.NewMultiaddr(DefaultListenAddr)
|
// http
|
||||||
cfg.ListenAddr = listen
|
httpListen, _ := ma.NewMultiaddr(DefaultHTTPListenAddr)
|
||||||
|
cfg.HTTPListenAddr = httpListen
|
||||||
cfg.pathSSLCertFile = ""
|
cfg.pathSSLCertFile = ""
|
||||||
cfg.pathSSLKeyFile = ""
|
cfg.pathSSLKeyFile = ""
|
||||||
cfg.ReadTimeout = DefaultReadTimeout
|
cfg.ReadTimeout = DefaultReadTimeout
|
||||||
cfg.ReadHeaderTimeout = DefaultReadHeaderTimeout
|
cfg.ReadHeaderTimeout = DefaultReadHeaderTimeout
|
||||||
cfg.WriteTimeout = DefaultWriteTimeout
|
cfg.WriteTimeout = DefaultWriteTimeout
|
||||||
cfg.IdleTimeout = DefaultIdleTimeout
|
cfg.IdleTimeout = DefaultIdleTimeout
|
||||||
|
|
||||||
|
// libp2p
|
||||||
|
cfg.ID = ""
|
||||||
|
cfg.PrivateKey = nil
|
||||||
|
cfg.Libp2pListenAddr = nil
|
||||||
|
|
||||||
|
// Auth
|
||||||
cfg.BasicAuthCreds = nil
|
cfg.BasicAuthCreds = nil
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -97,23 +122,19 @@ func (cfg *Config) Default() error {
|
||||||
// Validate makes sure that all fields in this Config have
|
// Validate makes sure that all fields in this Config have
|
||||||
// working values, at least in appearance.
|
// working values, at least in appearance.
|
||||||
func (cfg *Config) Validate() error {
|
func (cfg *Config) Validate() error {
|
||||||
if cfg.ListenAddr == nil {
|
if cfg.ReadTimeout < 0 {
|
||||||
return errors.New("restapi.listen_multiaddress not set")
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.ReadTimeout <= 0 {
|
|
||||||
return errors.New("restapi.read_timeout is invalid")
|
return errors.New("restapi.read_timeout is invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.ReadHeaderTimeout <= 0 {
|
if cfg.ReadHeaderTimeout < 0 {
|
||||||
return errors.New("restapi.read_header_timeout is invalid")
|
return errors.New("restapi.read_header_timeout is invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.WriteTimeout <= 0 {
|
if cfg.WriteTimeout < 0 {
|
||||||
return errors.New("restapi.write_timeout is invalid")
|
return errors.New("restapi.write_timeout is invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.IdleTimeout <= 0 {
|
if cfg.IdleTimeout < 0 {
|
||||||
return errors.New("restapi.idle_timeout invalid")
|
return errors.New("restapi.idle_timeout invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +146,16 @@ func (cfg *Config) Validate() error {
|
||||||
return errors.New("error loading SSL certificate or key")
|
return errors.New("error loading SSL certificate or key")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.ID != "" || cfg.PrivateKey != nil || cfg.Libp2pListenAddr != nil {
|
||||||
|
// if one is set, all should be
|
||||||
|
if cfg.ID == "" || cfg.PrivateKey == nil || cfg.Libp2pListenAddr == nil {
|
||||||
|
return errors.New("all ID, private_key and libp2p_listen_multiaddress should be set")
|
||||||
|
}
|
||||||
|
if !cfg.ID.MatchesPrivateKey(cfg.PrivateKey) {
|
||||||
|
return errors.New("restapi.ID does not match private_key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,18 +169,28 @@ func (cfg *Config) LoadJSON(raw []byte) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// A further improvement here below is that only non-zero fields
|
cfg.Default()
|
||||||
// are assigned. In that case, make sure you have Defaulted
|
|
||||||
// everything else.
|
|
||||||
// cfg.Default()
|
|
||||||
|
|
||||||
listen, err := ma.NewMultiaddr(jcfg.ListenMultiaddress)
|
// HTTP config --------------------------- //
|
||||||
if err != nil {
|
|
||||||
err = fmt.Errorf("error parsing listen_multiaddress: %s", err)
|
// Deal with legacy ListenMultiaddress parameter
|
||||||
return err
|
httpListen := jcfg.ListenMultiaddress
|
||||||
|
if httpListen != "" {
|
||||||
|
logger.Warning("restapi.listen_multiaddress has been replaced with http_listen_multiaddress")
|
||||||
|
}
|
||||||
|
if l := jcfg.HTTPListenMultiaddress; l != "" {
|
||||||
|
httpListen = l
|
||||||
|
}
|
||||||
|
|
||||||
|
if httpListen != "" {
|
||||||
|
httpAddr, err := ma.NewMultiaddr(httpListen)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("error parsing restapi.http_listen_multiaddress: %s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cfg.HTTPListenAddr = httpAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.ListenAddr = listen
|
|
||||||
cert := jcfg.SSLCertFile
|
cert := jcfg.SSLCertFile
|
||||||
key := jcfg.SSLKeyFile
|
key := jcfg.SSLKeyFile
|
||||||
cfg.pathSSLCertFile = cert
|
cfg.pathSSLCertFile = cert
|
||||||
|
@ -173,19 +214,63 @@ func (cfg *Config) LoadJSON(raw []byte) error {
|
||||||
cfg.TLS = tlsCfg
|
cfg.TLS = tlsCfg
|
||||||
}
|
}
|
||||||
|
|
||||||
// errors ignored as Validate() below will catch them
|
// only overwrite defaults when we can parse the time
|
||||||
t, _ := time.ParseDuration(jcfg.ReadTimeout)
|
// 0 is a valid value
|
||||||
|
t, err := time.ParseDuration(jcfg.ReadTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error parsing restapi.read_timeout: %s", err)
|
||||||
|
}
|
||||||
cfg.ReadTimeout = t
|
cfg.ReadTimeout = t
|
||||||
|
|
||||||
t, _ = time.ParseDuration(jcfg.ReadHeaderTimeout)
|
t, err = time.ParseDuration(jcfg.ReadHeaderTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error parsing restapi.read_header_timeout: %s", err)
|
||||||
|
}
|
||||||
cfg.ReadHeaderTimeout = t
|
cfg.ReadHeaderTimeout = t
|
||||||
|
|
||||||
t, _ = time.ParseDuration(jcfg.WriteTimeout)
|
t, err = time.ParseDuration(jcfg.WriteTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error parsing restapi.write_timeout: %s", err)
|
||||||
|
}
|
||||||
cfg.WriteTimeout = t
|
cfg.WriteTimeout = t
|
||||||
|
|
||||||
t, _ = time.ParseDuration(jcfg.IdleTimeout)
|
t, err = time.ParseDuration(jcfg.IdleTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error parsing restapi.idle_timeout: %s", err)
|
||||||
|
}
|
||||||
cfg.IdleTimeout = t
|
cfg.IdleTimeout = t
|
||||||
|
|
||||||
|
// Libp2p config ------------------ //
|
||||||
|
if libp2pListen := jcfg.Libp2pListenMultiaddress; libp2pListen != "" {
|
||||||
|
libp2pAddr, err := ma.NewMultiaddr(libp2pListen)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("error parsing restapi.libp2p_listen_multiaddress: %s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cfg.Libp2pListenAddr = libp2pAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
if jcfg.PrivateKey != "" {
|
||||||
|
pkb, err := base64.StdEncoding.DecodeString(jcfg.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error decoding restapi.private_key: %s", err)
|
||||||
|
}
|
||||||
|
pKey, err := crypto.UnmarshalPrivateKey(pkb)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error parsing restapi.private_key ID: %s", err)
|
||||||
|
}
|
||||||
|
cfg.PrivateKey = pKey
|
||||||
|
}
|
||||||
|
|
||||||
|
if jcfg.ID != "" {
|
||||||
|
id, err := peer.IDB58Decode(jcfg.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error parsing restapi.ID: %s", err)
|
||||||
|
}
|
||||||
|
cfg.ID = id
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authentication ------------------- //
|
||||||
cfg.BasicAuthCreds = jcfg.BasicAuthCreds
|
cfg.BasicAuthCreds = jcfg.BasicAuthCreds
|
||||||
|
|
||||||
return cfg.Validate()
|
return cfg.Validate()
|
||||||
|
@ -202,13 +287,28 @@ func (cfg *Config) ToJSON() (raw []byte, err error) {
|
||||||
}()
|
}()
|
||||||
|
|
||||||
jcfg := &jsonConfig{}
|
jcfg := &jsonConfig{}
|
||||||
jcfg.ListenMultiaddress = cfg.ListenAddr.String()
|
jcfg.HTTPListenMultiaddress = cfg.HTTPListenAddr.String()
|
||||||
jcfg.SSLCertFile = cfg.pathSSLCertFile
|
jcfg.SSLCertFile = cfg.pathSSLCertFile
|
||||||
jcfg.SSLKeyFile = cfg.pathSSLKeyFile
|
jcfg.SSLKeyFile = cfg.pathSSLKeyFile
|
||||||
jcfg.ReadTimeout = cfg.ReadTimeout.String()
|
jcfg.ReadTimeout = cfg.ReadTimeout.String()
|
||||||
jcfg.ReadHeaderTimeout = cfg.ReadHeaderTimeout.String()
|
jcfg.ReadHeaderTimeout = cfg.ReadHeaderTimeout.String()
|
||||||
jcfg.WriteTimeout = cfg.WriteTimeout.String()
|
jcfg.WriteTimeout = cfg.WriteTimeout.String()
|
||||||
jcfg.IdleTimeout = cfg.IdleTimeout.String()
|
jcfg.IdleTimeout = cfg.IdleTimeout.String()
|
||||||
|
|
||||||
|
if cfg.ID != "" {
|
||||||
|
jcfg.ID = peer.IDB58Encode(cfg.ID)
|
||||||
|
}
|
||||||
|
if cfg.PrivateKey != nil {
|
||||||
|
pkeyBytes, err := cfg.PrivateKey.Bytes()
|
||||||
|
if err == nil {
|
||||||
|
pKey := base64.StdEncoding.EncodeToString(pkeyBytes)
|
||||||
|
jcfg.PrivateKey = pKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cfg.Libp2pListenAddr != nil {
|
||||||
|
jcfg.Libp2pListenMultiaddress = cfg.Libp2pListenAddr.String()
|
||||||
|
}
|
||||||
|
|
||||||
jcfg.BasicAuthCreds = cfg.BasicAuthCreds
|
jcfg.BasicAuthCreds = cfg.BasicAuthCreds
|
||||||
|
|
||||||
raw, err = config.DefaultJSONMarshal(jcfg)
|
raw, err = config.DefaultJSONMarshal(jcfg)
|
||||||
|
|
|
@ -3,6 +3,10 @@ package rest
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
crypto "github.com/libp2p/go-libp2p-crypto"
|
||||||
|
peer "github.com/libp2p/go-libp2p-peer"
|
||||||
|
ma "github.com/multiformats/go-multiaddr"
|
||||||
)
|
)
|
||||||
|
|
||||||
var cfgJSON = []byte(`
|
var cfgJSON = []byte(`
|
||||||
|
@ -28,7 +32,7 @@ func TestLoadJSON(t *testing.T) {
|
||||||
j := &jsonConfig{}
|
j := &jsonConfig{}
|
||||||
|
|
||||||
json.Unmarshal(cfgJSON, j)
|
json.Unmarshal(cfgJSON, j)
|
||||||
j.ListenMultiaddress = "abc"
|
j.HTTPListenMultiaddress = "abc"
|
||||||
tst, _ := json.Marshal(j)
|
tst, _ := json.Marshal(j)
|
||||||
err = cfg.LoadJSON(tst)
|
err = cfg.LoadJSON(tst)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -37,7 +41,7 @@ func TestLoadJSON(t *testing.T) {
|
||||||
|
|
||||||
j = &jsonConfig{}
|
j = &jsonConfig{}
|
||||||
json.Unmarshal(cfgJSON, j)
|
json.Unmarshal(cfgJSON, j)
|
||||||
j.ReadTimeout = "0"
|
j.ReadTimeout = "-1"
|
||||||
tst, _ = json.Marshal(j)
|
tst, _ = json.Marshal(j)
|
||||||
err = cfg.LoadJSON(tst)
|
err = cfg.LoadJSON(tst)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -61,6 +65,72 @@ func TestLoadJSON(t *testing.T) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("expected error with TLS configuration")
|
t.Error("expected error with TLS configuration")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
j = &jsonConfig{}
|
||||||
|
json.Unmarshal(cfgJSON, j)
|
||||||
|
j.ID = "abc"
|
||||||
|
tst, _ = json.Marshal(j)
|
||||||
|
err = cfg.LoadJSON(tst)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("expected error with ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
j = &jsonConfig{}
|
||||||
|
json.Unmarshal(cfgJSON, j)
|
||||||
|
j.Libp2pListenMultiaddress = "abc"
|
||||||
|
tst, _ = json.Marshal(j)
|
||||||
|
err = cfg.LoadJSON(tst)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("expected error with libp2p address")
|
||||||
|
}
|
||||||
|
|
||||||
|
j = &jsonConfig{}
|
||||||
|
json.Unmarshal(cfgJSON, j)
|
||||||
|
j.PrivateKey = "abc"
|
||||||
|
tst, _ = json.Marshal(j)
|
||||||
|
err = cfg.LoadJSON(tst)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("expected error with private key")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLibp2pConfig(t *testing.T) {
|
||||||
|
cfg := &Config{}
|
||||||
|
err := cfg.Default()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
priv, pub, err := crypto.GenerateKeyPair(crypto.RSA, 2048)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
pid, err := peer.IDFromPublicKey(pub)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
cfg.ID = pid
|
||||||
|
cfg.PrivateKey = priv
|
||||||
|
addr, _ := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/10001")
|
||||||
|
cfg.Libp2pListenAddr = addr
|
||||||
|
|
||||||
|
err = cfg.Validate()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
id, _ := peer.IDB58Decode("QmTQ6oKHDwFjzr4ihirVCLJe8CxanxD3ZjGRYzubFuNDjE")
|
||||||
|
cfg.ID = id
|
||||||
|
err = cfg.Validate()
|
||||||
|
if err == nil {
|
||||||
|
t.Error("expected id-privkey mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.PrivateKey = nil
|
||||||
|
err = cfg.Validate()
|
||||||
|
if err == nil {
|
||||||
|
t.Error("expected missing private key error")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToJSON(t *testing.T) {
|
func TestToJSON(t *testing.T) {
|
||||||
|
@ -84,13 +154,8 @@ func TestDefault(t *testing.T) {
|
||||||
t.Fatal("error validating")
|
t.Fatal("error validating")
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.ListenAddr = nil
|
|
||||||
if cfg.Validate() == nil {
|
|
||||||
t.Fatal("expected error validating")
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.Default()
|
cfg.Default()
|
||||||
cfg.IdleTimeout = 0
|
cfg.IdleTimeout = -1
|
||||||
if cfg.Validate() == nil {
|
if cfg.Validate() == nil {
|
||||||
t.Fatal("expected error validating")
|
t.Fatal("expected error validating")
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ func NewAPI(cfg *Config) (*API, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
n, addr, err := manet.DialArgs(cfg.ListenAddr)
|
n, addr, err := manet.DialArgs(cfg.HTTPListenAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,7 @@ func (api *API) run() {
|
||||||
defer api.wg.Done()
|
defer api.wg.Done()
|
||||||
<-api.rpcReady
|
<-api.rpcReady
|
||||||
|
|
||||||
logger.Infof("REST API: %s", api.config.ListenAddr)
|
logger.Infof("REST API: %s", api.config.HTTPListenAddr)
|
||||||
err := api.server.Serve(api.listener)
|
err := api.server.Serve(api.listener)
|
||||||
if err != nil && !strings.Contains(err.Error(), "closed network connection") {
|
if err != nil && !strings.Contains(err.Error(), "closed network connection") {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
|
|
|
@ -20,7 +20,7 @@ func testAPI(t *testing.T) *API {
|
||||||
|
|
||||||
cfg := &Config{}
|
cfg := &Config{}
|
||||||
cfg.Default()
|
cfg.Default()
|
||||||
cfg.ListenAddr = apiMAddr
|
cfg.HTTPListenAddr = apiMAddr
|
||||||
|
|
||||||
rest, err := NewAPI(cfg)
|
rest, err := NewAPI(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -179,6 +179,10 @@ func (cfg *Config) Validate() error {
|
||||||
return errors.New("no cluster.private_key set")
|
return errors.New("no cluster.private_key set")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !cfg.ID.MatchesPrivateKey(cfg.PrivateKey) {
|
||||||
|
return errors.New("cluster.ID does not match the private_key")
|
||||||
|
}
|
||||||
|
|
||||||
if cfg.Peers == nil {
|
if cfg.Peers == nil {
|
||||||
return errors.New("cluster.peers is undefined")
|
return errors.New("cluster.peers is undefined")
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ var testingRaftCfg = []byte(`{
|
||||||
}`)
|
}`)
|
||||||
|
|
||||||
var testingAPICfg = []byte(`{
|
var testingAPICfg = []byte(`{
|
||||||
"listen_multiaddress": "/ip4/127.0.0.1/tcp/10002",
|
"http_listen_multiaddress": "/ip4/127.0.0.1/tcp/10002",
|
||||||
"read_timeout": "30s",
|
"read_timeout": "30s",
|
||||||
"read_header_timeout": "5s",
|
"read_header_timeout": "5s",
|
||||||
"write_timeout": "1m0s",
|
"write_timeout": "1m0s",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user