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 Project
- 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) CreateProject(ctx context.Context, p *Project) (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) DeleteProject(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) ListProjects(ctx context.Context) ([]Project, 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) ProjectByID(ctx context.Context, id int64) (*Project, 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) SetHostDisabled(ctx context.Context, id int64, disabled bool) 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) TouchProject(ctx context.Context, id 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) UpdateProjectName(ctx context.Context, id int64, name 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 ErrDuplicate = errors.New("store: duplicate")
ErrDuplicate is returned when an insert violates a UNIQUE constraint (e.g. a project slug that already exists).
var ErrNotFound = errors.New("store: not found")
ErrNotFound is returned when a lookup yields no row.
var Sections = []string{
"dashboard", "containers", "projects", "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)
Disabled bool // when true the monitor ignores this host (no events/stats)
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 Project ¶ added in v1.2.0
type Project struct {
ID int64
Name string
Slug string
ComposeFile string
CreatedBy string
CreatedAt time.Time
UpdatedAt time.Time
}
Project is a managed compose project: a folder under the data dir holding a compose file plus sidecar config/script files, deployed via the docker compose CLI. The folder is keyed by the numeric ID (derived at runtime, not stored) so renames never move files. Slug is the compose project name.
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) CreateProject ¶ added in v1.2.0
CreateProject inserts a project and returns its ID. A slug collision yields ErrDuplicate.
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) DeleteProject ¶ added in v1.2.0
DeleteProject removes the project row (the caller removes the folder).
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) ListProjects ¶ added in v1.2.0
ListProjects returns all projects ordered by name.
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) ProjectByID ¶ added in v1.2.0
ProjectByID looks up a project by primary key.
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) SetHostDisabled ¶ added in v1.2.0
SetHostDisabled toggles whether the monitor ignores a host.
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) TouchProject ¶ added in v1.2.0
TouchProject bumps updated_at (called when a file changes).
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) UpdateProjectName ¶ added in v1.2.0
UpdateProjectName changes the display name (the slug stays immutable).
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.