tangled
alpha
login
or
join now
atscan.net
/
atscand
1
fork
atom
wip
1
fork
atom
overview
issues
pulls
pipelines
update
tree.fail
4 months ago
8ebbd6f3
f608ec8b
+55
-39
2 changed files
expand all
collapse all
unified
split
internal
api
handlers.go
storage
postgres.go
+3
internal/api/handlers.go
···
276
if pds.IPInfo.ASN > 0 {
277
response["asn"] = pds.IPInfo.ASN
278
}
0
0
0
279
}
280
281
return response
···
276
if pds.IPInfo.ASN > 0 {
277
response["asn"] = pds.IPInfo.ASN
278
}
279
+
if pds.IPInfo.IsDatacenter {
280
+
response["is_datacenter"] = pds.IPInfo.IsDatacenter
281
+
}
282
}
283
284
return response
+52
-39
internal/storage/postgres.go
···
93
CREATE INDEX IF NOT EXISTS idx_endpoints_type ON endpoints(endpoint_type);
94
CREATE INDEX IF NOT EXISTS idx_endpoints_ip ON endpoints(ip);
95
CREATE INDEX IF NOT EXISTS idx_endpoints_server_did ON endpoints(server_did);
0
96
97
-- IP infos table (IP as PRIMARY KEY)
98
CREATE TABLE IF NOT EXISTS ip_infos (
···
670
671
func (p *PostgresDB) GetPDSDetail(ctx context.Context, endpoint string) (*PDSDetail, error) {
672
query := `
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
673
SELECT
674
-
e.id, e.endpoint, e.server_did, e.discovered_at, e.last_checked, e.status, e.ip,
0
0
0
0
0
0
675
latest.user_count,
676
latest.response_time,
677
latest.version,
···
679
latest.scanned_at,
680
i.city, i.country, i.country_code, i.asn, i.asn_org,
681
i.is_datacenter, i.is_vpn, i.latitude, i.longitude,
682
-
i.raw_data
683
-
FROM endpoints e
0
0
0
684
LEFT JOIN LATERAL (
685
SELECT scan_data, response_time, version, scanned_at, user_count
686
FROM endpoint_scans
687
-
WHERE endpoint_id = e.id
688
ORDER BY scanned_at DESC
689
LIMIT 1
690
) latest ON true
691
-
LEFT JOIN ip_infos i ON e.ip = i.ip
692
-
WHERE e.endpoint = $1 AND e.endpoint_type = 'pds'
693
`
694
695
detail := &PDSDetail{}
···
703
var serverInfoJSON []byte
704
var scannedAt sql.NullTime
705
var rawDataJSON []byte
0
0
706
707
err := p.db.QueryRowContext(ctx, query, endpoint).Scan(
708
&detail.ID, &detail.Endpoint, &serverDID, &detail.DiscoveredAt, &detail.LastChecked, &detail.Status, &ip,
···
710
&city, &country, &countryCode, &asn, &asnOrg,
711
&isDatacenter, &isVPN, &lat, &lon,
712
&rawDataJSON,
0
0
713
)
714
if err != nil {
715
return nil, err
···
719
detail.IP = ip.String
720
}
721
722
-
// NEW: Get aliases if this endpoint has a server_did
723
-
if serverDID.Valid && serverDID.String != "" {
724
-
aliasQuery := `
725
-
SELECT endpoint, discovered_at
726
-
FROM endpoints
727
-
WHERE server_did = $1
728
-
AND endpoint_type = 'pds'
729
-
AND endpoint != $2
730
-
ORDER BY discovered_at ASC
731
-
`
732
733
-
rows, err := p.db.QueryContext(ctx, aliasQuery, serverDID.String, endpoint)
734
-
if err == nil {
735
-
defer rows.Close()
736
-
737
-
var aliases []string
738
-
var primaryDiscoveredAt time.Time
739
-
740
-
for rows.Next() {
741
-
var alias string
742
-
var discoveredAt time.Time
743
-
if err := rows.Scan(&alias, &discoveredAt); err == nil {
744
-
aliases = append(aliases, alias)
745
-
if primaryDiscoveredAt.IsZero() || discoveredAt.Before(detail.DiscoveredAt) {
746
-
primaryDiscoveredAt = discoveredAt
747
-
}
748
-
}
749
-
}
750
-
751
-
detail.Aliases = aliases
752
-
detail.IsPrimary = detail.DiscoveredAt.Equal(primaryDiscoveredAt) ||
753
-
detail.DiscoveredAt.Before(primaryDiscoveredAt)
754
-
}
755
} else {
756
-
// No server_did means it's a unique server
757
detail.IsPrimary = true
758
}
759
···
93
CREATE INDEX IF NOT EXISTS idx_endpoints_type ON endpoints(endpoint_type);
94
CREATE INDEX IF NOT EXISTS idx_endpoints_ip ON endpoints(ip);
95
CREATE INDEX IF NOT EXISTS idx_endpoints_server_did ON endpoints(server_did);
96
+
CREATE INDEX IF NOT EXISTS idx_endpoints_server_did_type_discovered ON endpoints(server_did, endpoint_type, discovered_at);
97
98
-- IP infos table (IP as PRIMARY KEY)
99
CREATE TABLE IF NOT EXISTS ip_infos (
···
671
672
func (p *PostgresDB) GetPDSDetail(ctx context.Context, endpoint string) (*PDSDetail, error) {
673
query := `
674
+
WITH target_endpoint AS (
675
+
SELECT
676
+
e.id,
677
+
e.endpoint,
678
+
e.server_did,
679
+
e.discovered_at,
680
+
e.last_checked,
681
+
e.status,
682
+
e.ip
683
+
FROM endpoints e
684
+
WHERE e.endpoint = $1 AND e.endpoint_type = 'pds'
685
+
),
686
+
aliases_agg AS (
687
+
SELECT
688
+
te.server_did,
689
+
array_agg(e.endpoint ORDER BY e.discovered_at) FILTER (WHERE e.endpoint != te.endpoint) as aliases,
690
+
MIN(e.discovered_at) as first_discovered_at
691
+
FROM target_endpoint te
692
+
LEFT JOIN endpoints e ON te.server_did = e.server_did
693
+
AND e.endpoint_type = 'pds'
694
+
AND te.server_did IS NOT NULL
695
+
GROUP BY te.server_did
696
+
)
697
SELECT
698
+
te.id,
699
+
te.endpoint,
700
+
te.server_did,
701
+
te.discovered_at,
702
+
te.last_checked,
703
+
te.status,
704
+
te.ip,
705
latest.user_count,
706
latest.response_time,
707
latest.version,
···
709
latest.scanned_at,
710
i.city, i.country, i.country_code, i.asn, i.asn_org,
711
i.is_datacenter, i.is_vpn, i.latitude, i.longitude,
712
+
i.raw_data,
713
+
COALESCE(aa.aliases, ARRAY[]::text[]) as aliases,
714
+
aa.first_discovered_at
715
+
FROM target_endpoint te
716
+
LEFT JOIN aliases_agg aa ON te.server_did = aa.server_did
717
LEFT JOIN LATERAL (
718
SELECT scan_data, response_time, version, scanned_at, user_count
719
FROM endpoint_scans
720
+
WHERE endpoint_id = te.id
721
ORDER BY scanned_at DESC
722
LIMIT 1
723
) latest ON true
724
+
LEFT JOIN ip_infos i ON te.ip = i.ip
0
725
`
726
727
detail := &PDSDetail{}
···
735
var serverInfoJSON []byte
736
var scannedAt sql.NullTime
737
var rawDataJSON []byte
738
+
var aliases []string
739
+
var firstDiscoveredAt sql.NullTime
740
741
err := p.db.QueryRowContext(ctx, query, endpoint).Scan(
742
&detail.ID, &detail.Endpoint, &serverDID, &detail.DiscoveredAt, &detail.LastChecked, &detail.Status, &ip,
···
744
&city, &country, &countryCode, &asn, &asnOrg,
745
&isDatacenter, &isVPN, &lat, &lon,
746
&rawDataJSON,
747
+
pq.Array(&aliases),
748
+
&firstDiscoveredAt,
749
)
750
if err != nil {
751
return nil, err
···
755
detail.IP = ip.String
756
}
757
758
+
if serverDID.Valid {
759
+
detail.ServerDID = serverDID.String
760
+
}
0
0
0
0
0
0
0
761
762
+
// Set aliases and is_primary
763
+
detail.Aliases = aliases
764
+
if serverDID.Valid && serverDID.String != "" && firstDiscoveredAt.Valid {
765
+
// Has server_did - check if this is the first discovered
766
+
detail.IsPrimary = detail.DiscoveredAt.Equal(firstDiscoveredAt.Time) ||
767
+
detail.DiscoveredAt.Before(firstDiscoveredAt.Time)
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
768
} else {
769
+
// No server_did means unique server
770
detail.IsPrimary = true
771
}
772