65 lines
2.0 KiB
Go
65 lines
2.0 KiB
Go
package db
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"fmt"
|
||
|
|
)
|
||
|
|
|
||
|
|
// GetInboundChecks returns the singleton inbound-checks settings row.
|
||
|
|
// BootstrapFromConfig guarantees it exists before any other code path can
|
||
|
|
// observe it, so sql.ErrNoRows here would indicate a bootstrap bug, not a
|
||
|
|
// normal condition.
|
||
|
|
func (d *DB) GetInboundChecks(ctx context.Context) (InboundChecksSettings, error) {
|
||
|
|
var s InboundChecksSettings
|
||
|
|
var portsJSON, createdAt, updatedAt string
|
||
|
|
err := d.QueryRowContext(ctx, `
|
||
|
|
SELECT ports, icmp, created_at, updated_at FROM inbound_checks_settings WHERE id=1
|
||
|
|
`).Scan(&portsJSON, &s.ICMP, &createdAt, &updatedAt)
|
||
|
|
if err != nil {
|
||
|
|
return InboundChecksSettings{}, err
|
||
|
|
}
|
||
|
|
if err := json.Unmarshal([]byte(portsJSON), &s.Ports); err != nil {
|
||
|
|
return InboundChecksSettings{}, fmt.Errorf("decode inbound check ports: %w", err)
|
||
|
|
}
|
||
|
|
if s.Ports == nil {
|
||
|
|
s.Ports = []int{}
|
||
|
|
}
|
||
|
|
if s.CreatedAt, err = dbToTime(createdAt); err != nil {
|
||
|
|
return InboundChecksSettings{}, err
|
||
|
|
}
|
||
|
|
if s.UpdatedAt, err = dbToTime(updatedAt); err != nil {
|
||
|
|
return InboundChecksSettings{}, err
|
||
|
|
}
|
||
|
|
return s, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// SetInboundChecks persists a new prober check configuration. Validation is
|
||
|
|
// purely local (port range, no duplicates) — unlike fip_settle_seconds,
|
||
|
|
// there's no cross-field dependency on other orchestrator config, so this
|
||
|
|
// is called directly by the HTTP handler without going through
|
||
|
|
// orchestrator.Orchestrator.
|
||
|
|
func (d *DB) SetInboundChecks(ctx context.Context, ports []int, icmp bool) error {
|
||
|
|
seen := make(map[int]bool, len(ports))
|
||
|
|
for _, p := range ports {
|
||
|
|
if p < 1 || p > 65535 {
|
||
|
|
return fmt.Errorf("port %d out of range 1..65535: %w", p, ErrValidation)
|
||
|
|
}
|
||
|
|
if seen[p] {
|
||
|
|
return fmt.Errorf("duplicate port %d: %w", p, ErrValidation)
|
||
|
|
}
|
||
|
|
seen[p] = true
|
||
|
|
}
|
||
|
|
if ports == nil {
|
||
|
|
ports = []int{}
|
||
|
|
}
|
||
|
|
payload, err := json.Marshal(ports)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
now := timeToDB(Now())
|
||
|
|
_, err = d.ExecContext(ctx, `
|
||
|
|
UPDATE inbound_checks_settings SET ports=?, icmp=?, updated_at=? WHERE id=1
|
||
|
|
`, string(payload), icmp, now)
|
||
|
|
return err
|
||
|
|
}
|