You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
2.5 KiB
100 lines
2.5 KiB
// Package garage contains helper functions and types which are useful for
|
|
// setting up garage configs, processes, and deployments.
|
|
package garage
|
|
|
|
import (
|
|
crypticnet "cryptic-net"
|
|
"crypto/ed25519"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"net"
|
|
"strconv"
|
|
)
|
|
|
|
const (
|
|
|
|
// Region is the region which garage is configured with.
|
|
Region = "garage"
|
|
|
|
// GlobalBucket is the name of the global garage bucket which is
|
|
// accessible to all hosts in the network.
|
|
GlobalBucket = "cryptic-net-global"
|
|
)
|
|
|
|
// GeneratePeerKey deterministically generates a public/private keys which can
|
|
// be used as a garage node key.
|
|
//
|
|
// DANGER: This function will deterministically produce public/private keys
|
|
// given some arbitrary input. This is NEVER what you want. It's only being used
|
|
// in cryptic-net for a very specific purpose for which I think it's ok and is
|
|
// very necessary, and people are probably _still_ going to yell at me.
|
|
//
|
|
func GeneratePeerKey(ip string, port int) (pubKey, privKey []byte, err error) {
|
|
|
|
input := []byte(net.JoinHostPort(ip, strconv.Itoa(port)))
|
|
|
|
// Append the length of the input to the input, so that the input "foo"
|
|
// doesn't generate the same key as the input "foofoo".
|
|
input = strconv.AppendInt(input, int64(len(input)), 10)
|
|
|
|
return ed25519.GenerateKey(NewInfiniteReader(input))
|
|
}
|
|
|
|
// GeneratePeerID generates the peer id for the given peer.
|
|
//
|
|
// DANGER: See warning on GenerateNodeKey.
|
|
func GeneratePeerID(ip string, port int) (string, error) {
|
|
|
|
peerNodeKeyPub, _, err := GeneratePeerKey(ip, port)
|
|
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return hex.EncodeToString(peerNodeKeyPub), nil
|
|
}
|
|
|
|
// GeneratePeerAddr generates the peer address (e.g. "id@ip:port") for the
|
|
// given peer.
|
|
//
|
|
// DANGER: See warning on GenerateNodeKey.
|
|
func GeneratePeerAddr(ip string, port int) (string, error) {
|
|
|
|
id, err := GeneratePeerID(ip, port)
|
|
|
|
if err != nil {
|
|
return "", fmt.Errorf("generating peer id: %w", err)
|
|
}
|
|
|
|
return fmt.Sprintf("%s@%s", id, net.JoinHostPort(ip, strconv.Itoa(port))), nil
|
|
}
|
|
|
|
// BootstrapPeerAddrs generates the list of bootstrap peer strings based on the
|
|
// bootstrap hosts.
|
|
func BootstrapPeerAddrs(hosts map[string]crypticnet.Host) ([]string, error) {
|
|
|
|
var peers []string
|
|
|
|
for _, host := range hosts {
|
|
|
|
if host.Garage == nil {
|
|
continue
|
|
}
|
|
|
|
for _, instance := range host.Garage.Instances {
|
|
|
|
peer, err := GeneratePeerAddr(host.Nebula.IP, instance.RPCPort)
|
|
|
|
if err != nil {
|
|
return nil, fmt.Errorf(
|
|
"generating peer address with input %q,%d: %w",
|
|
host.Nebula.IP, instance.RPCPort, err,
|
|
)
|
|
}
|
|
|
|
peers = append(peers, peer)
|
|
}
|
|
}
|
|
|
|
return peers, nil
|
|
}
|
|
|