Manage external site-prober actions va API and Dashboard
This commit is contained in:
1 parent
f22ad569b6
commit
42f584dd3c
28 files changed
+717
-32
No files matched your search
@@ -31,28 +31,28 @@ type CheckConfig struct {
|
||||
}
|
||||
|
||||
type Orchestrator struct {
|
||||
DB *db.DB
|
||||
OS openstack.FloatingIPClient
|
||||
Cfg config.OrchestratorConfig
|
||||
Agg config.AggregationConfig
|
||||
Inbound config.InboundConfig
|
||||
Log *slog.Logger
|
||||
DB *db.DB
|
||||
OS openstack.FloatingIPClient
|
||||
Cfg config.OrchestratorConfig
|
||||
Agg config.AggregationConfig
|
||||
Log *slog.Logger
|
||||
}
|
||||
|
||||
// New constructs an Orchestrator. Egress check types/targets and prober
|
||||
// sites are no longer taken from cfg — they're read from the database on
|
||||
// every use (see AssignmentForValidator, expectedCheckCount,
|
||||
// isReadyToAggregate) so admin API changes to them take effect without a
|
||||
// restart. cfg.Validators/.Sites/.CheckTypes/.Targets/.IPAddresses are only
|
||||
// consulted once, at process startup, by db.BootstrapFromConfig.
|
||||
// New constructs an Orchestrator. Egress check types/targets, prober sites,
|
||||
// and prober inbound check config (ports/icmp) are no longer taken from
|
||||
// cfg — they're read from the database on every use (see
|
||||
// AssignmentForValidator, expectedCheckCount, isReadyToAggregate,
|
||||
// httpapi.handleProberAssignments) so admin API changes to them take effect
|
||||
// without a restart. cfg.Validators/.Sites/.CheckTypes/.Targets/.Inbound/
|
||||
// .IPAddresses are only consulted once, at process startup, by
|
||||
// db.BootstrapFromConfig.
|
||||
func New(d *db.DB, osClient openstack.FloatingIPClient, cfg *config.ControlAPI, log *slog.Logger) *Orchestrator {
|
||||
return &Orchestrator{
|
||||
DB: d,
|
||||
OS: osClient,
|
||||
Cfg: cfg.Orchestrator,
|
||||
Agg: cfg.Aggregation,
|
||||
Inbound: cfg.Inbound,
|
||||
Log: log,
|
||||
DB: d,
|
||||
OS: osClient,
|
||||
Cfg: cfg.Orchestrator,
|
||||
Agg: cfg.Aggregation,
|
||||
Log: log,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,10 +509,10 @@ func (o *Orchestrator) aggregateAndRelease(ctx context.Context, item db.IPQueueI
|
||||
|
||||
// expectedCheckCount is the number of check rows a fully-reported IP should
|
||||
// have: one per (egress check-type x target) plus one per (site x inbound
|
||||
// port/icmp probe). Reads the current check_types/targets/sites from the
|
||||
// database, so a config change between assignment and aggregation is
|
||||
// reflected in this specific aggregation (see the "accepted tradeoff" note
|
||||
// in docs/PLAN_API_CONFIG_MANAGEMENT.md).
|
||||
// port/icmp probe). Reads the current check_types/targets/sites/inbound
|
||||
// checks from the database, so a config change between assignment and
|
||||
// aggregation is reflected in this specific aggregation (see the "accepted
|
||||
// tradeoff" note in docs/PLAN_API_CONFIG_MANAGEMENT.md).
|
||||
func (o *Orchestrator) expectedCheckCount(ctx context.Context) (int, error) {
|
||||
resolved, err := o.DB.ListResolvedCheckTypes(ctx)
|
||||
if err != nil {
|
||||
@@ -526,8 +526,12 @@ func (o *Orchestrator) expectedCheckCount(ctx context.Context) (int, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
inboundPerSite := len(o.Inbound.Ports)
|
||||
if o.Inbound.ICMP {
|
||||
inbound, err := o.DB.GetInboundChecks(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
inboundPerSite := len(inbound.Ports)
|
||||
if inbound.ICMP {
|
||||
inboundPerSite++
|
||||
}
|
||||
return egress + inboundPerSite*len(sites), nil
|
||||
|
||||
@@ -575,3 +575,52 @@ func TestInboundChecksPartialSites(t *testing.T) {
|
||||
t.Fatalf("expected pass, got %s", ip.OverallResult)
|
||||
}
|
||||
}
|
||||
|
||||
// TestExpectedCheckCountReflectsInboundChecksConfigChange confirms
|
||||
// expectedCheckCount reads inbound_checks (ports/icmp) from the database on
|
||||
// every use, not a cached copy — same "accepted tradeoff" already true of
|
||||
// check_types/targets/sites (see expectedCheckCount's doc comment).
|
||||
func TestExpectedCheckCountReflectsInboundChecksConfigChange(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
sites := []config.SiteConfig{{SiteID: "site-1", Index: 1}}
|
||||
o, d, mock := newTestOrchestratorWithSites(t, 180, sites)
|
||||
// newTestOrchestratorWithSites seeds Inbound: {Ports: [22, 80], ICMP: true}
|
||||
// (3 inbound checks expected per site).
|
||||
mock.Seed("fip-1", "1.2.3.4", "svc-project")
|
||||
_ = d.RegisterValidator(ctx, "validator-1", "host-1", "port-1", "v0.1")
|
||||
_ = d.SeedQueue(ctx, []string{"1.2.3.4"})
|
||||
|
||||
o.Tick(ctx)
|
||||
ip, _ := d.GetIPByAddress(ctx, "1.2.3.4")
|
||||
_ = o.SelfCheckResult(ctx, "validator-1", ip.ID, true, "ok")
|
||||
ip, _ = d.GetIP(ctx, ip.ID)
|
||||
|
||||
_ = o.RecordCheck(ctx, db.Check{
|
||||
IPID: ip.ID, IPAddress: ip.IPAddress, AttemptNumber: ip.AttemptNumber,
|
||||
ValidatorID: "validator-1", Source: db.SourceEgress, CheckType: "https",
|
||||
Target: "https://example.test", Success: true, CheckedAt: db.Now(),
|
||||
})
|
||||
_ = o.MarkEgressComplete(ctx, ip.ID)
|
||||
|
||||
// Shrink the inbound check config to a single TCP port, no ICMP — an
|
||||
// admin API change made between assignment and aggregation.
|
||||
if err := d.SetInboundChecks(ctx, []int{22}, false); err != nil {
|
||||
t.Fatalf("set inbound checks: %v", err)
|
||||
}
|
||||
|
||||
// Report only the one now-expected inbound check.
|
||||
_ = o.RecordCheck(ctx, db.Check{
|
||||
IPID: ip.ID, IPAddress: ip.IPAddress, AttemptNumber: ip.AttemptNumber,
|
||||
Source: db.InboundSource(1), CheckType: "tcp-22", Target: ip.IPAddress, Success: true, CheckedAt: db.Now(),
|
||||
})
|
||||
_ = o.MarkSiteComplete(ctx, ip.ID, 1)
|
||||
|
||||
o.Tick(ctx)
|
||||
ip, _ = d.GetIP(ctx, ip.ID)
|
||||
if ip.State != db.IPDone {
|
||||
t.Fatalf("expected done once the (shrunk) inbound config was fully reported, got %s", ip.State)
|
||||
}
|
||||
if ip.OverallResult != db.ResultPass {
|
||||
t.Fatalf("expected pass, got %s", ip.OverallResult)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user