Documentation
¶
Overview ¶
Package sqlstore persists the durable MDM state in a SQL database.
Design ¶
One Store over database/sql implements the library's durable contracts: storage.Store (enrollments and issued certificates), storage.CredentialStore (the OMA DM session credential per device), and mdm.CommandQueue (the per-device command queue with per-command results). It also keeps a device facts table and an append-only event log the service writes through.
Three dialects are supported: SQLite (the pure-Go modernc.org/sqlite driver, the default and the one the tests exercise everywhere), PostgreSQL and MySQL. A small Dialect abstraction covers the three differences that matter: the parameter placeholder, the upsert clause and the column types. Times are stored as Unix nanoseconds and booleans as 0/1 so every driver round-trips them identically. Certificate DER and JSON blobs are stored verbatim.
OMA DM session state is not persisted here: a session is a short-lived, single-node construct holding engine-internal state, so the reference server keeps it in mdm.MemorySessions. Multi-node session sharing is a later concern (decision record 0014). Durable device facts are captured by the service's hooks and written to the facts table, independent of session lifetime.
References ¶
Index ¶
- Variables
- type Event
- type Facts
- type Kind
- type Options
- type PushChannel
- type Queue
- func (s *Queue) Cancel(ctx context.Context, deviceID string, ids []string, at time.Time) (int, error)
- func (s Queue) Close() error
- func (s Queue) DB() *sql.DB
- func (s *Queue) Deliverable(ctx context.Context, deviceID string, limit int) ([]mdm.QueuedCommand, error)
- func (s *Queue) Enqueue(ctx context.Context, deviceID string, cmd *mdm.Command, at time.Time) (*mdm.QueuedCommand, error)
- func (s *Queue) Get(ctx context.Context, deviceID, commandID string) (*mdm.QueuedCommand, error)
- func (s *Queue) List(ctx context.Context, deviceID string, q mdm.Query, p paging.Page) (paging.Result[mdm.QueuedCommand], error)
- func (s *Queue) MarkSent(ctx context.Context, deviceID string, deliveries []mdm.Delivery) error
- func (s *Queue) Prune(ctx context.Context, before time.Time, limit int) (int, error)
- func (s *Queue) StoreResult(ctx context.Context, deviceID, commandID string, r mdm.Result) error
- type Store
- func (s *Store) AgentWake(ctx context.Context, deviceID, token string) (string, error)
- func (s *Store) Certificate(ctx context.Context, serial string) (*storage.Certificate, error)
- func (s *Store) CertificateByThumbprint(ctx context.Context, thumbprint string) (*storage.Certificate, error)
- func (s Store) Close() error
- func (s *Store) Create(ctx context.Context, e *storage.Enrollment) error
- func (s Store) DB() *sql.DB
- func (s *Store) Events(ctx context.Context, deviceID string, limit int) ([]Event, error)
- func (s *Store) Facts(ctx context.Context, deviceID string) (Facts, error)
- func (s *Store) Get(ctx context.Context, deviceID string) (*storage.Enrollment, error)
- func (s *Store) GetBySerial(ctx context.Context, serial string) (*storage.Enrollment, error)
- func (s *Store) GetByThumbprint(ctx context.Context, thumbprint string) (*storage.Enrollment, error)
- func (s *Store) IssueAgentToken(ctx context.Context, deviceID string) (string, error)
- func (s *Store) List(ctx context.Context, q storage.EnrollmentQuery, p paging.Page) (paging.Result[storage.Enrollment], error)
- func (s *Store) ListByHWDevID(ctx context.Context, hwDevID string) ([]storage.Enrollment, error)
- func (s *Store) ListCertificates(ctx context.Context, q storage.CertificateQuery, p paging.Page) (paging.Result[storage.Certificate], error)
- func (s *Store) LogEvent(ctx context.Context, deviceID, kind string, detail any) error
- func (s *Store) MDMCredential(ctx context.Context, deviceID string) (storage.MDMCredential, error)
- func (s *Store) MarkPushDead(ctx context.Context, serial, uri string) error
- func (s *Store) ObservePush(ctx context.Context, serial string, uri, status *string, at time.Time) error
- func (s *Store) PushChannel(ctx context.Context, serial string) (PushChannel, error)
- func (s *Store) PutCertificate(ctx context.Context, c *storage.Certificate) error
- func (s *Store) PutFacts(ctx context.Context, f Facts) error
- func (s *Store) PutMDMCredential(ctx context.Context, c storage.MDMCredential) error
- func (s *Store) Queue() *Queue
- func (s *Store) Revoke(ctx context.Context, serial string, at time.Time) error
- func (s *Store) SetState(ctx context.Context, serial string, state storage.State, at time.Time) error
- func (s *Store) TouchLastSeen(ctx context.Context, serial string, at time.Time) error
Constants ¶
This section is empty.
Variables ¶
var ( // ErrDialect reports an unknown SQL dialect. ErrDialect = errors.New("sqlstore: unknown dialect") // ErrConfig reports an unusable configuration. ErrConfig = errors.New("sqlstore: invalid configuration") )
Errors returned by this package.
var ErrNotFound = errors.New("sqlstore: not found")
ErrNotFound reports a missing device-facts or event row.
Functions ¶
This section is empty.
Types ¶
type Facts ¶
type Facts struct {
DeviceID string
DevInfo map[string]string
LoginStatus string
SyncType string
DevicePrepSync string
ChannelURI string
UpdatedAt time.Time
}
Facts is the durable device facts the service captures from a session.
type Options ¶
type Options struct {
// Clock stamps server-side times (event log); default real time.
Clock clock.Clock
// MaxOpenConns caps the connection pool; 0 leaves the driver default,
// except SQLite where it is forced to 1 (a file database is not safe for
// concurrent writers).
MaxOpenConns int
}
Options configure Open.
type PushChannel ¶
type PushChannel struct {
Serial string
URI string `json:"-"`
FirstSeen time.Time
ObservedAt time.Time
Dead bool
Status string
}
PushChannel belongs to one enrollment certificate, never just a device ID.
type Queue ¶
type Queue struct {
// contains filtered or unexported fields
}
Queue is the SQL-backed mdm.CommandQueue over the same connection.
func (*Queue) Cancel ¶
func (s *Queue) Cancel(ctx context.Context, deviceID string, ids []string, at time.Time) (int, error)
Cancel implements mdm.CommandQueue.
func (*Queue) Deliverable ¶
func (s *Queue) Deliverable(ctx context.Context, deviceID string, limit int) ([]mdm.QueuedCommand, error)
Deliverable implements mdm.CommandQueue.
func (*Queue) Enqueue ¶
func (s *Queue) Enqueue(ctx context.Context, deviceID string, cmd *mdm.Command, at time.Time) (*mdm.QueuedCommand, error)
Enqueue implements mdm.CommandQueue.
func (*Queue) List ¶
func (s *Queue) List(ctx context.Context, deviceID string, q mdm.Query, p paging.Page) (paging.Result[mdm.QueuedCommand], error)
List implements mdm.CommandQueue.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is the SQL-backed durable store: enrollments, certificates, credentials, device facts and the event log. The command queue is a separate type (Queue) over the same connection, because storage.Store and mdm.CommandQueue both define Get and List with different signatures.
func (*Store) AgentWake ¶
AgentWake authenticates a device agent and returns the newest outstanding user command ID. Empty means that no wake is needed.
func (*Store) Certificate ¶
Certificate implements storage.CertificateStore.
func (*Store) CertificateByThumbprint ¶
func (s *Store) CertificateByThumbprint(ctx context.Context, thumbprint string) (*storage.Certificate, error)
CertificateByThumbprint implements storage.CertificateStore.
func (*Store) Create ¶
Create implements storage.EnrollmentStore. It supersedes the device's current active enrollment and inserts the new one, atomically.
func (*Store) GetBySerial ¶
GetBySerial implements storage.EnrollmentStore.
func (*Store) GetByThumbprint ¶
func (s *Store) GetByThumbprint(ctx context.Context, thumbprint string) (*storage.Enrollment, error)
GetByThumbprint implements storage.EnrollmentStore.
func (*Store) IssueAgentToken ¶
IssueAgentToken rotates the agent credential for the current enrollment. Only its SHA-256 digest is stored. Re-enrollment also invalidates it because the stored serial must match the currently active enrollment.
func (*Store) List ¶
func (s *Store) List(ctx context.Context, q storage.EnrollmentQuery, p paging.Page) (paging.Result[storage.Enrollment], error)
List implements storage.EnrollmentStore.
func (*Store) ListByHWDevID ¶
ListByHWDevID implements storage.EnrollmentStore.
func (*Store) ListCertificates ¶
func (s *Store) ListCertificates(ctx context.Context, q storage.CertificateQuery, p paging.Page) (paging.Result[storage.Certificate], error)
ListCertificates implements storage.CertificateStore.
func (*Store) MDMCredential ¶
MDMCredential implements storage.CredentialStore.
func (*Store) MarkPushDead ¶
MarkPushDead only invalidates the URI that failed, preserving a concurrent renewal.
func (*Store) ObservePush ¶
func (s *Store) ObservePush(ctx context.Context, serial string, uri, status *string, at time.Time) error
ObservePush records a successful read. Nil fields were not reported. Re-reading the same URI does not reset its age or revive a known-dead channel.
func (*Store) PushChannel ¶
PushChannel returns the last observed WNS channel for an enrollment.
func (*Store) PutCertificate ¶
PutCertificate implements storage.CertificateStore.
func (*Store) PutFacts ¶
PutFacts records the facts a device reported, merging the DevInfo and the non-empty scalar fields into any existing row.
func (*Store) PutMDMCredential ¶
PutMDMCredential implements storage.CredentialStore.