mesh/delivery closed: a newer head of the same pull request
mesh/check failed: shanks: novox/mesh-catalog#505: checks/placement/go.mod names mesh-sdk 91413de33516, which is neither on mesh-sdk's trunk nor the g…
99 lines
4.4 KiB
Go
99 lines
4.4 KiB
Go
package delivery
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
)
|
|
|
|
// A node's record is what the machine observes of itself (issue 1126, ADR 0555 §3), written by its own agent in its
|
|
// own have key, `<node>.node` of the node-engine's have bucket (HaveNode.Record), whenever an observed fact changes and
|
|
// only when the value differs. The key's change is the event its readers hear: every node and the parts that compose
|
|
// watch it. Where a module runs, and every fact a person decides of the node (its endpoint, site, hub, address on the
|
|
// private network, public domain, accounts, the tunnel found at adoption), are the catalogue's placement
|
|
// (placement.go). Nothing in it is secret: its keys are public halves.
|
|
|
|
// RecordTunnel is a tunnel found on a node when it was adopted, as compose.Tunnel holds it: public keys and addresses
|
|
// only. After the node took it over the tunnel is no longer there to observe, so it is kept as what was decided at
|
|
// adoption, in the node's placement (NodeDecided.Tunnel).
|
|
type RecordTunnel struct {
|
|
Interface string `json:"interface"`
|
|
Unit string `json:"unit,omitempty"`
|
|
Config string `json:"config,omitempty"`
|
|
Port int `json:"port,omitempty"`
|
|
MTU int `json:"mtu,omitempty"`
|
|
Address string `json:"address,omitempty"`
|
|
Range string `json:"range,omitempty"`
|
|
PublicKey string `json:"public-key,omitempty"`
|
|
Peers []RecordTunnelPeer `json:"peers,omitempty"`
|
|
}
|
|
|
|
// RecordTunnelPeer is one peer of a found tunnel.
|
|
type RecordTunnelPeer struct {
|
|
PublicKey string `json:"public-key"`
|
|
Address string `json:"address,omitempty"`
|
|
}
|
|
|
|
// NodeRecord is one node's record: what the machine observes of itself (issue 1126, ADR 0555: what a person decides
|
|
// lives in the catalogue's placement file, Placement.Decided; what the machine observes lives here). TunnelKey is the
|
|
// public key of its private-network tunnel; Certificate the one the mesh issued for its internal name, public, as the
|
|
// node holds it. The tunnel found at adoption and the names given to its peers are decisions kept in the placement;
|
|
// whether the hub took its found tunnel over, and which node enrolled under a carried peer's key, are read from both.
|
|
type NodeRecord struct {
|
|
V int `json:"v"`
|
|
Node string `json:"node"`
|
|
TunnelKey string `json:"tunnel-key,omitempty"`
|
|
Capabilities []string `json:"capabilities,omitempty"`
|
|
SealingKey string `json:"sealing-key,omitempty"`
|
|
ServingKey string `json:"serving-key,omitempty"`
|
|
Certificate string `json:"certificate,omitempty"`
|
|
OutwardLinks []string `json:"outward-links,omitempty"`
|
|
Networks []catalogue.AttachedNetwork `json:"networks,omitempty"`
|
|
NetworksSaid bool `json:"networks-said,omitempty"`
|
|
Contract int `json:"contract,omitempty"`
|
|
// Authority is the mesh's own certificate as this machine holds it (public): the one its declaration last wrote where
|
|
// a module asked for it. A node composing its own composes a certificate with it (compose.Input.Authority).
|
|
Authority string `json:"authority,omitempty"`
|
|
}
|
|
|
|
func (r NodeRecord) check() error {
|
|
if err := checkName("node", r.Node); err != nil {
|
|
return err
|
|
}
|
|
for _, c := range r.Capabilities {
|
|
if c == "" {
|
|
return fmt.Errorf("delivery: the record of %s names an empty capability", r.Node)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// EncodeNodeRecord is r as JSON at Version; it refuses what DecodeNodeRecord refuses.
|
|
func EncodeNodeRecord(r NodeRecord) ([]byte, error) {
|
|
if err := r.check(); err != nil {
|
|
return nil, err
|
|
}
|
|
r.V = Version
|
|
return json.Marshal(r)
|
|
}
|
|
|
|
// DecodeNodeRecord reads a node record; it refuses an unknown version (ErrUnknownVersion), a node that is not a name, and
|
|
// an empty capability.
|
|
func DecodeNodeRecord(data []byte) (NodeRecord, error) {
|
|
var r NodeRecord
|
|
if err := decode(data, &r); err != nil {
|
|
return NodeRecord{}, err
|
|
}
|
|
if err := r.check(); err != nil {
|
|
return NodeRecord{}, err
|
|
}
|
|
return r, nil
|
|
}
|
|
|
|
// SameNodeRecord says whether two records are the same value, so the agent writes only when they differ.
|
|
func SameNodeRecord(a, b NodeRecord) bool {
|
|
a.V, b.V = 0, 0
|
|
return jsonEqual(a, b)
|
|
}
|