Documentation
¶
Index ¶
- Constants
- func ApplyRedisScope(cfg *asset_entity.RedisConfig, scope string) error
- func ArgOptionalPartition(args map[string]any) (*int32, error)
- func CanonicalizeEtcdCommand(_ *asset_entity.Asset, command string) (string, error)
- func CanonicalizeKafkaCommand(_ *asset_entity.Asset, command string) (string, error)
- func CanonicalizeMongoCommand(asset *asset_entity.Asset, command string) (string, error)
- func CanonicalizeOSSCommand(_ *asset_entity.Asset, command string) (string, error)
- func ClosersAsOne(closers []io.Closer) io.Closer
- func DialAssetSSH(ctx context.Context, assetID int64) (*ssh.Client, func(), error)
- func DialSSHClient(ctx context.Context, assetID int64) (*ssh.Client, func(), error)
- func ExecCommandOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
- func ExecEtcdOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
- func ExecK8sOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
- func ExecKafkaOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
- func ExecMongoOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
- func ExecOSSOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
- func ExecRedisOnAsset(ctx context.Context, asset *asset_entity.Asset, command, scope string) (string, error)
- func ExecSQLOnAsset(ctx context.Context, asset *asset_entity.Asset, sqlText, scope string) (string, error)
- func ExecSerialOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
- func ExecWithStdio(ctx context.Context, assetID int64, command string, stdin io.Reader, ...) error
- func ExecuteK8sCommandLocal(ctx context.Context, kubeconfig string, args []string) (string, error)
- func ExecuteMongoDB(ctx context.Context, client *connpool.MongoClientCloser, ...) (string, error)
- func ExecuteRedis(ctx context.Context, client redis.UniversalClient, command, scope string) (string, error)
- func ExecuteRedisRaw(ctx context.Context, client redis.UniversalClient, args []string, scope string) (string, error)
- func ExecuteSQL(ctx context.Context, session dbdriver.Session, sqlText string) (string, error)
- func ExecuteSQLPaged(ctx context.Context, session dbdriver.Session, sqlText string, ...) (string, error)
- func ExecuteSSHCommand(ctx context.Context, assetID int64, command string) (string, error)
- func ExecuteWithSFTP(ctx context.Context, assetID int64, fn func(*sftp.Client) error) error
- func HandleKafkaACL(ctx context.Context, args map[string]any) (string, error)
- func HandleKafkaCluster(ctx context.Context, args map[string]any) (string, error)
- func HandleKafkaConnect(ctx context.Context, args map[string]any) (string, error)
- func HandleKafkaConsumerGroup(ctx context.Context, args map[string]any) (string, error)
- func HandleKafkaMessage(ctx context.Context, args map[string]any) (string, error)
- func HandleKafkaSchema(ctx context.Context, args map[string]any) (string, error)
- func HandleKafkaTopic(ctx context.Context, args map[string]any) (string, error)
- func HasGlobPattern(s string) bool
- func IsExpectedCloseErr(err error) bool
- func KafkaACLCommand(operation string) (string, error)
- func KafkaAlterTopicConfigRequestFromArgs(assetID int64, args map[string]any) (kafka_svc.AlterTopicConfigRequest, error)
- func KafkaCheckSchemaCompatibilityRequestFromArgs(assetID int64, args map[string]any) (kafka_svc.CheckSchemaCompatibilityRequest, error)
- func KafkaClusterCommand(operation string) (string, error)
- func KafkaConnectCommand(operation, connector string) (string, error)
- func KafkaConnectorConfigRequestFromArgs(assetID int64, args map[string]any) (kafka_svc.ConnectorConfigRequest, error)
- func KafkaConsumerGroupCommand(operation, group string) (string, error)
- func KafkaCreateACLRequestFromArgs(assetID int64, args map[string]any) kafka_svc.CreateACLRequest
- func KafkaCreateTopicRequestFromArgs(assetID int64, args map[string]any) (kafka_svc.CreateTopicRequest, error)
- func KafkaDeleteACLRequestFromArgs(assetID int64, args map[string]any) kafka_svc.DeleteACLRequest
- func KafkaDeleteRecordsRequestFromArgs(assetID int64, args map[string]any) (kafka_svc.DeleteRecordsRequest, error)
- func KafkaDeleteSchemaRequestFromArgs(assetID int64, args map[string]any) kafka_svc.DeleteSchemaRequest
- func KafkaInt32SliceFromJSON(raw string) ([]int32, error)
- func KafkaListACLsRequestFromArgs(assetID int64, args map[string]any) kafka_svc.ListACLsRequest
- func KafkaMessageCommand(operation, topic string) (string, error)
- func KafkaProduceHeadersFromArgs(args map[string]any) ([]kafka_svc.ProduceMessageHeader, error)
- func KafkaRegisterSchemaRequestFromArgs(assetID int64, args map[string]any) (kafka_svc.RegisterSchemaRequest, error)
- func KafkaResetConsumerGroupOffsetRequestFromArgs(assetID int64, args map[string]any) (kafka_svc.ResetConsumerGroupOffsetRequest, error)
- func KafkaRestartConnectorRequestFromArgs(assetID int64, args map[string]any) kafka_svc.RestartConnectorRequest
- func KafkaSchemaCommand(operation, subject string) (string, error)
- func KafkaSchemaReferencesFromJSON(raw string) ([]kafka_svc.SchemaReference, error)
- func KafkaStringMapFromJSON(raw string) (map[string]string, error)
- func KafkaTopicCommand(operation, topic string) (string, error)
- func ListMongoCollections(ctx context.Context, client *connpool.MongoClientCloser, database string) ([]string, error)
- func ListMongoDatabases(ctx context.Context, client *connpool.MongoClientCloser) ([]string, error)
- func NormalizeKafkaOperation(operation, fallback string) string
- func NormalizeTransferPath(adapter TransferAdapter, p string) string
- func ParseTransferEndpoint(ctx context.Context, s string, resolve ResolveAssetFunc) (asset *asset_entity.Asset, path string, err error)
- func PrecheckSerialSession(ctx context.Context, asset *asset_entity.Asset) error
- func RegisterTransferAdapter(assetType string, a TransferAdapter)
- func ResolveTransferPath(ctx context.Context, adapter TransferAdapter, asset *asset_entity.Asset, ...) (string, error)
- func RunSSHCommand(ctx context.Context, client *ssh.Client, command string) (string, error)
- func SameAssetCopyHint(adapter TransferAdapter, assetName string) string
- func WithDatabaseCache(ctx context.Context, cache *DatabaseClientCache) context.Context
- func WithKafkaService(ctx context.Context, svc *kafka_svc.Service) context.Context
- func WithLocalWriteGate(ctx context.Context, gate LocalWriteGate) context.Context
- func WithMongoDBCache(ctx context.Context, cache *MongoDBClientCache) context.Context
- func WithRedisCache(ctx context.Context, cache *RedisClientCache) context.Context
- func WithSFTPClientCache(ctx context.Context, cache *SFTPClientCache) context.Context
- func WithSSHCache(ctx context.Context, cache *SSHClientCache) context.Context
- func WithSSHClientSet(ctx context.Context, set *SSHClientSet) context.Context
- func WithSSHPool(ctx context.Context, pool *sshpool.Pool) context.Context
- func WithSerialManager(ctx context.Context, mgr serial_svc.CommandManager) context.Context
- func WithTransferWriteScope(ctx context.Context, scope string) context.Context
- type AIPoolDialer
- type ApprovalTarget
- type ConnCache
- type DatabaseClientCache
- type Direction
- type Entry
- type K8sCommandPlan
- type KafkaCommand
- type KeyedConnCache
- type ListResult
- type LocalWriteGate
- type MongoCommand
- type MongoDBClientCache
- type OSSCommand
- type PlannedTransferSource
- type RedisClientCache
- type RedisNodeRequiredError
- type ResolveAssetFunc
- type SFTPClientCache
- type SSHClientCache
- type SSHClientSet
- type TransferAdapter
- type TransferApprovalPlanner
- type TransferCapabilities
- type TransferPathNormalizer
- type TransferPathResolver
- type TransferPlan
Constants ¶
const MaxTransferEntries = 100_000
MaxTransferEntries 是执行资源边界,不是审批弹窗上限。目录范围只审批一次,但单次任务不能 无界物化整棵文件树;达到该值时在开始传输前明确失败。
Variables ¶
This section is empty.
Functions ¶
func ApplyRedisScope ¶ added in v1.15.0
func ApplyRedisScope(cfg *asset_entity.RedisConfig, scope string) error
ApplyRedisScope 把 scope 落到连接配置上:单机 / 哨兵时 scope 是库号,非空时覆盖 资产默认库;集群时 scope 是节点地址,不影响连接,由执行时的路由处理。
func ArgOptionalPartition ¶
ArgOptionalPartition parses the optional --partition flag of the "message" commands.
func CanonicalizeEtcdCommand ¶ added in v1.11.2
func CanonicalizeEtcdCommand(_ *asset_entity.Asset, command string) (string, error)
CanonicalizeEtcdCommand normalizes a model-provided command into the form used for policy matching, approval display, and audit logging: a round trip through ParseCommand + FormatCommand, which normalizes case, compound-op spelling, and flag order.
This must run before the permission check (see the ordering comment on handleExec in internal/ai/tool/tool_handlers_unified.go): a syntactically invalid command will always fail execution, so it must fail here — before an approval dialog can appear — rather than after the user has already been interrupted and approved a command that then fails to parse.
func CanonicalizeKafkaCommand ¶ added in v1.11.2
func CanonicalizeKafkaCommand(_ *asset_entity.Asset, command string) (string, error)
CanonicalizeKafkaCommand 把模型给的富命令串规范化为策略层的双 token 串 "<action> <resource>"——与已删除的 7 个 kafka_* 工具逐字节相同的形式(用户库里 存着的 CmdPolicy 与 grant 都是照那个形式写的,不能变),理由见 KafkaCommand.PolicyString 的注释。
排在权限检查之前(handleExec 的顺序,见 internal/ai/tool/tool_handlers_unified.go): 语法错误、未知 flag、缺必填 flag 都必然导致执行失败,必须在弹审批对话框之前失败, 否则用户先被打断批准一次(选 "allow all" 还会落一条常驻 grant),命令才失败。
func CanonicalizeMongoCommand ¶ added in v1.11.2
func CanonicalizeMongoCommand(asset *asset_entity.Asset, command string) (string, error)
CanonicalizeMongoCommand 把模型给的命令规范化为"真正会被执行、也应被策略匹配"的 形式:解析 + 注入资产默认库 + Render。
输出是完整命令串而不是裸 operation token:审批弹窗、策略匹配与审计看到的都是它, 而 `deleteMany logs` 与 `deleteMany logs --query='{"filter":{"level":"debug"}}'` 是完全不同的两件事(前者清空整个集合,internal/ai/helper/mongodb_helper.go 里 filter 为空时默认成 bson.D{})——只显示 "deleteMany" 的弹窗无法让用户区分。 策略侧因此改用 op 感知的 policy.MatchMongoRule,裸 op 规则照样命中富命令串。
排在权限检查之前(handleExec 的顺序,见 internal/ai/tool/tool_handlers_unified.go): 语法错误必然导致执行失败,必须在弹审批对话框之前失败。
func CanonicalizeOSSCommand ¶ added in v1.12.0
func CanonicalizeOSSCommand(_ *asset_entity.Asset, command string) (string, error)
CanonicalizeOSSCommand 把模型给的命令规范化为**规范 DSL 串**(决策 D6):审批弹窗与 audit_logs.command 展示的就是它,而策略与 grant 匹配用的是 PolicyStrings() 派生出的 两段串(OSS 一条命令可派生 1~3 条,单串承载不了)。
它同时是 exec 面唯一的输入闸门,两件事都排在权限检查之前(handleExec 的顺序是 canonicalize → precheck → 权限检查):
- 语法错误、未知 flag、缺必填 flag、相对 --file 都必然导致执行失败,必须在弹审批 对话框之前失败,否则用户先被打断批准一次(选"始终允许"还会落一条常驻 grant), 命令才失败;
- **策略串形状的输入被挡在这里**。permission.checkOSSPermission 靠"首词含 '.'"区分 "已派生的策略串"(cp 的端点主体、用户手写的 pattern)与"DSL 命令",因此一条 `object.read mybucket/*` 从 exec 面递进去会绕过 DSL 解析器直接参与规则匹配, 撞上一条整桶 allow 就被判成 Allow 并落成 grant,之后才在执行器里因为解析不了而失败。 ParseOSSCommand 只认 bucket / object 两个 family,`object.read` 在这里就报错。
func ClosersAsOne ¶
ClosersAsOne 将多个 closer 打包成单个 io.Closer(用于只接受单 closer 的 API,如 ConnCache)。
func DialAssetSSH ¶
DialAssetSSH 建立到资产的 SSH 连接,返回 client 与一次性清理函数。 底层委托给 credential_resolver.DialAssetSSH,统一支持 SOCKS5/HTTP 代理与跳板机链。 调用方必须在使用结束后调用返回的 cleanup,一并关闭 client 与跳板机链上的中间连接。
func DialSSHClient ¶
DialSSHClient 创建 SSH 客户端连接,自动解析凭据、代理、跳板机链。 调用者必须调用返回的 cleanup 关闭 client 与链路资源。
func ExecCommandOnAsset ¶ added in v1.11.2
func ExecCommandOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
ExecCommandOnAsset 是不含权限检查的纯执行入口:权限检查由调用方(统一 exec 工具的 handleExec、batch_exec 的预检)在调用之前完成。scope 对 SSH 无意义,忽略。
func ExecEtcdOnAsset ¶ added in v1.11.2
func ExecEtcdOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
ExecEtcdOnAsset is the permission-check-free execution entry point used by the unified exec tool — the only path to etcd since the exec_etcd tool was deleted. scope is meaningless for etcd and is ignored.
func ExecK8sOnAsset ¶ added in v1.11.2
func ExecK8sOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
ExecK8sOnAsset 是不含权限检查的纯执行入口,供统一 exec 使用。 统一 exec 的 canonicalizeK8sCommand(internal/ai/execimpl)先算一次同样的 plan,两条路径 共用同一执行体。command 是原始 kubectl 命令;scope 对 k8s 无意义,忽略。
注意:cfg 与 plan 在这里会被重新计算一次——调用方(canonicalizeK8sCommand)为了权限检查 已经算过一次 EffectiveCommand,但 ExecFunc 的签名只接受 (ctx, asset, command, scope),没有位置传入已算好的 plan,所以这里必须以同一份 BuildK8sCommandPlan 重新推导 Args。两处调用的是同一个函数,不构成第二份实现。
func ExecKafkaOnAsset ¶ added in v1.11.2
func ExecKafkaOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
ExecKafkaOnAsset is the permission-check-free execution entry point used by the unified exec tool — the only path to Kafka now that the seven kafka_* tools and their in-handler permission checks are gone. handleExec checks permission before calling it. scope is meaningless for Kafka and is ignored — the target resource is named by the command's target position (see internal/ai/skills/kafka/SKILL.md).
分派到既有的 HandleKafka* 而不是直连 kafka_svc:那 7 个函数里的 operation 分派、 kafka_args.go 的 ~20 个 *RequestFromArgs、结果序列化都已写好且有测试,重写一遍 就是 AGENTS.md 说的第二份实现。
func ExecMongoOnAsset ¶ added in v1.11.2
func ExecMongoOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
ExecMongoOnAsset is the permission-check-free execution entry point used by the unified exec tool — the only path to MongoDB since the exec_mongo tool was deleted. scope is meaningless for MongoDB and is ignored — the database is named by the command's --db flag (see internal/ai/skills/mongodb/SKILL.md).
func ExecOSSOnAsset ¶ added in v1.12.0
func ExecOSSOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
ExecOSSOnAsset is the permission-check-free execution entry point used by the unified exec tool; handleExec checks permission before calling it. scope is meaningless for object storage and is ignored — the target position names bucket and key (see internal/ai/skills/oss/SKILL.md).
分派到 oss_svc 而不是直连 minio:凭据解析、连接池与分页/移动语义都在 service 层写好 且有测试,重写一遍就是 AGENTS.md 说的第二份实现。
func ExecRedisOnAsset ¶ added in v1.11.2
func ExecRedisOnAsset(ctx context.Context, asset *asset_entity.Asset, command, scope string) (string, error)
ExecRedisOnAsset 是不含权限检查的纯执行入口:权限检查由调用方(统一 exec 工具的 handleExec、batch_exec 的预检)在调用之前完成,这里只负责连接与执行。 scope:单机 / 哨兵为库号(空 = 资产默认库);集群为节点 host:port(见 ExecuteRedisRaw)。
func ExecSQLOnAsset ¶ added in v1.11.2
func ExecSQLOnAsset(ctx context.Context, asset *asset_entity.Asset, sqlText, scope string) (string, error)
ExecSQLOnAsset 是不含权限检查的纯执行入口:权限检查由调用方(统一 exec 工具的 handleExec、batch_exec 的预检)在调用之前完成,这里只负责连接与执行——两者都经资产 配置的驱动。scope 非空时覆盖资产默认配置的数据库名。
func ExecSerialOnAsset ¶ added in v1.11.2
func ExecSerialOnAsset(ctx context.Context, asset *asset_entity.Asset, command, _ string) (string, error)
ExecSerialOnAsset 是不含权限检查的纯执行入口:权限检查由统一 exec 工具的 handleExec 在调用之前完成(会话是否存在则由 PrecheckSerialSession 更早地挡下)。 scope 对串口无意义,忽略。
func ExecWithStdio ¶
func ExecWithStdio(ctx context.Context, assetID int64, command string, stdin io.Reader, stdout, stderr io.Writer) error
ExecWithStdio 在远程服务器执行命令,直接连接 stdio(支持管道)。ctx 带有 SSHClientSet 时复用其中该资产的连接(不关闭),否则一次性拨号。
func ExecuteK8sCommandLocal ¶ added in v1.11.2
ExecuteK8sCommandLocal 在本机执行 kubectl(要求本机已安装 kubectl)。
func ExecuteMongoDB ¶
func ExecuteMongoDB(ctx context.Context, client *connpool.MongoClientCloser, database, collection, operation, query string) (string, error)
ExecuteMongoDB 执行 MongoDB 操作并返回 JSON 结果
func ExecuteRedis ¶
func ExecuteRedis(ctx context.Context, client redis.UniversalClient, command, scope string) (string, error)
ExecuteRedis 执行 Redis 命令(按空白切分)并返回 JSON 结果,scope 语义同 ExecuteRedisRaw。
func ExecuteRedisRaw ¶
func ExecuteRedisRaw(ctx context.Context, client redis.UniversalClient, args []string, scope string) (string, error)
ExecuteRedisRaw 使用预拆分的参数执行 Redis 命令(支持含空格的值)并返回 JSON 结果。 单机 / 哨兵:库号已在建连时由 ApplyRedisScope 生效,这里直接执行。 集群:按命令路由(见 execClusterArgs),scope 是节点 host:port,结果注明执行节点。
func ExecuteSQL ¶
ExecuteSQL 在会话上执行 SQL 并返回 JSON 结果。执行失败时原样返回驱动的错误。
func ExecuteSQLPaged ¶
func ExecuteSQLPaged(ctx context.Context, session dbdriver.Session, sqlText string, page, pageSize int) (string, error)
ExecuteSQLPaged 在会话上分页执行 SQL 并返回 JSON 结果。page 从 0 起。怎么分页、怎么 计数由驱动决定;驱动没有分页的语句(非查询等)结果里不带 total_count。
func ExecuteSSHCommand ¶
ExecuteSSHCommand 执行一次性 SSH 命令并返回输出(每次新建连接)
func ExecuteWithSFTP ¶
ExecuteWithSFTP 在 context 带任务级 SFTP cache 时复用该资产的会话;普通调用保持一次性 SSH+SFTP 连接语义。 ctx 取消时主动关闭底层连接以打断 fn 内部可能的 io.Copy 阻塞, 从而让 AI 停止会话能立即生效(否则大文件传输会挂住 runner.Stop)。
func HandleKafkaCluster ¶
func HandleKafkaConnect ¶
func HandleKafkaMessage ¶
func HandleKafkaSchema ¶
func HandleKafkaTopic ¶
func HasGlobPattern ¶ added in v1.12.0
HasGlobPattern 是 hasGlobMeta 的导出面,供入口层按 spec §6.5 判"多源形态"。 导出而不是让调用方自己写一遍 strings.ContainsAny:判形态与展开必须用同一份元字符 定义,否则会出现"按单源审批、按多源展开"这种两边对不上的传输。
func IsExpectedCloseErr ¶
IsExpectedCloseErr 判断 SSH/网络连接关闭时的预期错误。 取消路径会主动 Close session/client 打断阻塞,随后的 defer 关闭就会返回这些错误; 归类为预期错误后,上层可以跳过 warn 日志,避免噪音。
func KafkaACLCommand ¶
func KafkaClusterCommand ¶
KafkaClusterCommand 将 cluster family 的 operation 映射为策略命令字符串。
func KafkaConnectCommand ¶
func KafkaCreateACLRequestFromArgs ¶
func KafkaCreateACLRequestFromArgs(assetID int64, args map[string]any) kafka_svc.CreateACLRequest
func KafkaDeleteACLRequestFromArgs ¶
func KafkaDeleteACLRequestFromArgs(assetID int64, args map[string]any) kafka_svc.DeleteACLRequest
func KafkaDeleteSchemaRequestFromArgs ¶
func KafkaDeleteSchemaRequestFromArgs(assetID int64, args map[string]any) kafka_svc.DeleteSchemaRequest
func KafkaInt32SliceFromJSON ¶
func KafkaListACLsRequestFromArgs ¶
func KafkaListACLsRequestFromArgs(assetID int64, args map[string]any) kafka_svc.ListACLsRequest
func KafkaMessageCommand ¶
func KafkaProduceHeadersFromArgs ¶
func KafkaProduceHeadersFromArgs(args map[string]any) ([]kafka_svc.ProduceMessageHeader, error)
func KafkaRestartConnectorRequestFromArgs ¶
func KafkaRestartConnectorRequestFromArgs(assetID int64, args map[string]any) kafka_svc.RestartConnectorRequest
func KafkaSchemaCommand ¶
func KafkaSchemaReferencesFromJSON ¶
func KafkaSchemaReferencesFromJSON(raw string) ([]kafka_svc.SchemaReference, error)
func KafkaTopicCommand ¶
func ListMongoCollections ¶
func ListMongoCollections(ctx context.Context, client *connpool.MongoClientCloser, database string) ([]string, error)
ListMongoCollections 列出指定 MongoDB 资产指定数据库的所有集合名称。
func ListMongoDatabases ¶
ListMongoDatabases 列出指定 MongoDB 资产的所有数据库名称。 v1/v2 按连接模式自动分流,逻辑(含错误信息)由两个驱动共享。
func NormalizeKafkaOperation ¶
func NormalizeTransferPath ¶ added in v1.12.0
func NormalizeTransferPath(adapter TransferAdapter, p string) string
NormalizeTransferPath 通过适配器能力规范化端点路径;没有该能力的适配器保持原值。
func ParseTransferEndpoint ¶ added in v1.12.0
func ParseTransferEndpoint( ctx context.Context, s string, resolve ResolveAssetFunc, ) (asset *asset_entity.Asset, path string, err error)
ParseTransferEndpoint 解析 cp 的一端:"<asset>:<path>",AI cp 工具与 opsctl cp 共用。 只按第一个冒号切,其后整段都是该资产上的路径(路径里可以再有冒号)。
无冒号、或冒号前为空(":foo")一律是本地路径:asset 为 nil、path 是原串,且不做任何资产 查询。Windows 上带盘符的路径("C:\windows"、"C:/Users/me")同样是本地路径、不查资产: 盘符和单字母资产名写法相同,本地路径优先,单字母名称的资产在 Windows 上要用资产 ID 指定。 否则冒号后必须以 "/" 开头,或是 SSH 支持的 "~" / "~/...",才算远端路径。 home 语法在适配器接线后解析,解析出的绝对路径才进入审批与 I/O。
D15 守卫(spec §6.2 / §11):冒号后不以 "/" 开头、但前缀确实解析成了一个资产时报错, 明示正确写法 "<asset>:/<path>",而不是静默回落成本地路径——写错的远端路径不该变成一句 对着磁盘上某个字面路径的"文件不存在"。
func PrecheckSerialSession ¶ added in v1.11.2
func PrecheckSerialSession(ctx context.Context, asset *asset_entity.Asset) error
PrecheckSerialSession 是给统一 exec 注册的 permission.PrecheckFunc:把"会话是否 存在"的检查挪到权限检查之前,让统一 exec 对一个没有活跃会话的串口资产直接失败 ——不弹审批对话框。
这正是 canonicalizeK8sCommand(internal/ai/execimpl/register.go)解决的同一类问题: 该检查无副作用,必须排在 CheckForAsset(可能弹审批对话框并阻塞等待用户响应)之前, 否则用户会先被弹一次审批,批准之后命令才因为没有会话而失败。串口没有可规范化的 命令,所以是 precheck 而不是 canonicalize。
func RegisterTransferAdapter ¶ added in v1.12.0
func RegisterTransferAdapter(assetType string, a TransferAdapter)
RegisterTransferAdapter 注册某资产类型的传输适配器,由持有该协议的实现在 init() 中调用。 重复注册 panic——与 permission.RegisterExecutor 一致,注册冲突是启动期的编程错误, 不该静默覆盖。
func ResolveTransferPath ¶ added in v1.12.0
func ResolveTransferPath( ctx context.Context, adapter TransferAdapter, asset *asset_entity.Asset, p string, ) (string, error)
ResolveTransferPath 在审批主体生成之前解析端点路径,确保批准的路径就是实际传输的路径。
func RunSSHCommand ¶
RunSSHCommand 在已有的 SSH 客户端上执行命令
func SameAssetCopyHint ¶ added in v1.12.0
func SameAssetCopyHint(adapter TransferAdapter, assetName string) string
func WithDatabaseCache ¶
func WithDatabaseCache(ctx context.Context, cache *DatabaseClientCache) context.Context
WithDatabaseCache 将数据库缓存注入 context
func WithKafkaService ¶
WithKafkaService 将 Kafka 服务注入 context,让 AI handler 在同一次 AI Send 内复用 franz-go client(避免每次工具调用都重新 dial+ping)。
func WithLocalWriteGate ¶ added in v1.12.0
func WithLocalWriteGate(ctx context.Context, gate LocalWriteGate) context.Context
WithLocalWriteGate 把本地写门禁注入 ctx。由 internal/app/ai 在每次 Send 时注入同一个 LocalToolGate 实例 —— 白名单按 convID 分片,因此"本次会话允许"在两条路上是同一件事。
func WithMongoDBCache ¶
func WithMongoDBCache(ctx context.Context, cache *MongoDBClientCache) context.Context
WithMongoDBCache 将 MongoDB 缓存注入 context
func WithRedisCache ¶
func WithRedisCache(ctx context.Context, cache *RedisClientCache) context.Context
WithRedisCache 将 Redis 缓存注入 context
func WithSFTPClientCache ¶ added in v1.12.0
func WithSFTPClientCache(ctx context.Context, cache *SFTPClientCache) context.Context
WithSFTPClientCache 把任务级 SFTP cache 注入传输调用链。
func WithSSHCache ¶ added in v1.11.2
func WithSSHCache(ctx context.Context, cache *SSHClientCache) context.Context
WithSSHCache 将 SSH 缓存注入 context。
func WithSSHClientSet ¶ added in v1.14.0
func WithSSHClientSet(ctx context.Context, set *SSHClientSet) context.Context
WithSSHClientSet 把连接集合注入 ctx,供 ExecWithStdio 复用。
func WithSSHPool ¶
WithSSHPool 将 SSH 连接池注入 context(供 connpool 隧道使用)
func WithSerialManager ¶
func WithSerialManager(ctx context.Context, mgr serial_svc.CommandManager) context.Context
WithSerialManager 将串口管理器注入 context
Types ¶
type AIPoolDialer ¶
type AIPoolDialer struct{}
AIPoolDialer 实现 sshpool.PoolDialer,委托给 credential_resolver 统一 dial
type ApprovalTarget ¶ added in v1.12.0
ApprovalTarget 是一个端点操作必须同时满足的单条授权。通常只有一条;SSH 的 `-r path` 在审批前不能探测 path 是文件还是目录,因此同时要求精确路径与子树范围。
func ApprovalSubjectsFor ¶ added in v1.12.0
func ApprovalSubjectsFor(adapter TransferAdapter, p string, dir Direction) []ApprovalTarget
ApprovalSubjectsFor 返回该端点操作全部必须授权的主体。
type DatabaseClientCache ¶
DatabaseClientCache 在同一次 AI Send 中复用数据库会话
func NewDatabaseClientCache ¶
func NewDatabaseClientCache() *DatabaseClientCache
NewDatabaseClientCache 创建数据库会话缓存
type Direction ¶ added in v1.12.0
type Direction int
Direction 是端点在一次传输里被使用的方向。展开(DirList)自己也是一个方向:枚举读的是 元数据而不是内容,但 `cp -r web-01:/ ./x` 能把整棵文件树的结构拖出来,所以它同样要授权。
type Entry ¶ added in v1.12.0
type Entry struct {
// Path 是该端点上的完整路径 / 对象 key,直接交给 OpenRead / Write。
Path string
// RelPath 相对展开基点,决定它在目的端的落点:目的路径 = <dst 基点> + RelPath。
// 基点按形态取:单个文件是它所在目录,glob 是通配前的最后一层目录,递归是源目录自身。
// 始终以 "/" 分隔,跨端点拼接才不会带上本地平台的分隔符。
RelPath string
Size int64
}
Entry 是一次展开产出的单个可传输条目。只有文件/对象,没有目录——目录由 RelPath 隐含, 目的端在写入时按需创建。
type K8sCommandPlan ¶ added in v1.11.2
K8sCommandPlan 是解析、补全默认 context/namespace 之后的 kubectl 调用计划。 EffectiveCommand 用于权限检查展示实际执行的命令;Args 用于实际执行。
func BuildK8sCommandPlan ¶ added in v1.11.2
func BuildK8sCommandPlan(rawCommand string, cfg *asset_entity.K8sConfig) (*K8sCommandPlan, error)
BuildK8sCommandPlan 解析一条 kubectl 命令并按需注入默认 context/namespace。 供权限检查(需要 EffectiveCommand)与 ExecK8sOnAsset(需要 Args)共用。
type KafkaCommand ¶ added in v1.11.2
KafkaCommand 是 kafka 富命令串的结构形式。
格式:`<family> <verb> [target] [--flags]`
family 对应已删除的 7 个 kafka_* 工具,verb 对应各工具的 operation 参数, target 是资源名(topic / group / subject / connector),flags 承载其余全部参数。 之所以让 family 占 Verb 位、verb 退到第一个 positional:cmdline 只认"第一个词是 动词"这一条词法规则,kafka 的资源维度比其他类型多一层,把 family 放在最前面 才能让 `topic delete orders` 读起来仍然是命令行的样子。
func ParseKafkaCommand ¶ added in v1.11.2
func ParseKafkaCommand(s string) (*KafkaCommand, error)
ParseKafkaCommand 解析富命令串。
func (*KafkaCommand) PolicyString ¶ added in v1.11.2
func (c *KafkaCommand) PolicyString() (string, error)
PolicyString 返回策略匹配用的 "<action> <resource>" 串。
**必须**恰好两个 token,且与已删除的 7 个 kafka_* 工具的输出逐字节相同——所以这里 直接复用现有的 Kafka*Command 函数(internal/ai/helper/kafka_command.go),不重写一遍。 理由见 TestKafkaCommand_PolicyStringIsUnchangedTwoTokenForm 的注释: splitKafkaRule 要求恰好 2 段,不满足时 MatchKafkaRule 静默返回 false, 于是 BuiltinKafkaDangerousDeny 的 deny 规则不再匹配任何命令(fail-open)。
后置条件(结果必须恰好 2 个 Fields)不是可有可无的防御性代码,别顺手删: ParseKafkaCommand 的 validateKafkaTarget 只守住"解析命令串"这一条路,而 KafkaCommand 是导出结构体,统一 exec 会从结构化的工具参数直接构造它(mongo 侧 opsctl batch 的 mongo 类型条目就是这么做的,见 cmd/opsctl/command/batch.go 的 executeBatchItem)、 完全绕开解析。这条后置条件是那条缝上唯一的守卫,而这条缝一旦破了 是静默的——不满足 2-token 时 splitKafkaRule 返回 ok=false,deny 规则一条都不匹配。 宁可在这里 fail closed 报错,也不能把一个匹配不上任何规则的串交出去。
func (*KafkaCommand) Render ¶ added in v1.11.2
func (c *KafkaCommand) Render() (string, error)
Render 是 ParseKafkaCommand 的逆函数(TestKafkaCommand_RoundTrip 锁住)。
拒绝以 "--" 开头的 Target,理由与 MongoCommand.Render 拒绝同形 Collection 完全一致 (见该函数注释):cmdline.Parse 判断 positional 还是 flag,看的是**剥掉引号之后**的 词是否以 "--" 开头(internal/ai/cmdline/cmdline.go:162),判断发生在引号信息已经 丢失之后,所以加引号救不了。ParseKafkaCommand 自己永远产不出这种 Target,但 KafkaCommand 是导出结构体,统一 exec 会用结构化的工具参数直接构造它、绕开 Parse—— 拒绝好过悄悄产出一个 Render 完语义就变了的串。 同理还要校验 flag 名:cmdline.Command.Render 明说手写字面量不受 Parse 的入口校验 保护、由调用方保证 flag 名合法,KafkaCommand.Render 就是那个调用方。mongo 靠写死 db / query 两个 flag 名绕开了这件事,kafka 接受任意 flag 名,绕不开—— `{"cfg=x": "1"}` 渲染成 `--cfg=x=1`,重新解析后是 flag "cfg" 值 "x=1"。 判定复用 cmdline.ValidFlagName,不在这里重抄一份 safeUnquotedWord。
type KeyedConnCache ¶ added in v1.15.0
type KeyedConnCache[K comparable, C io.Closer] struct { // contains filtered or unexported fields }
KeyedConnCache 泛型连接缓存,在同一次 AI Send 中复用连接,按 K 区分连接 (多数类型按资产 ID;连接级参数会改变连接本身时,K 需包含该参数,如 Redis 的库号)。 并发模型:mu 保护 maps;sf 保证同一 key 并发首拨只发生一次(second waiter 拿到 first dialer 的结果),batch_exec 多条命令并发命中同资产时只握手一次。
func NewKeyedConnCache ¶ added in v1.15.0
func NewKeyedConnCache[K comparable, C io.Closer](name string) *KeyedConnCache[K, C]
NewKeyedConnCache 创建按 K 区分的连接缓存
func (*KeyedConnCache[K, C]) Close ¶ added in v1.15.0
func (c *KeyedConnCache[K, C]) Close() error
Close 关闭所有缓存的连接
func (*KeyedConnCache[K, C]) Forget ¶ added in v1.15.0
func (c *KeyedConnCache[K, C]) Forget(key K)
Forget 仅把 key 对应的连接从缓存中摘除,但不主动调用 Close。 用于 client 已被上游提前关闭(例如 RunSSHCommand 在 ctx 取消时已 Close)的场景, 避免 Remove 触发二次 Close 及伴随的预期关闭错误日志。
func (*KeyedConnCache[K, C]) GetOrDial ¶ added in v1.15.0
func (c *KeyedConnCache[K, C]) GetOrDial(key K, dial func() (C, io.Closer, error)) (C, io.Closer, error)
GetOrDial 从缓存获取连接,不存在则通过 dial 创建并缓存。 返回的 closer 始终为 nil —— 缓存命中或新拨号都由 cache 持有 closer, 调用方不需要也不应该 Close 这个连接(应通过 Remove/Forget/Close 释放)。
并发安全:同一 key 的并发首拨经 singleflight 合流为一次 dial,second waiter 直接拿到 first dialer 的 client;不同 key 完全并行。
func (*KeyedConnCache[K, C]) Remove ¶ added in v1.15.0
func (c *KeyedConnCache[K, C]) Remove(key K)
Remove 关闭并移除指定 key 的缓存连接
type ListResult ¶ added in v1.12.0
ListResult 是一次展开的全部产出。跳过的符号链接与 Entries 分开返回,因为它们不是可传输 条目,却必须原样报给用户——静默跳过就成了一次看起来完整、实际残缺的传输。
type LocalWriteGate ¶ added in v1.12.0
type LocalWriteGate interface {
// CheckLocalWrites 让一批本地写路径过一次 local_write 门禁:返回 nil 即放行,
// 非 nil 是拒绝理由(可直接回给模型)。paths 必须非空。
CheckLocalWrites(ctx context.Context, paths []string, detail string) error
}
LocalWriteGate 是"一次本地写要先过 local_write 门禁"的接缝。
实现是 internal/ai/tool.LocalToolGate —— 模型直接调用 local_write 工具时走的就是它, 两条路共用同一份会话白名单、同一个对话框、同一套 pattern 语义。接口留在本包,是因为 被它保护的那个原语(localAdapter.Write:MkdirAll + os.Create + io.Copy)就在本包, 而 helper 不能反向 import tool。
**它不是通用的本地写检查**:本地端点照旧不产生审批项(spec §6.2)。它只补 D11 的前提 不成立的那一档 —— D11 说"本地路径由用户批准的那条命令串完全决定",而当两端都被策略/ grant 自动放行时,压根没有"用户批准的那条串",于是本地写需要另一道门。
func RequireLocalWriteGate ¶ added in v1.12.0
func RequireLocalWriteGate(ctx context.Context) (LocalWriteGate, error)
RequireLocalWriteGate 取出本地写门禁,缺失即报错 —— 不放行。
与 permission.RequireChecker 同一条理由(#249):把"注入缺失"写成放行,漏接线就等于 没有门禁。而调用方走到这里时,恰恰是"这次操作一个弹框都没有过"的场合,它是仅剩的那道门。
type MongoCommand ¶ added in v1.11.2
MongoCommand 是 mongo 富命令串的结构形式。
格式:`<op> [collection] [--db=<database>] [--query=<json>]`
之所以让 collection 走 positional、database 走 flag:collection 是几乎每次调用 都要给的字段,正好也是最自然的 positional 用法。database 在**这一层**没有默认值: mongoFind 等执行函数(internal/ai/helper/mongodb_helper.go:212 及同类)在 database 为空时直接报错。资产的 MongoDBConfig.Database 由上一层的 resolveMongoCommand (internal/ai/helper/mongo_exec.go)注入,规范化与执行两条路径共用它——本文件只做 词法,不碰资产。
func ParseMongoCommand ¶ added in v1.11.2
func ParseMongoCommand(s string) (*MongoCommand, error)
ParseMongoCommand 解析富命令串。
func (*MongoCommand) Render ¶ added in v1.11.2
func (c *MongoCommand) Render() (string, error)
Render 是 ParseMongoCommand 的逆函数(TestMongoCommand_RoundTrip 锁住)。
拒绝以 "--" 开头的 Collection。cmdline.Parse 只看词本身(Words 已经剥掉引号 之后)是否以 "--" 开头来判断它是 positional 还是 flag (internal/ai/cmdline/cmdline.go:162)——这个判断发生在引号信息已经丢失之后, 所以给 "--db=evil" 加引号并不能让它安全地回代成一个 positional:Render 出来的 串重新解析后,"--db=evil" 依然会被当成 --db=evil 这个 flag(Collection 变成 空字符串),单独一个 "--" 会被当成格式错误的 flag("malformed flag: --")。 这属于 cmdline 引号策略"位置无关"的已知局限,在 Verb 侧也有同样的记录 (internal/ai/cmdline/cmdline.go:184-192),这里不重新设计 cmdline 的引号规则, 只在 mongo 这一层堵住它:ParseMongoCommand 产出的 Collection 永远不会以 "--" 开头(这种词在解析阶段就被当 flag 吃掉了),但 MongoCommand 是导出结构体, 统一 exec 那边会用结构化的 collection 工具参数直接构造它,绕开 Parse—— 拒绝好过悄悄产出一个 Render 完语义就变了的串。
type MongoDBClientCache ¶
type MongoDBClientCache = ConnCache[*connpool.MongoClientCloser]
MongoDBClientCache 在同一次 AI Send 中复用 MongoDB 连接
func NewMongoDBClientCache ¶
func NewMongoDBClientCache() *MongoDBClientCache
NewMongoDBClientCache 创建 MongoDB 连接缓存
type OSSCommand ¶ added in v1.12.0
OSSCommand 是对象存储富命令串的结构形式。
格式:`<family> <verb> [target] [--flags]`,与 KafkaCommand 同形(family 占 Verb 位、 verb 退到第一个 positional),因为 cmdline 只认"第一个词是动词"这一条词法规则, 而对象存储同样有 bucket / object 两层资源维度。
Target 是 `<bucket>[/<key-or-prefix>]`;OSS 侧一条命令可能派生多条策略串 (copy 两条、move 三条),所以对外是 PolicyStrings 而不是 kafka 的单串 PolicyString。
func ParseOSSCommand ¶ added in v1.12.0
func ParseOSSCommand(s string) (*OSSCommand, error)
ParseOSSCommand 解析富命令串。
func (*OSSCommand) PolicyStrings ¶ added in v1.12.0
func (c *OSSCommand) PolicyStrings() ([]string, error)
PolicyStrings 返回策略匹配用的 "<action> <resource>" 串,每条恰好两段。
copy / move 派生多条是本设计的核心安全点(决策 D7):只检查目的地就等于放行 "把受限对象复制到可读位置再读"的绕过路径。调用方要按"任一条被 deny 即整条命令被拒、 allow 名单存在时必须每条都命中才放行"来消费这个切片。
后置条件(每条都能被"第一段空白"切成两段)不是可有可无的防御性代码,别顺手删: ParseOSSCommand 的 target 校验只守住"解析命令串"这一条路,而 OSSCommand 是导出结构体, 统一 exec / opsctl batch 会从结构化参数直接构造它、完全绕开解析。这条后置条件是那条缝上 唯一的守卫,而这条缝一旦破了是**静默**的——切不出两段时匹配器对任何规则都返回 false, deny 规则一条都不匹配(fail-open),allow 名单侧则永远不放行。宁可在这里 fail closed 报错,也不能把一个匹配不上任何规则的串交出去。
func (*OSSCommand) Render ¶ added in v1.12.0
func (c *OSSCommand) Render() (string, error)
Render 是 ParseOSSCommand 的逆函数(TestOSSCommand_RoundTrip 锁住),也是审批弹窗与 审计行看到的展示态(决策 D6:规范形式是 DSL 串,匹配用派生出的策略串)。
拒绝以 "--" 开头的 Target,理由与 KafkaCommand.Render / MongoCommand.Render 完全一致: cmdline.Parse 判断 positional 还是 flag,看的是**剥掉引号之后**的词是否以 "--" 开头, 判断发生在引号信息已经丢失之后,所以加引号救不了。ParseOSSCommand 自己永远产不出 这种 Target,但 OSSCommand 是导出结构体,统一 exec 会用结构化的工具参数直接构造它、 绕开 Parse——拒绝好过悄悄产出一个 Render 完语义就变了的串。flag 名同理,判定复用 cmdline.ValidFlagName。
type PlannedTransferSource ¶ added in v1.12.0
PlannedTransferSource is the protocol-neutral shape of one cp source.
type RedisClientCache ¶
type RedisClientCache = KeyedConnCache[redisConnKey, redis.UniversalClient]
RedisClientCache 在同一次 AI Send 中复用 Redis 连接,按「资产 + 库」区分。
func NewRedisClientCache ¶
func NewRedisClientCache() *RedisClientCache
NewRedisClientCache 创建 Redis 连接缓存
type RedisNodeRequiredError ¶ added in v1.15.0
RedisNodeRequiredError 表示集群模式下一条不带 key 的命令没有指定有效节点:scope 缺省、 不是集群中的节点,或是一个库号。Masters 为当前主节点地址,供调用方(AI、opsctl、 桌面控制台)提示用户从中选择。用 errors.As 识别。
func (*RedisNodeRequiredError) Error ¶ added in v1.15.0
func (e *RedisNodeRequiredError) Error() string
type ResolveAssetFunc ¶ added in v1.12.0
ResolveAssetFunc 把 "<asset>:" 前缀解析成资产。由调用方注入:**共享的是语法,不是引用 解析策略**——opsctl 传自己的 resolveAsset(`cmd/opsctl/command/resolve.go`,支持 "组路径/名称" 消歧),AI 侧传 assetref.Resolve(数字 id 或精确名称)。两者在解析器上提 之前就已经不同,共享解析器不能替入口选一个。
解析不出资产时返回 error;ParseTransferEndpoint 只看 error 是否为 nil,不解读它的种类。
type SFTPClientCache ¶ added in v1.12.0
type SFTPClientCache struct {
// contains filtered or unexported fields
}
SFTPClientCache 在一次 cp 命令内按资产复用 SFTP 会话。
func EnsureSFTPClientCache ¶ added in v1.12.0
EnsureSFTPClientCache 复用已有 cache,或创建一个由调用方负责关闭的新 cache。 第三个返回值说明本次调用是否拥有新 cache。
func NewSFTPClientCache ¶ added in v1.12.0
func NewSFTPClientCache() *SFTPClientCache
NewSFTPClientCache 创建使用真实资产连接的任务级 SFTP cache。
func (*SFTPClientCache) Close ¶ added in v1.12.0
func (c *SFTPClientCache) Close() error
type SSHClientCache ¶ added in v1.11.2
SSHClientCache 在同一次 AI Send 中复用 SSH 连接。
func NewSSHClientCache ¶ added in v1.11.2
func NewSSHClientCache() *SSHClientCache
NewSSHClientCache 创建 SSH 客户端缓存。
type SSHClientSet ¶ added in v1.14.0
type SSHClientSet struct {
// contains filtered or unexported fields
}
SSHClientSet 在一次调用(如 opsctl batch)内按资产至多拨号一次:并发请求等待同一次 拨号,拨号失败(含 MFA 未通过 / 取消)被记住,后续请求直接拿到同一错误,不再对 同一资产发起第二次挑战。与 ConnCache 的区别正在于记住失败:一次性验证码不能重试。
func NewSSHClientSet ¶ added in v1.14.0
func NewSSHClientSet() *SSHClientSet
NewSSHClientSet 创建空集合;调用方负责 Close。
type TransferAdapter ¶ added in v1.12.0
type TransferAdapter interface {
// List 展开 pattern。pattern 含 glob 元字符(* ? [)时按 glob 展开;recursive 为真时
// 下钻目录树;单个具体文件/对象返回单元素切片。展开途中遇到的符号链接一律跳过并计入
// SkippedSymlinks——跟随会让 `cp -r ./dir` 因为一条指向 / 的链接变成整机 dump。
// 指名到一个目录却没有 recursive 时报错,不猜。
List(ctx context.Context, asset *asset_entity.Asset, pattern string, recursive bool) (*ListResult, error)
// OpenRead 打开该端点上的 path 用于读取;size 未知时返回 -1。返回的 ReadCloser 活过
// 本次调用,调用方负责 Close。
OpenRead(ctx context.Context, asset *asset_entity.Asset, path string) (io.ReadCloser, int64, error)
// Write 把 r 的内容写入该端点的 path,必要时创建中间目录;size 未知时传 -1。
Write(ctx context.Context, asset *asset_entity.Asset, path string, r io.Reader, size int64) error
// ValidateDestination 判断 path 能不能当这一端点的写入目标,只看形态、不碰网络。
//
// 它存在是因为目的端与源端不对称:源端的形态错误由 List 在展开时报出来,而目的端
// **不经过 List**(要写的东西还不存在),ApprovalSubject 又不能报错。没有这一关,
// 一个形态错误的目的地会带着一个错误的主体走完审批、到 Write 才失败——用户批准了
// 一件必然失败的事。与 handleExec 的排序不变式同源:无副作用的判断必须全部走完,
// 才能碰有副作用的那一步(审批弹窗)。
//
// 入参是**具体的**目的路径,即多源展开时 dst 基点拼上 RelPath 之后的结果——正是
// 会被审批、也会被写入的那个字符串,因此这里不需要知道是单源还是多源。
ValidateDestination(path string) error
// ApprovalSubject 返回这一端点在该方向上必须被授权的审批类型与匹配串。
//
// DirList 方向收到的是用户**指名的那个串**——可能是一个 pattern,也可能是一个前缀,
// 与 List 收到的完全相同。收窄成"实际会被枚举的那个基点"是适配器自己的事,调用方
// 不得先替它截一刀:哪些字符是通配语法只有适配器知道(对象存储的前缀形态 key 里
// `*?[` 是字面量,规则侧走的是 strings.HasPrefix),入口层按 glob 截断会让指名一个
// 前缀的递归传输换来整桶列举的授权。反过来,主体也绝不能是 pattern 原文:cp 的 grant
// 不分方向,一条 "/var/log/*.log" 的 grant 会连它命中的每个文件的读写一起授权。
//
// **一个端点有审批主体,当且仅当它有资产。** 本地端点没有资产,因此正确的调用方按
// asset 是否为 nil 来决定要不要走权限检查,压根不会问本地适配器要主体;它返回的空串是
// "不适用",不是一个让调用方去判空的哨兵——按哨兵写,漏判时就会静默放行。
ApprovalSubject(path string, dir Direction) (approvalType, subject string)
}
TransferAdapter 是一类传输端点的全部能力:怎么展开、怎么读写、以及在每个方向上要授权 什么。四件事放在同一个接口里,是为了不出现第二张"类型 → 审批语义"的表。
func TransferAdapterFor ¶ added in v1.12.0
func TransferAdapterFor(asset *asset_entity.Asset) (TransferAdapter, error)
TransferAdapterFor 返回该端点的适配器,与 ParseTransferEndpoint 的返回值配套: asset 为 nil 就是本地端点——它没有资产,因此不进注册表,由包级实现直接交出。 没有接进传输面的资产类型返回错误,而不是回落成本地。
type TransferApprovalPlanner ¶ added in v1.12.0
type TransferApprovalPlanner interface {
ApprovalSubjects(path string, dir Direction) []ApprovalTarget
}
TransferApprovalPlanner 是适配器的可选多主体授权能力。
type TransferCapabilities ¶ added in v1.12.0
TransferCapabilities 让入口询问适配器能力,不按资产类型或协议分支。
type TransferPathNormalizer ¶ added in v1.12.0
TransferPathNormalizer 是文件系统类适配器的可选能力。对象存储 key 是不透明名字,不能 用文件系统规则清理;本地与 SSH 则必须在审批、审计和 I/O 分叉之前归一成同一个路径。
type TransferPathResolver ¶ added in v1.12.0
type TransferPathResolver interface {
ResolveTransferPath(ctx context.Context, asset *asset_entity.Asset, path string) (string, error)
}
TransferPathResolver 把端点专属的路径缩写解析为审批和 I/O 共用的确定路径。 当前只有 SSH 的 "~" / "~/..." 需要这一步;对象存储 key 不具有 home 语义。
type TransferPlan ¶ added in v1.12.0
type TransferPlan struct {
Sources []PlannedTransferSource
Multiple bool
}
TransferPlan owns the shape rules shared by the AI and opsctl entrances.
func PlanTransfer ¶ added in v1.12.0
func PlanTransfer(sourcePaths []string, destination string, localDestination, recursive bool) (*TransferPlan, error)
PlanTransfer 判定传输形态。localDestination 表示目的端是本机路径:多源时目的端必须写成 目录,远端(POSIX 路径)以 "/" 结尾,本机路径还可以用本机的路径分隔符结尾(Windows 的 "\")。
Source Files
¶
- conn_cache.go
- database_helper.go
- etcd_exec.go
- etcd_helper.go
- flag_spec.go
- k8s_helper.go
- kafka_args.go
- kafka_command.go
- kafka_dsl.go
- kafka_exec.go
- kafka_helper.go
- local_write_gate.go
- mongo_command.go
- mongo_exec.go
- mongodb_exec.go
- mongodb_helper.go
- mongodb_v1.go
- mongodb_v2.go
- oss_dsl.go
- oss_exec.go
- redis_cluster.go
- redis_helper.go
- serial_helper.go
- ssh_helper.go
- transfer.go
- transfer_local.go
- transfer_oss.go
- transfer_path.go
- transfer_plan.go
- transfer_ssh.go