api/rest/client: add private networks support.
Also, re-use some convinient functions provided by pnet. License: MIT Signed-off-by: Hector Sanjuan <code@hector.link>
This commit is contained in:
parent
bbe2407531
commit
4bed9d0076
|
@ -2,6 +2,7 @@ package client
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
|
@ -11,8 +12,10 @@ import (
|
|||
logging "github.com/ipfs/go-log"
|
||||
libp2p "github.com/libp2p/go-libp2p"
|
||||
host "github.com/libp2p/go-libp2p-host"
|
||||
ipnet "github.com/libp2p/go-libp2p-interface-pnet"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
peerstore "github.com/libp2p/go-libp2p-peerstore"
|
||||
pnet "github.com/libp2p/go-libp2p-pnet"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
madns "github.com/multiformats/go-multiaddr-dns"
|
||||
manet "github.com/multiformats/go-multiaddr-net"
|
||||
|
@ -125,7 +128,21 @@ func (c *Client) setupHTTPClient() error {
|
|||
return err
|
||||
}
|
||||
|
||||
h, err := libp2p.New(c.ctx)
|
||||
var prot ipnet.Protector
|
||||
if c.config.ProtectorKey != nil && len(c.config.ProtectorKey) > 0 {
|
||||
if len(c.config.ProtectorKey) != 32 {
|
||||
return errors.New("Length of ProtectorKey should be 32")
|
||||
}
|
||||
var key [32]byte
|
||||
copy(key[:], c.config.ProtectorKey)
|
||||
|
||||
prot, err = pnet.NewV1ProtectorFromBytes(&key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
h, err := libp2p.New(c.ctx, libp2p.PrivateNetwork(prot))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/ipfs/ipfs-cluster/test"
|
||||
|
||||
libp2p "github.com/libp2p/go-libp2p"
|
||||
pnet "github.com/libp2p/go-libp2p-pnet"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
|
@ -20,10 +21,16 @@ func testAPI(t *testing.T) *rest.API {
|
|||
cfg := &rest.Config{}
|
||||
cfg.Default()
|
||||
cfg.HTTPListenAddr = apiMAddr
|
||||
var secret [32]byte
|
||||
prot, err := pnet.NewV1ProtectorFromBytes(&secret)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
h, err := libp2p.New(
|
||||
context.Background(),
|
||||
libp2p.ListenAddrs(apiMAddr),
|
||||
libp2p.PrivateNetwork(prot),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -73,6 +80,7 @@ func testClientHTTP(t *testing.T, api *rest.API) *Client {
|
|||
func testClientLibp2p(t *testing.T, api *rest.API) *Client {
|
||||
cfg := &Config{
|
||||
PeerAddr: peerMAddr(api),
|
||||
ProtectorKey: make([]byte, 32),
|
||||
DisableKeepAlives: true,
|
||||
}
|
||||
c, err := NewClient(cfg)
|
||||
|
|
|
@ -40,7 +40,7 @@ var (
|
|||
// ErrNoEndpointEnabled is returned when the API is created but
|
||||
// no HTTPListenAddr, nor libp2p configuration fields, nor a libp2p
|
||||
// Host are provided.
|
||||
ErrNoEndointsEnabled = errors.New("Neither the libp2p nor the HTTP endpoints are enabled")
|
||||
ErrNoEndpointsEnabled = errors.New("Neither the libp2p nor the HTTP endpoints are enabled")
|
||||
|
||||
// ErrHTTPEndpointNotEnabled is returned when trying to perform
|
||||
// operations that rely on the HTTPEndpoint but it is disabled.
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package ipfscluster
|
||||
|
||||
import (
|
||||
crand "crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
|
@ -15,6 +14,7 @@ import (
|
|||
|
||||
crypto "github.com/libp2p/go-libp2p-crypto"
|
||||
peer "github.com/libp2p/go-libp2p-peer"
|
||||
pnet "github.com/libp2p/go-libp2p-pnet"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
|
@ -159,11 +159,11 @@ func (cfg *Config) Default() error {
|
|||
// --
|
||||
|
||||
// cluster secret
|
||||
clusterSecret, err := generateClusterSecret()
|
||||
clusterSecret, err := pnet.GenerateV1Bytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Secret = clusterSecret
|
||||
cfg.Secret = (*clusterSecret)[:]
|
||||
// --
|
||||
return nil
|
||||
}
|
||||
|
@ -436,12 +436,3 @@ func DecodeClusterSecret(hexSecret string) ([]byte, error) {
|
|||
return nil, fmt.Errorf("input secret is %d bytes, cluster secret should be 32", secretLen)
|
||||
}
|
||||
}
|
||||
|
||||
func generateClusterSecret() ([]byte, error) {
|
||||
secretBytes := make([]byte, 32)
|
||||
_, err := crand.Read(secretBytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading from rand: %v", err)
|
||||
}
|
||||
return secretBytes, nil
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package ipfscluster
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
|
||||
libp2p "github.com/libp2p/go-libp2p"
|
||||
host "github.com/libp2p/go-libp2p-host"
|
||||
|
@ -17,14 +15,13 @@ import (
|
|||
// provided cluster configuration.
|
||||
func NewClusterHost(ctx context.Context, cfg *Config) (host.Host, error) {
|
||||
var prot ipnet.Protector
|
||||
var err error
|
||||
|
||||
// Create protector if we have a secret.
|
||||
if cfg.Secret != nil && len(cfg.Secret) > 0 {
|
||||
protKey, err := SecretToProtectorKey(cfg.Secret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
prot, err = pnet.NewProtector(strings.NewReader(protKey))
|
||||
var key [32]byte
|
||||
copy(key[:], cfg.Secret)
|
||||
prot, err = pnet.NewV1ProtectorFromBytes(&key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -41,17 +38,6 @@ func NewClusterHost(ctx context.Context, cfg *Config) (host.Host, error) {
|
|||
)
|
||||
}
|
||||
|
||||
// SecretToProtectorKey converts a private network secret
|
||||
// provided as a byte-slice into the format expected by go-libp2p-pnet
|
||||
func SecretToProtectorKey(secret []byte) (string, error) {
|
||||
var key bytes.Buffer
|
||||
key.WriteString("/key/swarm/psk/1.0.0/\n")
|
||||
key.WriteString("/base16/\n")
|
||||
key.WriteString(EncodeProtectorKey(secret))
|
||||
|
||||
return key.String(), nil
|
||||
}
|
||||
|
||||
// EncodeProtectorKey converts a byte slice to its hex string representation.
|
||||
func EncodeProtectorKey(secretBytes []byte) string {
|
||||
return hex.EncodeToString(secretBytes)
|
||||
|
|
10
pnet_test.go
10
pnet_test.go
|
@ -1,6 +1,10 @@
|
|||
package ipfscluster
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"testing"
|
||||
|
||||
pnet "github.com/libp2p/go-libp2p-pnet"
|
||||
)
|
||||
|
||||
func TestClusterSecretFormat(t *testing.T) {
|
||||
goodSecret := "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
|
@ -54,11 +58,11 @@ func TestSimplePNet(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestClusterSecretRequired(t *testing.T) {
|
||||
cl1Secret, err := generateClusterSecret()
|
||||
cl1Secret, err := pnet.GenerateV1Bytes()
|
||||
if err != nil {
|
||||
t.Fatal("Unable to generate cluster secret.")
|
||||
}
|
||||
cl1, _ := createOnePeerCluster(t, 1, cl1Secret)
|
||||
cl1, _ := createOnePeerCluster(t, 1, (*cl1Secret)[:])
|
||||
cl2, _ := createOnePeerCluster(t, 2, testingClusterSecret)
|
||||
defer cleanRaft()
|
||||
defer cl1.Shutdown()
|
||||
|
|
Loading…
Reference in New Issue
Block a user