Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Domain ¶
type Domain struct {
Host string `json:"host"`
IP string `json:"ip,omitempty"`
SSHHostName string `json:"sshHostName,omitempty"`
SSHUser string `json:"sshUser,omitempty"`
TLSValid *bool `json:"tlsValid,omitempty"`
TLSExpiry *time.Time `json:"tlsExpiry,omitempty"`
LastChecked time.Time `json:"lastChecked,omitempty"`
Comment string `json:"comment,omitempty"`
SSHOverride string `json:"sshOverride,omitempty"`
// SSHPasswordAuth forces `-o PreferredAuthentications=password` on connect,
// for hosts where key-based auth isn't set up yet. Remembered per-domain.
SSHPasswordAuth bool `json:"sshPasswordAuth,omitempty"`
// SSHUserAsked records whether the user has already been prompted for a
// username when no ~/.ssh/config entry was found, so we don't ask again.
SSHUserAsked bool `json:"sshUserAsked,omitempty"`
// SSHPasswordSaved is a UI-only flag noting that a password for this
// host is stored in the encrypted vault (~/.config/stool/secrets.enc).
// The password itself never lives in this file.
SSHPasswordSaved bool `json:"sshPasswordSaved,omitempty"`
// UpdatedAt is bumped on every user-visible edit (comment, ssh link,
// user, password flags, IP change) — the sync merge uses it to pick the
// newer of two concurrently edited copies.
UpdatedAt time.Time `json:"updatedAt,omitempty"`
}
func (*Domain) EffectiveSSHHost ¶
EffectiveSSHHost returns SSHOverride if set, otherwise the auto-matched SSHHostName.
func (*Domain) SSHTarget ¶
SSHTarget returns the ssh destination to actually run commands on: the linked ~/.ssh/config alias if there is one, otherwise a raw "user@ip" built from the domain's resolved IP (defaulting to user "root"), so remote tools can still run even for domains with no named ssh host. Empty if neither an alias nor an IP is known yet.
func (*Domain) Stamp ¶
Stamp is the domain's effective last-modification time for merge decisions: the newer of the explicit edit stamp and the last probe.
func (*Domain) Touch ¶
func (d *Domain) Touch()
Touch marks the domain as just-edited (see UpdatedAt).
func (*Domain) VaultKey ¶
VaultKey identifies the actual connection target a saved password belongs to — the ~/.ssh/config alias if one is linked, otherwise the resolved IP, falling back to the domain name itself if neither is known yet. Keying on the target rather than the domain means two domains pointing at the same host/IP transparently share one saved password.
func (*Domain) VaultTarget ¶
VaultTarget is the human-readable form of VaultKey (without its type prefix), for displaying what a saved password is actually attached to.
type LocalPrefs ¶
type LocalPrefs struct {
// HostSyncOff holds project names whose HOST sync is disabled here
// (absence = enabled, the default).
HostSyncOff map[string]bool `json:"hostSyncOff,omitempty"`
}
LocalPrefs are MACHINE-LOCAL settings that must never travel through any sync channel — each machine decides for itself. Stored in local.json in the config dir, which the global sync repo gitignores.
Currently: per-project "sync ssh hosts too, or only domains". The importer of a shared project chooses whether stool may touch this machine's ~/.ssh/config for it.
func LoadPrefs ¶
func LoadPrefs() *LocalPrefs
LoadPrefs reads the machine-local preferences; a missing or unreadable file yields defaults (everything enabled).
func (*LocalPrefs) HostSyncEnabled ¶
func (p *LocalPrefs) HostSyncEnabled(project string) bool
HostSyncEnabled reports whether host definitions sync for the project on THIS machine (default true).
func (*LocalPrefs) Save ¶
func (p *LocalPrefs) Save() error
func (*LocalPrefs) SetHostSync ¶
func (p *LocalPrefs) SetHostSync(project string, enabled bool)
SetHostSync flips the per-project host sync for this machine.
type Project ¶
type Project struct {
Name string `json:"name"`
Domains []Domain `json:"domains"`
// Hosts are the ssh host definitions referenced by this project's
// domains, synced alongside them (see SyncedHost).
Hosts []SyncedHost `json:"hosts,omitempty"`
// SyncRemote is the git remote for project-level sync (empty = not
// synced individually). It lives in data.json on purpose: the global
// sync carries it, so a second machine auto-configures the project repo.
SyncRemote string `json:"syncRemote,omitempty"`
}
func (*Project) FindDomain ¶
func (*Project) FindHost ¶
func (p *Project) FindHost(alias string) *SyncedHost
FindHost returns the synced host definition with the given canonical alias, or nil.
func (*Project) RemoveDomain ¶
type Store ¶
type Store struct {
Projects []Project `json:"projects"`
}
func (*Store) AddProject ¶
func (*Store) FindProject ¶
func (*Store) RemoveProject ¶
type SyncedHost ¶
type SyncedHost struct {
Alias string `json:"alias"`
HostName string `json:"hostName,omitempty"`
User string `json:"user,omitempty"`
Port string `json:"port,omitempty"`
Comment string `json:"comment,omitempty"`
// UpdatedAt drives the 3-way merge: the newer edit of a host wins.
UpdatedAt time.Time `json:"updatedAt,omitempty"`
}
SyncedHost is an ssh host definition carried by project sync: the config of a host that the project's domains link to, exported from ~/.ssh/config on the machine that edited it and applied to ~/.ssh/config on the others. Alias is the repo-wide CANONICAL name; on a machine where that name is taken by a hand-written block, the definition is materialized under a derived local alias carrying a canonical marker (see sshconfig.Canonical). IdentityFile is deliberately absent — key paths are machine-local.