Enable SSH and TLS handshake on prober for TCP22 and TCP443 ports

This commit is contained in:
ayurishchev committed 2026-08-26 23:52:31 +03:00
1 parent af3453f19f
commit 550ce3fec4
11 files changed
+308 -20

No files matched your search

+5
View File
@@ -531,6 +531,11 @@ func (o *Orchestrator) expectedCheckCount(ctx context.Context) (int, error) {
if inbound.ICMP {
inboundPerSite++
}
for _, p := range inbound.Ports {
if p == 443 || p == 22 {
inboundPerSite++
}
}
return egress + inboundPerSite*len(sites), nil
}
+113 -11
View File
@@ -127,7 +127,7 @@ func TestHappyPath(t *testing.T) {
// 4. inbound results from all 3 sites
for site := 1; site <= 3; site++ {
for _, ct := range []string{"tcp-22", "tcp-80", "icmp"} {
for _, ct := range []string{"tcp-22", "ssh", "tcp-80", "icmp"} {
if err := o.RecordCheck(ctx, db.Check{
IPID: ip.ID, IPAddress: ip.IPAddress, AttemptNumber: ip.AttemptNumber,
Source: db.InboundSource(site), CheckType: ct, Target: ip.IPAddress,
@@ -558,7 +558,7 @@ func TestInboundChecksPartialSites(t *testing.T) {
t.Fatalf("expected still checking (site-1 pending), got %s", ip.State)
}
for _, ct := range []string{"tcp-22", "tcp-80", "icmp"} {
for _, ct := range []string{"tcp-22", "ssh", "tcp-80", "icmp"} {
_ = o.RecordCheck(ctx, db.Check{
IPID: ip.ID, IPAddress: ip.IPAddress, AttemptNumber: ip.AttemptNumber,
Source: db.InboundSource(1), CheckType: ct, Target: ip.IPAddress, Success: true, CheckedAt: db.Now(),
@@ -585,7 +585,7 @@ func TestExpectedCheckCountReflectsInboundChecksConfigChange(t *testing.T) {
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).
// (4 inbound checks expected per site: tcp-22, ssh, tcp-80, icmp).
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"})
@@ -603,16 +603,19 @@ func TestExpectedCheckCountReflectsInboundChecksConfigChange(t *testing.T) {
_ = 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.
// admin API change made between assignment and aggregation. Port 22
// still auto-triggers the extra "ssh" check (see expectedCheckCount).
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(),
})
// Report only the two now-expected inbound checks.
for _, ct := range []string{"tcp-22", "ssh"} {
_ = o.RecordCheck(ctx, db.Check{
IPID: ip.ID, IPAddress: ip.IPAddress, AttemptNumber: ip.AttemptNumber,
Source: db.InboundSource(1), CheckType: ct, Target: ip.IPAddress, Success: true, CheckedAt: db.Now(),
})
}
_ = o.MarkSiteComplete(ctx, ip.ID, 1)
o.Tick(ctx)
@@ -652,7 +655,7 @@ func TestFourSitesAllMustReportBeforeAggregation(t *testing.T) {
_ = o.MarkEgressComplete(ctx, ip.ID)
for _, site := range []int{1, 2, 3} {
for _, ct := range []string{"tcp-22", "tcp-80", "icmp"} {
for _, ct := range []string{"tcp-22", "ssh", "tcp-80", "icmp"} {
_ = o.RecordCheck(ctx, db.Check{
IPID: ip.ID, IPAddress: ip.IPAddress, AttemptNumber: ip.AttemptNumber,
Source: db.InboundSource(site), CheckType: ct, Target: ip.IPAddress, Success: true, CheckedAt: db.Now(),
@@ -669,7 +672,7 @@ func TestFourSitesAllMustReportBeforeAggregation(t *testing.T) {
t.Fatalf("expected still checking (site-4 pending), got %s", ip.State)
}
for _, ct := range []string{"tcp-22", "tcp-80", "icmp"} {
for _, ct := range []string{"tcp-22", "ssh", "tcp-80", "icmp"} {
_ = o.RecordCheck(ctx, db.Check{
IPID: ip.ID, IPAddress: ip.IPAddress, AttemptNumber: ip.AttemptNumber,
Source: db.InboundSource(4), CheckType: ct, Target: ip.IPAddress, Success: true, CheckedAt: db.Now(),
@@ -686,3 +689,102 @@ func TestFourSitesAllMustReportBeforeAggregation(t *testing.T) {
t.Fatalf("expected pass, got %s", ip.OverallResult)
}
}
// TestExpectedCheckCountIncludesTLSAndSSHForPorts443And22 confirms
// expectedCheckCount counts the auto-triggered tls-443/ssh checks (in
// addition to the base tcp-443/tcp-22) once those ports are configured —
// reporting exactly that full set must be enough to aggregate as pass.
func TestExpectedCheckCountIncludesTLSAndSSHForPorts443And22(t *testing.T) {
ctx := context.Background()
sites := []config.SiteConfig{{SiteID: "site-1", Index: 1}}
o, d, mock := newTestOrchestratorWithSites(t, 180, sites)
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)
if err := d.SetInboundChecks(ctx, []int{22, 443}, false); err != nil {
t.Fatalf("set inbound checks: %v", err)
}
for _, ct := range []string{"tcp-22", "ssh", "tcp-443", "tls-443"} {
_ = o.RecordCheck(ctx, db.Check{
IPID: ip.ID, IPAddress: ip.IPAddress, AttemptNumber: ip.AttemptNumber,
Source: db.InboundSource(1), CheckType: ct, 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 tcp+tls+ssh all reported, got %s", ip.State)
}
if ip.OverallResult != db.ResultPass {
t.Fatalf("expected pass, got %s", ip.OverallResult)
}
}
// TestAggregationWaitsForTLSAndSSHResults confirms that reporting only the
// base tcp-22/tcp-443 checks (without the auto-triggered ssh/tls-443
// checks) is not enough to aggregate as pass — expectedCheckCount must
// actually have grown, not just failed to break.
func TestAggregationWaitsForTLSAndSSHResults(t *testing.T) {
ctx := context.Background()
sites := []config.SiteConfig{{SiteID: "site-1", Index: 1}}
o, d, mock := newTestOrchestratorWithSites(t, 180, sites)
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)
if err := d.SetInboundChecks(ctx, []int{22, 443}, false); err != nil {
t.Fatalf("set inbound checks: %v", err)
}
// Only the base TCP checks report — ssh/tls-443 never arrive, but the
// site still (incorrectly, from the operator's point of view) claims
// completion. Force the checking window to have elapsed so aggregation
// runs anyway, same as TestPartialResult.
for _, ct := range []string{"tcp-22", "tcp-443"} {
_ = o.RecordCheck(ctx, db.Check{
IPID: ip.ID, IPAddress: ip.IPAddress, AttemptNumber: ip.AttemptNumber,
Source: db.InboundSource(1), CheckType: ct, Target: ip.IPAddress, Success: true, CheckedAt: db.Now(),
})
}
_ = o.MarkSiteComplete(ctx, ip.ID, 1)
o.Cfg.CheckingWindowSeconds = 0
time.Sleep(5 * time.Millisecond)
o.Tick(ctx)
ip, _ = d.GetIP(ctx, ip.ID)
if ip.State != db.IPDone {
t.Fatalf("expected done, got %s", ip.State)
}
if ip.OverallResult != db.ResultPartial {
t.Fatalf("expected partial (missing ssh/tls-443 counted against it), got %s", ip.OverallResult)
}
}