A cross-node module reaches the broker by the hub's overlay name #27
@@ -216,6 +216,11 @@ func builderCommand(ctx context.Context, args []string) error {
|
|||||||
}
|
}
|
||||||
defer inv.Close()
|
defer inv.Close()
|
||||||
|
|
||||||
|
brokerAddr, err := brokerReachableAt(ctx, inv, known, *forNode)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// The URL and what verifies the broker, together. A mesh's broker presents a certificate
|
// The URL and what verifies the broker, together. A mesh's broker presents a certificate
|
||||||
// of the mesh's own, which is in no public trust store — so a URL on its own reaches only
|
// of the mesh's own, which is in no public trust store — so a URL on its own reaches only
|
||||||
// a broker somebody else vouches for, and the connection fails at TLS with an error about
|
// a broker somebody else vouches for, and the connection fails at TLS with an error about
|
||||||
@@ -228,7 +233,7 @@ func builderCommand(ctx context.Context, args []string) error {
|
|||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
Fingerprint string `json:"fingerprint,omitempty"`
|
Fingerprint string `json:"fingerprint,omitempty"`
|
||||||
}{
|
}{
|
||||||
URL: fmt.Sprintf("amqps://%s:%s@%s/", name, password, known.Address),
|
URL: fmt.Sprintf("amqps://%s:%s@%s/", name, password, brokerAddr),
|
||||||
Fingerprint: known.Fingerprint,
|
Fingerprint: known.Fingerprint,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -283,6 +284,10 @@ func moduleCommand(ctx context.Context, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot deliver a credential without knowing where the broker is: %w", err)
|
return fmt.Errorf("cannot deliver a credential without knowing where the broker is: %w", err)
|
||||||
}
|
}
|
||||||
|
brokerAddr, err := brokerReachableAt(ctx, inv, known, *forNode)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// The URL and what verifies the broker, together — a mesh's broker presents its own
|
// The URL and what verifies the broker, together — a mesh's broker presents its own
|
||||||
// certificate, in no public trust store, so a URL alone fails at TLS (as `builder issue`).
|
// certificate, in no public trust store, so a URL alone fails at TLS (as `builder issue`).
|
||||||
held, err := json.Marshal(struct {
|
held, err := json.Marshal(struct {
|
||||||
@@ -291,7 +296,7 @@ func moduleCommand(ctx context.Context, args []string) error {
|
|||||||
Node string `json:"node"`
|
Node string `json:"node"`
|
||||||
Module string `json:"module"`
|
Module string `json:"module"`
|
||||||
}{
|
}{
|
||||||
URL: fmt.Sprintf("amqps://%s:%s@%s/", account, password, known.Address),
|
URL: fmt.Sprintf("amqps://%s:%s@%s/", account, password, brokerAddr),
|
||||||
Fingerprint: known.Fingerprint,
|
Fingerprint: known.Fingerprint,
|
||||||
// The node and module the account is for, so the runtime names its queue as the mesh
|
// The node and module the account is for, so the runtime names its queue as the mesh
|
||||||
// scoped it (<node>.<module>.events) without a manifest having to interpolate a node.
|
// scoped it (<node>.<module>.events) without a manifest having to interpolate a node.
|
||||||
@@ -461,3 +466,37 @@ func pinCommand(ctx context.Context, args []string, setting bool) error {
|
|||||||
fmt.Printf(" run `push %s` to send it\n", args[0])
|
fmt.Printf(" run `push %s` to send it\n", args[0])
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// brokerReachableAt is the broker's address as the given node can reach it.
|
||||||
|
//
|
||||||
|
// The genesis address (MESH_BROKER_ADDRESS) is the broker's public endpoint — reachable from the
|
||||||
|
// control-node itself, but not routed to another node, whose firewall admits only the overlay
|
||||||
|
// (from:mesh). The foundation, and so the broker, sits on the control-node, which is the overlay
|
||||||
|
// hub; a node that is on the overlay reaches the broker by the hub's `.internal` name, which the
|
||||||
|
// firewall admits and every node resolves. A node not yet on the overlay — at genesis, before any
|
||||||
|
// `overlay place`, which is when the builder's account is issued — keeps the genesis address it
|
||||||
|
// was given, so nothing about bring-up changes. This is issue 055.
|
||||||
|
func brokerReachableAt(ctx context.Context, inv *inventory.Inventory, known broker.Broker, node string) (string, error) {
|
||||||
|
overlays, err := inv.Overlays(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
var hub string
|
||||||
|
onOverlay := false
|
||||||
|
for _, o := range overlays {
|
||||||
|
if o.Hub && o.Address != "" {
|
||||||
|
hub = o.Name
|
||||||
|
}
|
||||||
|
if o.Name == node && o.Address != "" {
|
||||||
|
onOverlay = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if hub == "" || !onOverlay {
|
||||||
|
return known.Address, nil
|
||||||
|
}
|
||||||
|
_, port, err := net.SplitHostPort(known.Address)
|
||||||
|
if err != nil {
|
||||||
|
return known.Address, nil
|
||||||
|
}
|
||||||
|
return net.JoinHostPort(overlay.InternalName(hub), port), nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user