Documentation
¶
Overview ¶
Package store provides a pure-Go SQLite-backed persistence layer.
It uses modernc.org/sqlite which is a CGO-free SQLite implementation, so the whole application can be cross-compiled to a single static binary for Windows/Linux/macOS without a C toolchain.
Index ¶
- Variables
- func NormalizeRegistryHost(host string) string
- func ValidSection(key string) bool
- type AlertEvent
- type AlertRule
- type AuditEntry
- type Host
- type LDAPConfig
- type ParseRule
- type Registry
- type RegistryAuth
- type SMTPConfig
- type Store
- func (s *Store) AckAlertEvent(ctx context.Context, id int64) error
- func (s *Store) Audit(ctx context.Context, e AuditEntry) error
- func (s *Store) AuthByID(ctx context.Context, id int64) (*RegistryAuth, error)
- func (s *Store) AuthForHost(ctx context.Context, host string) (*RegistryAuth, error)
- func (s *Store) Close() error
- func (s *Store) CountAdmins(ctx context.Context) (int, error)
- func (s *Store) CountUnacknowledged(ctx context.Context) (int, error)
- func (s *Store) CountUsers(ctx context.Context) (int, error)
- func (s *Store) CreateAlertRule(ctx context.Context, r *AlertRule) (int64, error)
- func (s *Store) CreateHost(ctx context.Context, h *Host) (int64, error)
- func (s *Store) CreateParseRule(ctx context.Context, name, pattern string) (int64, error)
- func (s *Store) CreateRegistry(ctx context.Context, name, address, username, secret string) (int64, error)
- func (s *Store) CreateUser(ctx context.Context, u *User) (int64, error)
- func (s *Store) CreateWebhook(ctx context.Context, w *Webhook) (int64, error)
- func (s *Store) DeleteAlertRule(ctx context.Context, id int64) error
- func (s *Store) DeleteHost(ctx context.Context, id int64) error
- func (s *Store) DeleteParseRule(ctx context.Context, id int64) error
- func (s *Store) DeleteRegistry(ctx context.Context, id int64) error
- func (s *Store) DeleteUser(ctx context.Context, id int64) error
- func (s *Store) DeleteWebhook(ctx context.Context, id int64) error
- func (s *Store) DisabledSections(ctx context.Context) ([]string, error)
- func (s *Store) EnsureLocalHost(ctx context.Context) error
- func (s *Store) GetLDAP(ctx context.Context) (LDAPConfig, error)
- func (s *Store) GetSMTP(ctx context.Context) (SMTPConfig, error)
- func (s *Store) HostByID(ctx context.Context, id int64) (*Host, error)
- func (s *Store) InsertAlertEvent(ctx context.Context, e *AlertEvent) (int64, error)
- func (s *Store) ListAlertEvents(ctx context.Context, limit int) ([]AlertEvent, error)
- func (s *Store) ListAlertRules(ctx context.Context) ([]AlertRule, error)
- func (s *Store) ListHosts(ctx context.Context) ([]Host, error)
- func (s *Store) ListParseRules(ctx context.Context) ([]ParseRule, error)
- func (s *Store) ListRegistries(ctx context.Context) ([]Registry, error)
- func (s *Store) ListUsers(ctx context.Context) ([]User, error)
- func (s *Store) ListWebhooks(ctx context.Context) ([]Webhook, error)
- func (s *Store) LocalhostNo2FA(ctx context.Context) (bool, error)
- func (s *Store) Ping(ctx context.Context) error
- func (s *Store) RecentAudit(ctx context.Context, limit int, before int64) ([]AuditEntry, error)
- func (s *Store) SetAlertRuleEnabled(ctx context.Context, id int64, enabled bool) error
- func (s *Store) SetCipher(c *crypto.Cipher)
- func (s *Store) SetDisabledSections(ctx context.Context, keys []string) error
- func (s *Store) SetHostAlertEmail(ctx context.Context, id int64, email string) error
- func (s *Store) SetHostKey(ctx context.Context, id int64, key string) error
- func (s *Store) SetLDAP(ctx context.Context, c LDAPConfig) error
- func (s *Store) SetLocalhostNo2FA(ctx context.Context, on bool) error
- func (s *Store) SetSMTP(ctx context.Context, c SMTPConfig) error
- func (s *Store) SetSetting(ctx context.Context, key, value string) error
- func (s *Store) SetTOTP(ctx context.Context, userID int64, secret string, enabled bool) error
- func (s *Store) SetUserPrefs(ctx context.Context, userID int64, prefs string) error
- func (s *Store) Setting(ctx context.Context, key string) (string, error)
- func (s *Store) TouchLogin(ctx context.Context, userID int64) error
- func (s *Store) UpdateAlertRule(ctx context.Context, id int64, r *AlertRule) error
- func (s *Store) UpdatePassword(ctx context.Context, userID int64, hash string) error
- func (s *Store) UpdateUserAccess(ctx context.Context, id int64, role string, readOnly bool, sections []string) error
- func (s *Store) UserByID(ctx context.Context, id int64) (*User, error)
- func (s *Store) UserByUsername(ctx context.Context, username string) (*User, error)
- func (s *Store) UserPrefs(ctx context.Context, userID int64) (string, error)
- func (s *Store) WebhookByID(ctx context.Context, id int64) (*Webhook, error)
- type User
- type Webhook
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = errors.New("store: not found")
ErrNotFound is returned when a lookup yields no row.
var Sections = []string{
"dashboard", "containers", "images", "volumes", "networks", "topology",
"logs", "events", "alerts", "hosts", "registries", "audit",
}
Sections are the access-control units, matching the app's menu. A user's permissions and the global feature flags are both expressed as sets of these.
Functions ¶
func NormalizeRegistryHost ¶
NormalizeRegistryHost maps the various Docker Hub aliases to a single key so a stored "docker.io" credential matches refs like "nginx" or "user/app".
func ValidSection ¶
ValidSection reports whether key is a known section.
Types ¶
type AlertEvent ¶
type AlertEvent struct {
ID int64 `json:"id"`
RuleID int64 `json:"ruleId"`
RuleName string `json:"ruleName"`
Type string `json:"type"`
Severity string `json:"severity"`
HostID int64 `json:"hostId"`
HostName string `json:"hostName"`
ContainerID string `json:"containerId"`
ContainerName string `json:"containerName"`
Message string `json:"message"`
Value *float64 `json:"value"`
Acknowledged bool `json:"acknowledged"`
CreatedAt time.Time `json:"createdAt"`
}
AlertEvent is a fired alert recorded for the in-app feed.
type AlertRule ¶
type AlertRule struct {
ID int64 `json:"id"`
Name string `json:"name"`
Enabled bool `json:"enabled"`
Type string `json:"type"` // state | resource | log | restart
Target string `json:"target"` // container name substring; ” or '*' = all
Config string `json:"config"` // raw JSON, interpreted by the engine
Severity string `json:"severity"` // info | warning | critical
WebhookID *int64 `json:"webhookId"`
Email bool `json:"email"` // also send to the configured SMTP recipient
CooldownSec int `json:"cooldownSec"`
CreatedAt time.Time `json:"createdAt"`
}
AlertRule defines when an alert fires and where it goes.
type AuditEntry ¶
type AuditEntry struct {
ID int64 `json:"id"`
UserID int64 `json:"userId"`
Username string `json:"username"`
Action string `json:"action"`
Target string `json:"target"`
Detail string `json:"detail"`
IP string `json:"ip"`
CreatedAt time.Time `json:"createdAt"`
}
AuditEntry is a single recorded security-relevant action.
type Host ¶
type Host struct {
ID int64
Name string
Kind string
Address string
TLSCA string
TLSCert string
TLSKey string
HostKey string // pinned SSH host public key (authorized_keys line); ssh hosts only
AlertEmail string // per-host alert recipient override (falls back to global SMTP To)
CreatedAt time.Time
}
Host describes a Docker engine endpoint the app can connect to.
Kind is one of:
- "local": the local daemon (unix socket / windows named pipe)
- "tcp": a remote daemon over TCP, optionally TLS-secured
- "ssh": a remote daemon reached through an SSH tunnel
type LDAPConfig ¶
type LDAPConfig struct {
Enabled bool `json:"enabled"`
URL string `json:"url"` // ldap://host:389 or ldaps://host:636
StartTLS bool `json:"startTls"` // upgrade a plain connection to TLS
BindDN string `json:"bindDn"` // service account used to search for users
BindPassword string `json:"bindPassword"`
UserBaseDN string `json:"userBaseDn"`
UserFilter string `json:"userFilter"` // e.g. (uid=%s) or (sAMAccountName=%s)
AdminGroupDN string `json:"adminGroupDn"` // optional: members are provisioned as admins
}
LDAPConfig configures optional LDAP / Active Directory authentication. The bind password is encrypted at rest (like the SMTP one) and never returned.
func (LDAPConfig) Configured ¶
func (c LDAPConfig) Configured() bool
Configured reports whether enough is set to attempt LDAP authentication.
type ParseRule ¶
type ParseRule struct {
ID int64 `json:"id"`
Name string `json:"name"`
Pattern string `json:"pattern"`
CreatedAt time.Time `json:"createdAt"`
}
ParseRule is a saved log-parsing rule: a regex with named capture groups that the Logs view applies to extract structured fields (columns) from log lines.
type Registry ¶
Registry holds credentials for a container image registry. The secret (password/token) is encrypted at rest and never returned in listings.
type RegistryAuth ¶
RegistryAuth is the decrypted credential pair used to authenticate to a registry for pull/push. It is only assembled server-side, never serialised.
type SMTPConfig ¶
type SMTPConfig struct {
Host string `json:"host"`
Port int `json:"port"`
Username string `json:"username"`
Password string `json:"password"`
From string `json:"from"`
To string `json:"to"` // comma-separated recipients
TLS bool `json:"tls"` // implicit TLS (e.g. port 465); otherwise STARTTLS if offered
}
SMTPConfig is the mail server used for the email alert channel. The password is stored encrypted at rest (the persisted JSON holds ciphertext); it is decrypted on read and never returned to API clients.
func (SMTPConfig) Configured ¶
func (c SMTPConfig) Configured() bool
Configured reports whether enough is set to attempt sending.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store wraps the database handle and exposes typed queries.
func Open ¶
Open opens (creating if necessary) the SQLite database at path and runs all pending migrations. A path of ":memory:" yields an ephemeral DB.
func (*Store) Audit ¶
func (s *Store) Audit(ctx context.Context, e AuditEntry) error
Audit appends an entry to the audit log. Failures are returned but callers generally log-and-continue: an audit write must never block a user action.
func (*Store) AuthForHost ¶
AuthForHost returns the decrypted credentials whose address matches the registry host of an image reference, or ErrNotFound if none is configured.
func (*Store) CountAdmins ¶
CountAdmins returns how many admin accounts exist (to guard the last admin).
func (*Store) CountUnacknowledged ¶
func (*Store) CountUsers ¶
CountUsers returns the number of accounts; used to detect first-run setup.
func (*Store) CreateAlertRule ¶
func (*Store) CreateHost ¶
CreateHost inserts a new host and returns its ID.
func (*Store) CreateParseRule ¶
func (*Store) CreateRegistry ¶
func (s *Store) CreateRegistry(ctx context.Context, name, address, username, secret string) (int64, error)
CreateRegistry stores a registry, encrypting the secret. The address is normalised so it matches image references later (see NormalizeRegistryHost).
func (*Store) CreateUser ¶
CreateUser inserts a new account and returns its assigned ID.
func (*Store) CreateWebhook ¶
func (*Store) DeleteAlertRule ¶
func (*Store) DeleteHost ¶
DeleteHost removes a host by ID.
func (*Store) DeleteParseRule ¶
func (*Store) DeleteRegistry ¶
DeleteRegistry removes a registry by ID.
func (*Store) DeleteUser ¶
DeleteUser removes an account.
func (*Store) DisabledSections ¶
DisabledSections returns the sections an admin has turned off app-wide.
func (*Store) EnsureLocalHost ¶
EnsureLocalHost guarantees a "local" host row exists so the app is usable immediately on first run without manual host configuration.
func (*Store) GetLDAP ¶
func (s *Store) GetLDAP(ctx context.Context) (LDAPConfig, error)
GetLDAP loads the LDAP config, decrypting the bind password.
func (*Store) GetSMTP ¶
func (s *Store) GetSMTP(ctx context.Context) (SMTPConfig, error)
GetSMTP loads the SMTP config, decrypting the password.
func (*Store) InsertAlertEvent ¶
func (*Store) ListAlertEvents ¶
func (*Store) ListAlertRules ¶
func (*Store) ListParseRules ¶
func (*Store) ListRegistries ¶
ListRegistries returns the configured registries without their secrets.
func (*Store) ListUsers ¶
ListUsers returns all accounts (without secrets) for the admin user manager.
func (*Store) LocalhostNo2FA ¶
LocalhostNo2FA reports whether password-only login is allowed from loopback.
func (*Store) Ping ¶ added in v1.1.0
Ping checks that the database is reachable (used by the health endpoint).
func (*Store) RecentAudit ¶
RecentAudit returns the most recent audit entries, newest first. When before is > 0, only entries older than that id are returned (cursor pagination).
func (*Store) SetAlertRuleEnabled ¶
func (*Store) SetCipher ¶
SetCipher installs the cipher used to encrypt secrets at rest (registry credentials). It is wired up once at startup, after the key is loaded.
func (*Store) SetDisabledSections ¶
SetDisabledSections persists the app-wide disabled sections.
func (*Store) SetHostAlertEmail ¶
SetHostAlertEmail sets a host's per-host alert recipient override.
func (*Store) SetHostKey ¶
SetHostKey pins (or clears, when key is "") the trusted SSH host public key for a host. Subsequent connections verify the daemon's key against it.
func (*Store) SetLDAP ¶
func (s *Store) SetLDAP(ctx context.Context, c LDAPConfig) error
SetLDAP persists the config, encrypting the bind password. An empty bind password preserves the previously stored one.
func (*Store) SetLocalhostNo2FA ¶
SetLocalhostNo2FA toggles the localhost 2FA exemption.
func (*Store) SetSMTP ¶
func (s *Store) SetSMTP(ctx context.Context, c SMTPConfig) error
SetSMTP persists the SMTP config, encrypting the password. An empty password preserves the previously stored one (so the UI need not resend the secret).
func (*Store) SetSetting ¶
SetSetting upserts a key/value pair.
func (*Store) SetTOTP ¶
SetTOTP stores the secret and enabled flag for a user (enrollment / disable).
func (*Store) SetUserPrefs ¶ added in v1.1.0
SetUserPrefs replaces a user's UI preferences JSON blob.
func (*Store) Setting ¶
Setting reads a single key from the settings table. Returns ("", nil) when the key is absent so callers can treat "missing" as "use default".
func (*Store) TouchLogin ¶
TouchLogin records the timestamp of a successful login.
func (*Store) UpdateAlertRule ¶
UpdateAlertRule replaces a rule's mutable fields (enabled is managed separately via SetAlertRuleEnabled).
func (*Store) UpdatePassword ¶
UpdatePassword replaces the stored Argon2id hash for a user.
func (*Store) UpdateUserAccess ¶
func (s *Store) UpdateUserAccess(ctx context.Context, id int64, role string, readOnly bool, sections []string) error
UpdateUserAccess changes a user's role, read-only flag and allowed sections.
func (*Store) UserByUsername ¶
UserByUsername looks up a user by their unique username.
type User ¶
type User struct {
ID int64
Username string
PasswordHash string
Role string
AuthSource string // "local" (password stored here) or "ldap" (verified externally)
ReadOnly bool
Sections []string
TOTPSecret string
TOTPEnabled bool
CreatedAt time.Time
LastLoginAt time.Time
}
User is an application account. PasswordHash is an Argon2id encoded hash. TOTPSecret is the base32 shared secret; it is only meaningful once TOTPEnabled is true (i.e. the user confirmed enrollment with a valid code).
Role is "admin" (full access incl. user/feature management) or "user". For "user" accounts, Sections lists the menu sections they may access and ReadOnly blocks mutating actions. Admins ignore both.
type Webhook ¶
type Webhook struct {
ID int64 `json:"id"`
Name string `json:"name"`
URL string `json:"url"`
Method string `json:"method"`
Headers map[string]string `json:"headers"`
BodyTemplate string `json:"bodyTemplate"`
CreatedAt time.Time `json:"createdAt"`
}
Webhook is a generic HTTP destination an alert rule can fire to. body_template is a Go text/template rendered against the alert event.