config

package
v0.12.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 12, 2026 License: MIT Imports: 36 Imported by: 0

Documentation

Index

Constants

View Source
const OpenSSHNodePrefix = "openssh:"

Variables

View Source
var (
	// ErrNodeNotFound 节点不存在错误
	ErrNodeNotFound = errors.New("node not found")
	// ErrHostNotFound 关联的主机配置不存在
	ErrHostNotFound = errors.New("host reference not found")
	// ErrIdentityNotFound 关联的认证身份不存在
	ErrIdentityNotFound = errors.New("identity reference not found")
	// ErrProxyCycle 检测到代理跳转环路
	ErrProxyCycle = errors.New("proxy jump cycle detected")
	// ErrAmbiguousNode means a selector matched more than one node.
	ErrAmbiguousNode = errors.New("node selector is ambiguous")
)
View Source
var ErrConfigConflict = errors.New("configuration revision conflict")
View Source
var ErrSchemaValidation = errors.New("schema validation failed")

ErrSchemaValidation 表示配置模式校验失败。

View Source
var ErrUnsupportedSchemaVersion = errors.New("unsupported schema version")

ErrUnsupportedSchemaVersion 表示不支持的配置文件 schema_version。

Functions

func BackupReferences added in v0.12.0

func BackupReferences(path, storeID string) ([]credential.Ref, error)

BackupReferences reads a caller-selected stopped schema-v2 backup without loading legacy secrets or publishing configuration. Only matching refs return.

func BindPrivateKeyFingerprint added in v0.12.0

func BindPrivateKeyFingerprint(cfg *Configuration, target credential.Target, passphrase []byte) (credential.Target, error)

BindPrivateKeyFingerprint prepares v2 passphrase metadata before the caller enters a credential transaction. Legacy compatibility is unchanged.

func BuildRegistryFromConfig added in v0.12.0

func BuildRegistryFromConfig(credCfg *CredentialConfig) (*credential.Registry, error)

BuildRegistryFromConfig 遍历 CredentialConfig 中声明的所有 stores 并构建已注册的 Registry。

func BuildStore added in v0.12.0

func BuildStore(storeID string, cfg StoreConfig) (credential.Store, error)

BuildStore 根据 StoreConfig 配置实例化对应的凭据存储。 若配置了 cache_ttl > 0,会自动挂载有界内存凭据缓存装饰器。

func DetectSchemaVersion added in v0.12.0

func DetectSchemaVersion(data []byte) (int, error)

DetectSchemaVersion 探测 YAML 字节流的配置模式版本。 如果没有显式指定 schema_version,按 Schema v1 处理(返回 1)。 目前支持版本 1 与版本 2;其余版本返回 ErrUnsupportedSchemaVersion。

func FormatHostPort added in v0.12.0

func FormatHostPort(address string, port uint16) string

FormatHostPort formats host and port, enclosing IPv6 addresses in brackets.

func FormatNodeID added in v0.12.0

func FormatNodeID(user, address string, port uint16) string

FormatNodeID formats node ID using user@host:port (with IPv6 bracketed if necessary).

func PrivateKeyFingerprint added in v0.12.0

func PrivateKeyFingerprint(path string, passphrase []byte) (string, error)

PrivateKeyFingerprint verifies a private key and returns its public fingerprint. Key material is transient and never included in a returned configuration.

func ResolveProxyJumpChainWithConfig added in v0.12.0

func ResolveProxyJumpChainWithConfig(cfg *Configuration, openSSH *OpenSSHParser, jumpChain string) (string, error)

ResolveProxyJumpChainWithConfig validates and normalizes a comma-separated jump host chain.

func ValidateV2 added in v0.12.0

func ValidateV2(cfg *ConfigurationV2) error

ValidateV2 对 ConfigurationV2 进行全面且严格的合法性校验。

Types

type AmbiguousNodeError added in v0.12.0

type AmbiguousNodeError struct {
	Selector   string
	Candidates []string
}

AmbiguousNodeError reports a selector that resolves to more than one local node. Choosing one implicitly would make a command target nondeterministic.

func (*AmbiguousNodeError) Error added in v0.12.0

func (e *AmbiguousNodeError) Error() string

func (*AmbiguousNodeError) Unwrap added in v0.12.0

func (e *AmbiguousNodeError) Unwrap() error

type CommitResult added in v0.12.0

type CommitResult struct {
	Snapshot Snapshot
	Applied  bool
	Durable  bool
}

CommitResult distinguishes pre-write failures from a replacement that was applied but whose crash durability is uncertain.

type ConfigProvider

type ConfigProvider interface {
	Resolve(name string) (models.Node, models.Host, models.Identity, error)
	// ResolveConnection returns one complete connection view. The optional
	// UpdateRef is present only when discovery may be conditionally persisted.
	ResolveConnection(name string) (ConnectionSnapshot, error)
	GetNode(name string) (models.Node, bool)
	GetHost(name string) (models.Host, bool)
	GetIdentity(name string) (models.Identity, bool)
	ListNodes() map[string]models.Node
	GetNodesByTag(tag string) map[string]models.Node
	ListIdentities() map[string]models.Identity
	Find(input string) string
	ResolveSelector(input string) (string, error)
	FindAlias(alias string) string
	ResolveProxyJumpChain(jumpChain string) (string, error)
	Snapshot() *Configuration
}

ConfigProvider is the read-only configuration view consumed by commands, connectors, and presentation code. Durable mutations intentionally do not belong here: they must go through Repository, which verifies preconditions inside one cross-process transaction.

type ConfigView added in v0.12.0

type ConfigView struct {
	Revision      uint64
	Configuration *Configuration
	NodeRefs      map[string]NodeRef
	IdentityRefs  map[string]IdentityRef
}

ConfigView is one immutable configuration revision. Configuration is a defensive copy and may safely be retained or changed by its caller.

type Configuration

type Configuration struct {
	SchemaVersion         int                                      `yaml:"schema_version,omitempty"`
	Credential            *CredentialConfig                        `yaml:"credential,omitempty"`
	Identities            *concurrent.Map[string, models.Identity] `yaml:"identities"`
	Hosts                 *concurrent.Map[string, models.Host]     `yaml:"hosts"`
	Nodes                 *concurrent.Map[string, models.Node]     `yaml:"nodes"`
	Guardrail             *GuardrailConfig                         `yaml:"guardrail,omitempty"`
	PasswordPromptPattern string                                   `yaml:"password_prompt_pattern,omitempty"` // 全局级自定义密码提示正则
}

Configuration 对应 yaml 文件的顶层结构

func FromV2 added in v0.12.0

func FromV2(v2 *ConfigurationV2) (*Configuration, error)

FromV2 将 Schema v2 DTO 转换为内存中的 Configuration 实体。

func (*Configuration) CanRememberCredentials added in v0.12.0

func (c *Configuration) CanRememberCredentials() bool

CanRememberCredentials checks configured write capability without accessing a backend. Missing configuration means none, including for legacy v1 files.

func (*Configuration) Snapshot added in v0.12.0

func (c *Configuration) Snapshot() *Configuration

Snapshot 返回当前配置的防御性深拷贝副本。

func (*Configuration) ToV2 added in v0.12.0

func (c *Configuration) ToV2() (*ConfigurationV2, error)

ToV2 将内存中的 Configuration 转换为 Schema v2 DTO。 如果包含明文机密,将拒绝转换,确保安全。

type ConfigurationV2 added in v0.12.0

type ConfigurationV2 struct {
	SchemaVersion         int                    `yaml:"schema_version"`
	Credential            CredentialConfig       `yaml:"credential"`
	Identities            map[string]IdentityV2  `yaml:"identities"`
	Hosts                 map[string]models.Host `yaml:"hosts"`
	Nodes                 map[string]NodeV2      `yaml:"nodes"`
	Guardrail             *GuardrailConfig       `yaml:"guardrail,omitempty"`
	PasswordPromptPattern string                 `yaml:"password_prompt_pattern,omitempty"`
}

ConfigurationV2 是 Schema v2 的顶级规范配置 DTO。 【安全红线】本结构及反序列化过程中绝不包含任何密码明文字段。

func UnmarshalV2 added in v0.12.0

func UnmarshalV2(data []byte) (*ConfigurationV2, error)

UnmarshalV2 解析并严格校验 Schema v2 YAML 配置。 如果 YAML 中含有历史明文机密字段(password/passphrase/su_pwd),坚决拒绝并返回错误。

type ConnectionSnapshot added in v0.12.0

type ConnectionSnapshot struct {
	Node      models.Node
	Host      models.Host
	Identity  models.Identity
	UpdateRef *ConnectionUpdateRef
}

ConnectionSnapshot is one internally consistent connection configuration. UpdateRef is nil for read-only sources, including OpenSSH virtual nodes.

type ConnectionTarget added in v0.12.0

type ConnectionTarget struct {
	Selector     string
	User         string
	HasUser      bool
	Port         uint16
	HasPort      bool
	ProxyJump    string
	HasProxyJump bool
}

ConnectionTarget represents the user's connection intent, preserving whether user, port, and jump host were explicitly specified.

type ConnectionUpdateRef added in v0.12.0

type ConnectionUpdateRef struct {
	AuthVersion Version
	SudoVersion Version
}

ConnectionUpdateRef carries the field versions observed with a persistent connection snapshot. Both versions must originate from that same snapshot.

type CredentialConfig added in v0.12.0

type CredentialConfig struct {
	DefaultStore     string                 `yaml:"default_store"`
	RememberPrompted string                 `yaml:"remember_prompted,omitempty"` // "ask", "always", "never"
	Stores           map[string]StoreConfig `yaml:"stores"`
}

CredentialConfig 描述 Schema v2 顶层的凭据全局配置。

func DefaultCredentialConfig added in v0.12.0

func DefaultCredentialConfig() *CredentialConfig

DefaultCredentialConfig returns independent, lazy new-install defaults. Paths are relative to the configuration file, never to the working directory. Callers must preserve existing explicit backend and remember-policy choices.

func (*CredentialConfig) Clone added in v0.12.0

func (c *CredentialConfig) Clone() *CredentialConfig

Clone 返回 CredentialConfig 的深拷贝。

type CredentialMigrator added in v0.12.0

type CredentialMigrator struct {
	// contains filtered or unexported fields
}

CredentialMigrator operates directly on files, never publishing legacy secrets into a Repository or Provider. It serializes migrations separately from ordinary configuration edits; backend I/O never holds the config lock.

func NewCredentialMigrator added in v0.12.0

func NewCredentialMigrator(configPath, keyPath string) (*CredentialMigrator, error)

NewCredentialMigrator binds migration to fixed local paths without reading or writing them.

func (*CredentialMigrator) AutoMigrate added in v0.12.0

func (m *CredentialMigrator) AutoMigrate(ctx context.Context) (MigrationReport, error)

AutoMigrate upgrades eligible legacy configurations to their selected store. A zero report means the configuration was absent, already v2, or opted out. Call only from normal usage paths; never from inspection or dry-run commands.

func (*CredentialMigrator) Finalize added in v0.12.0

func (m *CredentialMigrator) Finalize(ctx context.Context) (report MigrationReport, retErr error)

Finalize rechecks the current metadata-only config and all live references, then removes old files. Only this explicitly invoked operation deletes old material. Partial cleanup is retryable and never touches backend secrets.

func (*CredentialMigrator) Migrate added in v0.12.0

func (m *CredentialMigrator) Migrate(ctx context.Context, opts MigrationOptions) (report MigrationReport, retErr error)

Migrate preserves all old materials until an explicit Finalize call. A failed or interrupted run can reuse the recorded immutable refs on the next run.

func (*CredentialMigrator) WithRegistryFactory added in v0.12.0

func (m *CredentialMigrator) WithRegistryFactory(factory func(*CredentialConfig) (*credential.Registry, error)) *CredentialMigrator

WithRegistryFactory injects the composition owner's stores without reading input files.

type DurabilityChecker added in v0.12.0

type DurabilityChecker interface {
	IsDurable() bool
}

DurabilityChecker 表示支持查询存储持久介质是否已真正耐久落盘的接口。

type DurabilityError added in v0.12.0

type DurabilityError struct {
	Err error
}

DurabilityError reports a write which has replaced the configuration file but whose parent-directory sync failed. The mutation is visible now and must not be retried blindly.

func (*DurabilityError) Error added in v0.12.0

func (e *DurabilityError) Error() string

func (*DurabilityError) Unwrap added in v0.12.0

func (e *DurabilityError) Unwrap() error

type EncryptedRuntime added in v0.12.0

type EncryptedRuntime struct {
	// contains filtered or unexported fields
}

EncryptedRuntime is an explicitly owned composition-root resource. Close must be awaited before exit or configuration replacement. Registries borrow it.

func NewEncryptedRuntime added in v0.12.0

func NewEncryptedRuntime(ctx context.Context, configPath string, prompt credentialfile.PromptProvider) *EncryptedRuntime

NewEncryptedRuntime binds path resolution and terminal interaction for one owner.

func (*EncryptedRuntime) Close added in v0.12.0

func (r *EncryptedRuntime) Close() error

Close cancels and reaps all sessions, stores and KDF children.

func (*EncryptedRuntime) Lock added in v0.12.0

func (r *EncryptedRuntime) Lock(ctx context.Context) error

Lock revokes all sessions already opened by this owner. Unopened stores have no keys.

func (*EncryptedRuntime) Registry added in v0.12.0

Registry builds lazy sources. File stores use only Runtime's revision-aware cache, never the generic credential cache decorator.

func (*EncryptedRuntime) Store added in v0.12.0

Store opens a configured file store without unlocking it. Failed opens retry.

func (*EncryptedRuntime) Vaults added in v0.12.0

Vaults exposes maintenance operations on the same process-owned runtime.

type EnsureNodeOptions added in v0.12.0

type EnsureNodeOptions struct {
	Target       ConnectionTarget
	DefaultUser  string
	Password     string
	IdentityFile string
	Passphrase   string
	Alias        string
	Tags         []string
	SudoMode     models.SudoMode
	SuPwd        string
}

EnsureNodeOptions carries connection intent and optional creation attributes.

type EnsureNodeResult added in v0.12.0

type EnsureNodeResult struct {
	NodeID   string
	Created  bool
	Mutation NodeMutation
}

EnsureNodeResult contains the resolved or created node ID and mutation details.

type GuardrailConfig

type GuardrailConfig struct {
	Enabled           bool                        `yaml:"enabled"`
	AuditLog          string                      `yaml:"audit_log,omitempty"`
	ApprovalThreshold string                      `yaml:"approval_threshold,omitempty"` // "safe"|"moderate"|"dangerous"
	BlockedPatterns   []string                    `yaml:"blocked_patterns,omitempty"`
	ProtectedPaths    []string                    `yaml:"protected_paths,omitempty"`
	NodeOverrides     map[string]NodeGuardrailCfg `yaml:"nodes,omitempty"`

	// NoElicitFallback controls behavior when the MCP client does not support
	// Elicitation (e.g. Gemini CLI).
	//   "deny"      — reject all operations that need approval (most secure)
	//   "allow"     — allow all, trust client-side tool approval + ToolAnnotations
	//   "downgrade" — allow moderate, still deny dangerous (recommended default)
	NoElicitFallback string `yaml:"no_elicit_fallback,omitempty"`
}

GuardrailConfig configures the MCP safety guardrail.

type IdentityRef added in v0.12.0

type IdentityRef struct {
	ID      string
	Version Version
}

IdentityRef identifies the exact identity record displayed to a caller. It is intentionally distinct from NodeRef so a stale identity cannot be accidentally used as a node precondition.

type IdentityV2 added in v0.12.0

type IdentityV2 struct {
	User             string          `yaml:"user"`
	KeyPath          string          `yaml:"key_path,omitempty"`
	KeyFingerprint   string          `yaml:"key_fingerprint,omitempty"`
	LoginPasswordRef *credential.Ref `yaml:"login_password_ref,omitempty"`
	PassphraseRef    *credential.Ref `yaml:"passphrase_ref,omitempty"`
	AuthType         string          `yaml:"auth_type"`
}

IdentityV2 对应 Schema v2 中的认证身份配置,不含任何明文凭据。

type ImportIssue added in v0.12.0

type ImportIssue struct {
	Name string
	Err  error
}

ImportIssue records one OpenSSH host that could not be imported without making the whole batch invalid.

type ImportResult added in v0.12.0

type ImportResult struct {
	Imported int
	Skipped  int
	Issues   []ImportIssue
}

ImportResult separates expected per-host skips from fatal persistence failures. A non-nil error from ImportOpenSSHHosts means no batch state was published unless it is a DurabilityError.

type MigrationOptions added in v0.12.0

type MigrationOptions struct {
	ToStore string
	DryRun  bool
	Restart bool
	// contains filtered or unexported fields
}

MigrationOptions selects an explicitly configured writable destination.

type MigrationReport added in v0.12.0

type MigrationReport struct {
	Store            string
	Credentials      int
	BackupPath       string
	BackupKeyPath    string
	DryRun           bool
	Verified         bool
	Finalized        bool
	BackendMigration bool
}

MigrationReport contains metadata only. It never returns decoded secrets.

type MutationOutcome added in v0.12.0

type MutationOutcome struct {
	Applied bool
	Durable bool
}

MutationOutcome reports whether a durable configuration mutation reached the destination pathname and whether it is crash durable. Applied mutations remain authoritative even when the accompanying error is a DurabilityError.

type NodeGuardrailCfg

type NodeGuardrailCfg struct {
	ApprovalThreshold string `yaml:"approval_threshold"`
}

NodeGuardrailCfg holds per-node (glob pattern) policy overrides.

type NodeMutation added in v0.12.0

type NodeMutation struct {
	Ref         NodeRef
	AuthVersion string
	Outcome     MutationOutcome
}

NodeMutation is returned by node creation even when persistence reports a durability failure. Ref must be used for later conditional cleanup.

type NodeRef added in v0.12.0

type NodeRef struct {
	ID      string
	Version Version
}

NodeRef identifies a displayed node bundle and the exact node, host, and identity values it contained. It is suitable for optimistic concurrency across independently running CLI processes.

type NodeV2 added in v0.12.0

type NodeV2 struct {
	Alias                 []string        `yaml:"alias,omitempty"`
	Tags                  []string        `yaml:"tags,omitempty"`
	HostRef               string          `yaml:"host_ref"`
	IdentityRef           string          `yaml:"identity_ref"`
	ProxyJump             string          `yaml:"proxy_jump,omitempty"`
	SudoMode              models.SudoMode `yaml:"sudo_mode"`
	PrivilegePasswordRef  *credential.Ref `yaml:"privilege_password_ref,omitempty"`
	PasswordPromptPattern string          `yaml:"password_prompt_pattern,omitempty"`
}

NodeV2 对应 Schema v2 中的节点配置,提权密码使用引用模型。

type OpenSSHHost added in v0.11.0

type OpenSSHHost struct {
	Name     string
	Host     models.Host
	Identity models.Identity
	Node     models.Node
}

OpenSSHHost is a concrete Host entry that can be persisted in the XOps inventory. Wildcard and negated patterns are intentionally excluded because they do not identify a single inventory node.

func ParseOpenSSHHosts added in v0.11.0

func ParseOpenSSHHosts(r io.Reader, defaultUser string) ([]OpenSSHHost, error)

ParseOpenSSHHosts parses concrete Host entries from an OpenSSH configuration. It does not connect to any remote host or modify the source configuration.

type OpenSSHParser added in v0.5.0

type OpenSSHParser struct {
	// contains filtered or unexported fields
}

OpenSSHParser 提供针对 ~/.ssh/config 的解析和模型映射功能

func NewOpenSSHParser added in v0.5.0

func NewOpenSSHParser() (*OpenSSHParser, error)

NewOpenSSHParser 尝试从标准路径加载用户的 ~/.ssh/config 配置文件。 如果文件不存在,返回空的 OpenSSHParser 和 nil 错误;其他错误返回具体包装错误。

func NewOpenSSHParserFromPath added in v0.12.0

func NewOpenSSHParserFromPath(path string) (parser *OpenSSHParser, retErr error)

NewOpenSSHParserFromPath 从指定路径加载 SSH 配置文件。如果文件不存在,返回空的 OpenSSHParser 和 nil 错误。

func NewOpenSSHParserFromReader added in v0.12.0

func NewOpenSSHParserFromReader(r io.Reader) (*OpenSSHParser, error)

NewOpenSSHParserFromReader 从任意 io.Reader 加载 SSH 配置

func (*OpenSSHParser) Find added in v0.5.0

func (p *OpenSSHParser) Find(alias string) (string, bool)

Find 尝试在 ssh_config 中寻找匹配的主机名 如果用户输入了未知主机,我们一律返回带前缀的虚拟 NodeID, 在连接时利用 ssh_config 的默认回退属性来尝试连接, 这样使得 xops 表现得和原生 ssh 命令的体验完全一致。

func (*OpenSSHParser) GetVirtualNode added in v0.5.0

func (p *OpenSSHParser) GetVirtualNode(alias string) (models.Node, models.Host, models.Identity, error)

GetVirtualNode 根据 alias 从 ssh_config 生成运行时的内存 Node / Host / Identity

func (*OpenSSHParser) HasHost added in v0.12.0

func (p *OpenSSHParser) HasHost(alias string) bool

HasHost 检查 alias 是否在 ssh_config 中显式定义了具体的 Host 模式(排除仅通配符匹配)。

type PersistResult added in v0.12.0

type PersistResult struct {
	Applied bool
	Durable bool
}

PersistResult describes the observable outcome of one configuration write. Applied means the destination pathname was replaced. Durable means the replacement was also synchronized to the parent directory.

A write can be applied without being durable when the directory sync fails. Callers must not retry such a write blindly: the current process already observes the new file, while crash recovery durability is uncertain.

type Provider

type Provider struct {
	// contains filtered or unexported fields
}

Provider owns one coherent in-memory configuration snapshot. All reads see one revision. Repository owns durable mutations and publishes new snapshots.

func NewProvider

func NewProvider(cfg *Configuration) (*Provider, error)

NewProvider creates a provider and loads the local OpenSSH configuration.

func NewProviderWithOpenSSHParser added in v0.12.0

func NewProviderWithOpenSSHParser(cfg *Configuration, parser *OpenSSHParser) *Provider

NewProviderWithOpenSSHParser creates a provider using parser as its OpenSSH fallback. A nil parser disables the fallback.

func NewProviderWithoutOpenSSH added in v0.12.0

func NewProviderWithoutOpenSSH(cfg *Configuration) *Provider

NewProviderWithoutOpenSSH creates a provider without an OpenSSH fallback.

func (*Provider) Find

func (p *Provider) Find(input string) string

Find is the legacy no-error selector helper. Ambiguous selectors deliberately resolve to an empty string; callers that need diagnostics must use ResolveSelector.

func (*Provider) FindAlias added in v0.5.0

func (p *Provider) FindAlias(alias string) string

func (*Provider) GetHost

func (p *Provider) GetHost(nodeID string) (models.Host, bool)

func (*Provider) GetIdentity

func (p *Provider) GetIdentity(nodeID string) (models.Identity, bool)

func (*Provider) GetNode

func (p *Provider) GetNode(nodeID string) (models.Node, bool)

func (*Provider) GetNodesByTag

func (p *Provider) GetNodesByTag(tag string) map[string]models.Node

func (*Provider) ListIdentities

func (p *Provider) ListIdentities() map[string]models.Identity

func (*Provider) ListNodes

func (p *Provider) ListNodes() map[string]models.Node

func (*Provider) Resolve added in v0.12.0

func (p *Provider) Resolve(nodeID string) (models.Node, models.Host, models.Identity, error)

Resolve returns one internally consistent, defensive-copy configuration triple. OpenSSH virtual nodes remain read-only fallbacks.

func (*Provider) ResolveConnection added in v0.12.0

func (p *Provider) ResolveConnection(nodeID string) (ConnectionSnapshot, error)

ResolveConnection returns a read-only connection snapshot. Provider does not own durable mutations, so discovery values must remain session-local.

func (*Provider) ResolveProxyJumpChain added in v0.12.0

func (p *Provider) ResolveProxyJumpChain(jumpChain string) (string, error)

func (*Provider) ResolveSelector added in v0.12.0

func (p *Provider) ResolveSelector(input string) (string, error)

func (*Provider) Snapshot added in v0.12.0

func (p *Provider) Snapshot() *Configuration

Snapshot returns a deep copy that callers may retain and mutate freely.

type Repository added in v0.12.0

type Repository struct {
	// contains filtered or unexported fields
}

Repository is the sole durable mutation boundary for one process. It owns configuration state and serializes the complete clone-validate-persist- publish sequence. It intentionally does not expose its Store.

func NewRepository added in v0.12.0

func NewRepository(cfg *Configuration, store Store) (*Repository, error)

NewRepository creates a durable repository with an optional local OpenSSH fallback. OpenSSH parse failures are retained and reported only if a caller actually needs the fallback; local xops configuration stays usable.

func NewRepositoryWithOpenSSHParser added in v0.12.0

func NewRepositoryWithOpenSSHParser(cfg *Configuration, store Store, parser *OpenSSHParser) (*Repository, error)

NewRepositoryWithOpenSSHParser creates a durable repository with parser as its OpenSSH fallback. A nil parser disables the fallback.

func NewRepositoryWithoutOpenSSH added in v0.12.0

func NewRepositoryWithoutOpenSSH(cfg *Configuration, store Store) (*Repository, error)

NewRepositoryWithoutOpenSSH creates a durable repository without an OpenSSH fallback.

func (*Repository) AsConfigUpdater added in v0.12.0

func (r *Repository) AsConfigUpdater() credential.ConfigUpdater

AsConfigUpdater returns the credential.ConfigUpdater adapter for the repository.

func (*Repository) CheckRefUnreferenced added in v0.12.0

func (r *Repository) CheckRefUnreferenced(ctx context.Context, ref credential.Ref) (bool, error)

CheckRefUnreferenced checks whether the reference is unreferenced in authoritative storage and confirms that this unreferenced state has been durably persisted across processes.

func (*Repository) ConfirmRefDurable added in v0.12.0

func (r *Repository) ConfirmRefDurable(ctx context.Context, target credential.Target, ref *credential.Ref) (bool, error)

ConfirmRefDurable 从底层权威持久化存储重新检查指定 target 的凭据引用是否已持久化生效(Durable)。

func (*Repository) CreateIdentityContext added in v0.12.0

func (r *Repository) CreateIdentityContext(ctx context.Context, identityID string, identity models.Identity) (MutationOutcome, error)

CreateIdentityContext creates an identity only when its name is still absent in the transaction's freshly loaded snapshot.

func (*Repository) CreateNodeContext added in v0.12.0

func (r *Repository) CreateNodeContext(ctx context.Context, nodeID string, node models.Node, host models.Host, identity models.Identity) (mutation NodeMutation, retErr error)

CreateNodeContext creates one complete node bundle. Existing referenced records may be reused only when their values are exactly equal; creation can therefore never overwrite another process's host or identity.

func (*Repository) DeleteIdentityAtRefContext added in v0.12.0

func (r *Repository) DeleteIdentityAtRefContext(ctx context.Context, ref IdentityRef) (MutationOutcome, error)

DeleteIdentityAtRefContext removes an unreferenced identity only when it still equals the selected value.

func (*Repository) DeleteIdentityWithCredentialsContext added in v0.12.0

func (r *Repository) DeleteIdentityWithCredentialsContext(ctx context.Context, ref IdentityRef, service *credential.Service) error

DeleteIdentityWithCredentialsContext also retains the existing restriction that an identity referenced by any node cannot be deleted.

func (*Repository) DeleteNodeAtRefContext added in v0.12.0

func (r *Repository) DeleteNodeAtRefContext(ctx context.Context, ref NodeRef) (MutationOutcome, error)

DeleteNodeAtRefContext removes one node only if its complete bundle still equals the value created or displayed by the caller.

func (*Repository) DeleteNodesAtRefsContext added in v0.12.0

func (r *Repository) DeleteNodesAtRefsContext(ctx context.Context, refs []NodeRef) error

DeleteNodesAtRefsContext removes nodes only when every selected node bundle still matches its displayed version. Unrelated configuration updates may merge.

func (*Repository) DeleteNodesWithCredentialsContext added in v0.12.0

func (r *Repository) DeleteNodesWithCredentialsContext(ctx context.Context, refs []NodeRef, service *credential.Service) error

DeleteNodesWithCredentialsContext atomically removes selected assets, then cleans up their now-unreferenced credentials through a recoverable journal.

func (*Repository) EnsureNodeContext added in v0.12.0

func (r *Repository) EnsureNodeContext(ctx context.Context, opts EnsureNodeOptions) (EnsureNodeResult, error)

EnsureNodeContext ensures a node matching the target intent exists. If not, it atomically creates the required Host, Identity, and Node within a single configuration transaction.

func (*Repository) Find added in v0.12.0

func (r *Repository) Find(input string) string

func (*Repository) FindAlias added in v0.12.0

func (r *Repository) FindAlias(alias string) string

func (*Repository) GetHost added in v0.12.0

func (r *Repository) GetHost(nodeID string) (models.Host, bool)

func (*Repository) GetIdentity added in v0.12.0

func (r *Repository) GetIdentity(nodeID string) (models.Identity, bool)

func (*Repository) GetNode added in v0.12.0

func (r *Repository) GetNode(nodeID string) (models.Node, bool)

func (*Repository) GetNodesByTag added in v0.12.0

func (r *Repository) GetNodesByTag(tag string) map[string]models.Node

func (*Repository) IdentityCredentialEdit added in v0.12.0

func (r *Repository) IdentityCredentialEdit(ref IdentityRef, identity models.Identity) credential.ConfigUpdater

IdentityCredentialEdit binds a credential transaction to an exact identity edit. The returned updater retains defensive copies for a single operation.

func (*Repository) ImportOpenSSHHostsContext added in v0.12.0

func (r *Repository) ImportOpenSSHHostsContext(ctx context.Context, hosts []OpenSSHHost) (ImportResult, error)

ImportOpenSSHHostsContext adds all non-conflicting OpenSSH hosts in one durable transaction. Existing node IDs are skipped; malformed candidates are reported individually without suppressing their cause.

func (*Repository) InitializeContext added in v0.12.0

func (r *Repository) InitializeContext(ctx context.Context) error

InitializeContext persists an otherwise empty newly created configuration.

func (*Repository) ListIdentities added in v0.12.0

func (r *Repository) ListIdentities() map[string]models.Identity

func (*Repository) ListNodes added in v0.12.0

func (r *Repository) ListNodes() map[string]models.Node

func (*Repository) NodeCredentialCreate added in v0.12.0

func (r *Repository) NodeCredentialCreate(nodeID string, node models.Node, host models.Host, identity models.Identity) credential.ConfigUpdater

NodeCredentialCreate binds an authentication credential to atomic node creation. An empty expected version denotes an absent node; CreateNodeContext checks absence and referenced-record conflicts under the durable transaction lock.

func (*Repository) NodeCredentialEdit added in v0.12.0

func (r *Repository) NodeCredentialEdit(ref NodeRef, nodeID string, node models.Node, host models.Host, identity models.Identity) credential.ConfigUpdater

NodeCredentialEdit binds a credential transaction to an exact node bundle, including renames and private copies of shared hosts and identities.

func (*Repository) ReplaceIdentityAtRefContext added in v0.12.0

func (r *Repository) ReplaceIdentityAtRefContext(ctx context.Context, ref IdentityRef, identity models.Identity) (MutationOutcome, error)

ReplaceIdentityAtRefContext updates one shared identity only when it still equals the value the caller displayed.

func (*Repository) ReplaceNodeAtRefContext added in v0.12.0

func (r *Repository) ReplaceNodeAtRefContext(ctx context.Context, ref NodeRef, nodeID string, node models.Node, host models.Host, identity models.Identity) error

ReplaceNodeAtRefContext replaces a node bundle only if the original bundle still equals the one the caller displayed.

func (*Repository) ReplaceNodeAtRefWithAuthVersionContext added in v0.12.0

func (r *Repository) ReplaceNodeAtRefWithAuthVersionContext(ctx context.Context, ref NodeRef, nodeID string, node models.Node, host models.Host, identity models.Identity) (string, error)

ReplaceNodeAtRefWithAuthVersionContext replaces a node bundle and returns the authentication version produced by that same committed mutation.

func (*Repository) Resolve added in v0.12.0

func (r *Repository) Resolve(nodeID string) (models.Node, models.Host, models.Identity, error)

func (*Repository) ResolveConnection added in v0.12.0

func (r *Repository) ResolveConnection(nodeID string) (ConnectionSnapshot, error)

ResolveConnection returns one atomic connection snapshot. Persistent nodes receive field versions from the same configuration copy as their values; OpenSSH virtual nodes remain read-only and therefore have no UpdateRef.

func (*Repository) ResolveProxyJumpChain added in v0.12.0

func (r *Repository) ResolveProxyJumpChain(jumpChain string) (string, error)

ResolveProxyJumpChain validates and resolves a comma-separated jump host chain against the current configuration.

func (*Repository) ResolveSelector added in v0.12.0

func (r *Repository) ResolveSelector(input string) (string, error)

func (*Repository) Revision added in v0.12.0

func (r *Repository) Revision() uint64

func (*Repository) Snapshot added in v0.12.0

func (r *Repository) Snapshot() *Configuration

func (*Repository) UpdateAuthAtVersionContext added in v0.12.0

func (r *Repository) UpdateAuthAtVersionContext(ctx context.Context, nodeID, authVersion, password, keyPath, passphrase string) (string, error)

UpdateAuthAtVersionContext updates only authentication fields that still match the connection snapshot. A shared identity is copied for the current node before discovery is persisted, so runtime discovery cannot mutate a reusable template for unrelated nodes.

func (*Repository) UpdateIdentityCredentialRefAtVersionContext added in v0.12.0

func (r *Repository) UpdateIdentityCredentialRefAtVersionContext(
	ctx context.Context,
	identityID string,
	expectedVersion string,
	kind credential.Kind,
	newRef *credential.Ref,
) (MutationOutcome, string, error)

UpdateIdentityCredentialRefAtVersionContext updates the specified credential reference directly on an identity.

func (*Repository) UpdateNodeCredentialRefAtVersionContext added in v0.12.0

func (r *Repository) UpdateNodeCredentialRefAtVersionContext(
	ctx context.Context,
	nodeID string,
	expectedVersion string,
	kind credential.Kind,
	newRef *credential.Ref,
) (MutationOutcome, string, error)

UpdateNodeCredentialRefAtVersionContext updates the specified credential reference on a node. If the node shares an identity with other nodes, updating authentication credentials (KindLoginPassword or KindPassphrase) automatically forks a private identity for the node, preserving shared templates for other nodes.

func (*Repository) UpdateNodeCredentialRefWithKeyPathAtVersionContext added in v0.12.0

func (r *Repository) UpdateNodeCredentialRefWithKeyPathAtVersionContext(
	ctx context.Context,
	nodeID string,
	expectedVersion string,
	kind credential.Kind,
	newRef *credential.Ref,
	keyPath string,
) (MutationOutcome, string, error)

UpdateNodeCredentialRefWithKeyPathAtVersionContext atomically updates a node credential reference and, for a private-key passphrase, its non-secret key path. An empty keyPath leaves the existing path unchanged.

func (*Repository) UpdateNodeCredentialRefWithMetadataAtVersionContext added in v0.12.0

func (r *Repository) UpdateNodeCredentialRefWithMetadataAtVersionContext(
	ctx context.Context,
	nodeID string,
	expectedVersion string,
	kind credential.Kind,
	newRef *credential.Ref,
	keyPath string,
	authType string,
	clearKeyPath bool,
	clearLegacyLoginPassword bool,
	clearLegacyPassphrase bool,
) (MutationOutcome, string, error)

UpdateNodeCredentialRefWithMetadataAtVersionContext atomically updates a node credential reference with non-secret authentication metadata.

func (*Repository) UpdateNodeTagsContext added in v0.12.0

func (r *Repository) UpdateNodeTagsContext(ctx context.Context, nodeIDs, tags []string, add bool) (updatedCount int, retErr error)

UpdateNodeTagsContext applies one tag operation to all nodes in a single durable transaction and reports how many nodes changed. It is the CLI-facing batch operation; callers must resolve selectors before invoking it.

func (*Repository) UpdateSudoAtVersionContext added in v0.12.0

func (r *Repository) UpdateSudoAtVersionContext(ctx context.Context, nodeID, sudoVersion string, mode models.SudoMode, suPwd string) (string, error)

UpdateSudoAtVersionContext updates only sudo fields that still match the connection snapshot. It may merge with unrelated node or identity changes.

func (*Repository) View added in v0.12.0

func (r *Repository) View() ConfigView

View returns a self-consistent, mutable copy of the current state and its revision for optimistic concurrency at UI boundaries.

type RepositoryConfigUpdater added in v0.12.0

type RepositoryConfigUpdater struct {
	// contains filtered or unexported fields
}

RepositoryConfigUpdater adapts a Repository to satisfy credential.ConfigUpdater.

func NewRepositoryConfigUpdater added in v0.12.0

func NewRepositoryConfigUpdater(repo *Repository) *RepositoryConfigUpdater

NewRepositoryConfigUpdater creates a new RepositoryConfigUpdater.

func (*RepositoryConfigUpdater) ApplyCredentialRefAtVersion added in v0.12.0

func (u *RepositoryConfigUpdater) ApplyCredentialRefAtVersion(
	ctx context.Context,
	target credential.Target,
	expectedVersion string,
	newRef *credential.Ref,
) (credential.MutationOutcome, string, error)

ApplyCredentialRefAtVersion commits a credential reference mutation to the repository.

func (*RepositoryConfigUpdater) CheckRefUnreferenced added in v0.12.0

func (u *RepositoryConfigUpdater) CheckRefUnreferenced(ctx context.Context, ref credential.Ref) (bool, error)

CheckRefUnreferenced checks whether the reference is unreferenced in the configuration.

func (*RepositoryConfigUpdater) ConfirmRefDurable added in v0.12.0

func (u *RepositoryConfigUpdater) ConfirmRefDurable(ctx context.Context, target credential.Target, ref *credential.Ref) (bool, error)

ConfirmRefDurable checks whether the reference has become durable in authoritative storage.

type Snapshot added in v0.12.0

type Snapshot struct {
	Configuration *Configuration
	Version       Version
}

Snapshot is a defensive plaintext configuration copy paired with its serialized version.

type Store

type Store interface {
	Load() (*Configuration, error)
	Save(cfg *Configuration) error
}

Store 定义了配置存储和持久化的接口

func NewDefaultStore

func NewDefaultStore(path string, keyPath string) Store

NewDefaultStore 创建一个默认的文件系统配置存储实例

type StoreConfig added in v0.12.0

type StoreConfig struct {
	Path           string        `yaml:"path,omitempty"`
	Unlock         string        `yaml:"unlock,omitempty"`
	KeyFile        string        `yaml:"key_file,omitempty"`
	UnlockIdleTTL  time.Duration `yaml:"unlock_idle_ttl,omitempty"`
	PromptTimeout  time.Duration `yaml:"prompt_timeout,omitempty"`
	UnlockTimeout  time.Duration `yaml:"unlock_timeout,omitempty"`
	Type           StoreType     `yaml:"type"`
	Timeout        time.Duration `yaml:"timeout"`
	CacheTTL       time.Duration `yaml:"cache_ttl"`
	Prefix         string        `yaml:"prefix,omitempty"`
	Command        string        `yaml:"command,omitempty"`
	Args           []string      `yaml:"args,omitempty"`
	NonInteractive bool          `yaml:"non_interactive,omitempty"`
	ReadOnly       bool          `yaml:"read_only,omitempty"`
}

StoreConfig 描述单个凭据存储后端的连接与运行配置。

func FileStoreDefaults added in v0.12.0

func FileStoreDefaults(s StoreConfig) StoreConfig

FileStoreDefaults applies the encrypted-file defaults to an in-memory configuration. YAML decoding separately rejects explicit zero duration fields.

func ResolveFileStore added in v0.12.0

func ResolveFileStore(s StoreConfig, configPath string) (StoreConfig, error)

ResolveFileStore resolves vault paths relative to the actual configuration file. An empty configuration filename permits only absolute vault and key paths.

func (StoreConfig) MarshalYAML added in v0.12.0

func (s StoreConfig) MarshalYAML() (any, error)

MarshalYAML writes effective offline defaults so in-memory zero defaults do not turn into explicitly invalid zero durations when configuration is saved.

func (*StoreConfig) UnmarshalYAML added in v0.12.0

func (s *StoreConfig) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML 自定义反序列化,支持 "5s"、"10m" 格式的超时与缓存 TTL 配置,并严格校验未知字段。

type StoreType added in v0.12.0

type StoreType string

StoreType 定义受支持的凭据存储后端类型。

const (
	StoreTypeSystem        StoreType = "system"
	StoreTypePass          StoreType = "pass"
	StoreTypeHelper        StoreType = "helper"
	StoreTypeNone          StoreType = "none"
	StoreTypeEncryptedFile StoreType = "encrypted-file"
)

type Syncer added in v0.12.0

type Syncer interface {
	Sync(ctx context.Context) error
}

Syncer 表示支持显式刷新文件与目录至持久介质的存储。

type TransactionStore added in v0.12.0

type TransactionStore interface {
	LoadSnapshot(ctx context.Context) (Snapshot, error)
	Transact(ctx context.Context, mutate func(Snapshot) (*Configuration, error)) (CommitResult, error)
}

TransactionStore atomically reloads, mutates, validates at the caller, and persists configuration while holding the cross-process configuration lock. Mutators must be CPU-only and must not perform I/O while the lock is held.

type Version added in v0.12.0

type Version [sha256.Size]byte

Version identifies the exact serialized configuration observed by a transaction. It is the SHA-256 digest of the on-disk file bytes; the digest of an absent file is SHA-256 of an empty byte slice.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL