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.
 
 
 
isle/go-workspace/src/garage/garageutil.go

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
}