Keep what an adopted node reports holding, the firewall it found and what is reachable on it (hq ADR 0100)
This commit is contained in:
@@ -2,9 +2,13 @@ package inventory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
// A node is adopted or converged (novox/hq ADR 0100).
|
||||
@@ -113,7 +117,9 @@ func (i *Inventory) Converge(ctx context.Context, nodeName string) ([]string, er
|
||||
return nil, err
|
||||
}
|
||||
if _, err := tx.Exec(ctx,
|
||||
`update node set adopted = false, adopted_since = null, converged_at = now() where id = $1`,
|
||||
`update node set adopted = false, adopted_since = null, converged_at = now(),
|
||||
held = null, reachable = null
|
||||
where id = $1`,
|
||||
node.ID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -147,3 +153,94 @@ func (i *Inventory) Taken(ctx context.Context, nodeName string) ([]string, error
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
// Held is one file or container an adopted node found and keeps as it was until its module is
|
||||
// taken. The node's own account, kept as it said it.
|
||||
type Held struct {
|
||||
ID string `json:"id"`
|
||||
Module string `json:"module"`
|
||||
Kind string `json:"kind"`
|
||||
Target string `json:"target"`
|
||||
Since time.Time `json:"since"`
|
||||
Changed string `json:"changed,omitempty"`
|
||||
Kept string `json:"kept,omitempty"`
|
||||
}
|
||||
|
||||
// Reach is one thing reachable on an adopted node: a listening socket or a published port.
|
||||
type Reach struct {
|
||||
Protocol string `json:"protocol"`
|
||||
Address string `json:"address"`
|
||||
Port int `json:"port"`
|
||||
By string `json:"by,omitempty"`
|
||||
Published bool `json:"published,omitempty"`
|
||||
ContainerPort int `json:"container-port,omitempty"`
|
||||
}
|
||||
|
||||
// Adoption is what an adopted node last said about adoption, and when.
|
||||
type Adoption struct {
|
||||
Held []Held
|
||||
Firewall string
|
||||
Reachable []Reach
|
||||
// At is when it said so; zero when it never has.
|
||||
At time.Time
|
||||
}
|
||||
|
||||
// RecordAdoption keeps what a node last reported about adoption, replacing what was there: the
|
||||
// question is the machine as it is now.
|
||||
func (i *Inventory) RecordAdoption(ctx context.Context, node string, held []Held, firewall string,
|
||||
reachable []Reach) error {
|
||||
heldRaw, err := json.Marshal(nonNil(held))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reachRaw, err := json.Marshal(nonNil(reachable))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = i.store.Pool().Exec(ctx,
|
||||
`update node set held = $2, firewall = nullif($3, ''), reachable = $4,
|
||||
adoption_reported = now(), last_seen = now()
|
||||
where id = $1`, node, heldRaw, firewall, reachRaw)
|
||||
return err
|
||||
}
|
||||
|
||||
func nonNil[T any](s []T) []T {
|
||||
if s == nil {
|
||||
return []T{}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// AdoptionOf is what a node last reported about adoption.
|
||||
func (i *Inventory) AdoptionOf(ctx context.Context, name string) (Adoption, error) {
|
||||
var heldRaw, reachRaw []byte
|
||||
var firewall *string
|
||||
var at *time.Time
|
||||
err := i.store.Pool().QueryRow(ctx,
|
||||
`select held, firewall, reachable, adoption_reported from node where name = $1`, name).
|
||||
Scan(&heldRaw, &firewall, &reachRaw, &at)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return Adoption{}, fmt.Errorf("%w: %s", ErrNoSuchNode, name)
|
||||
}
|
||||
if err != nil {
|
||||
return Adoption{}, err
|
||||
}
|
||||
var out Adoption
|
||||
if firewall != nil {
|
||||
out.Firewall = *firewall
|
||||
}
|
||||
if at != nil {
|
||||
out.At = *at
|
||||
}
|
||||
if len(heldRaw) > 0 {
|
||||
if err := json.Unmarshal(heldRaw, &out.Held); err != nil {
|
||||
return Adoption{}, err
|
||||
}
|
||||
}
|
||||
if len(reachRaw) > 0 {
|
||||
if err := json.Unmarshal(reachRaw, &out.Reachable); err != nil {
|
||||
return Adoption{}, err
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
-- What an adopted node last reported about adoption (novox/hq ADR 0100): the files and containers
|
||||
-- it found and holds until their module is taken, the firewall it found, and what is reachable on
|
||||
-- the machine now — which converging it previews, so nothing closes without being named first.
|
||||
--
|
||||
-- The last report, replaced, like what a node owns: the question is the machine as it is now.
|
||||
-- Kept apart from node_report because a node reports it on its own schedule, when what it holds
|
||||
-- changes, and not only after an apply.
|
||||
|
||||
alter table node add column held jsonb;
|
||||
alter table node add column firewall text;
|
||||
alter table node add column reachable jsonb;
|
||||
alter table node add column adoption_reported timestamptz;
|
||||
Reference in New Issue
Block a user