ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

如何为 Vault UI Secrets Sync 功能新增一种密钥引擎类型:挂载检测、类型配置与 fetcher 注册

如何为 Vault UI Secrets Sync 功能新增一种密钥引擎类型:挂载检测、类型配置与 fetcher 注册 如何为 Vault UI Secrets Sync 功能新增一种密钥引擎类型挂载检测、类型配置与 fetcher 注册【免费下载链接】vaultA tool for secrets management, encryption as a service, and privileged access management项目地址: https://gitcode.com/GitHub_Trending/va/vault如果你在开发 Vault UI需要让 Secrets Sync 功能支持一种新的密钥引擎当前只支持 KV v2 和 Database 静态角色凭证这篇文章给出完整的修改路径。Vault UI 的 Secrets Sync 采用挂载mount驱动的类型检测用户在选择挂载点的那一刻系统就自动判定密钥类型。整个体系是配置驱动的新增类型只需要改动类型定义、检测函数和两个注册表核心组件SuggestionInput、sync 页面不需要修改。完整说明见 secrets-sync-adding-new-types.md。动手前需要理解的机制与关键文件系统由以下部分组成新增类型时各自承担一个角色文件作用ui/types/vault/sync.d.tsSecretType联合类型和共享类型定义ui/lib/sync/addon/utils/secret-type-config.tsSECRET_TYPE_CONFIGS、getSecretTypeFromMount()、getSecretTypeFromAccessor()ui/lib/core/addon/utils/secret-type-fetchers.tsSECRET_TYPE_FETCHERS—— API 拉取、过滤与选中逻辑ui/lib/sync/addon/components/secrets/page/destinations/destination/sync.ts主 sync 组件 —— 挂载拉取与类型检测ui/lib/sync/addon/components/secrets/page/destinations/destination/sync.hbs含 HDS SuperSelect 与SuggestionInput的模板ui/lib/core/addon/components/suggestion-input.ts通用的建议输入组件ui/lib/sync/addon/components/secrets/secret-type-badge.ts带图标的引擎类型徽章两个检测函数分工不同都要处理缺一不可getSecretTypeFromMount(type, version)—— 用户从下拉框选择挂载时调用如果你的类型有特殊要求例如 KV 必须是 v2在这里判断。getSecretTypeFromAccessor(accessor)—— 展示已同步密钥时调用依据 API 返回的accessor字段如kv_9b39cc0f做前缀匹配。步骤 1扩展 SecretType 联合类型在 ui/types/vault/sync.d.ts 中把新类型加入SecretType联合。当前定义为export type SecretType kv | database;新增后your-new-type替换为你的类型标识export type SecretType kv | database | your-new-type;这一步会立即触发 TypeScript 的类型检查因为SECRET_TYPE_CONFIGS和SECRET_TYPE_FETCHERS都声明为RecordSecretType, ...两个注册表中缺少新类型的条目会直接报错。官方文档把这种强制补全称为该架构的Type Safe特性等于编译器替你检查是否漏改。步骤 2更新两个挂载检测函数在 ui/lib/sync/addon/utils/secret-type-config.ts 中补全两个函数。getSecretTypeFromMount现有逻辑KV 要求 version 2其余返回 nullexport function getSecretTypeFromMount(type: string, version?: number): SecretType | null { if (type kv) { return version 2 ? kv : null; // KV requires version 2 } if (type database) { return database; } // Add your new type — add a version check if needed if (type your-engine-type) { return your-new-type; } return null; }getSecretTypeFromAccessor按_拆出前缀做匹配export function getSecretTypeFromAccessor(accessor: string): SecretType | null { const prefix accessor.split(_)[0]; if (prefix kv || prefix database || prefix your-engine-type) return prefix; return null; }注意your-engine-type要与 Vault 端该引擎在挂载信息中返回的type值一致getSecretTypeFromAccessor中的前缀要与 API 返回的accessor字段前缀一致。改完getSecretTypeFromMount后挂载下拉框会自动纳入新引擎类型的挂载点——文档明确说明fetchMounts()靠这个函数过滤只要它对某引擎类型返回非 null该挂载就会出现无需再改 sync.ts见步骤 6 说明。步骤 3添加类型配置 SECRET_TYPE_CONFIGS仍在 ui/lib/sync/addon/utils/secret-type-config.ts向SECRET_TYPE_CONFIGS增加一条。现有kv和database条目给出了全部字段的实际取值新条目按文档模板填写尖括号内容为你需要替换的值export const SECRET_TYPE_CONFIGS: RecordSecretType, SecretTypeConfig { // ... existing configs your-new-type: { placeholder: Input placeholder text, noMatchesMessage: Message when no suggestions found, accessorType: Your Engine Display Name, // Shown in the type badge icon: your-hds-icon-name, // HDS icon name for this engine type route: externalRouteName, // External route name for viewing the secret supportsExternalLink: true, // Whether to show a link to the secret in the success message getModels: (mount, secretName) { // Return array of route parameters // Example: [mount, secretName] or [mount, role/${secretName}] return [mount, secretName]; }, getQuery: () { // Optional: Return query parameters for the route // Example: { type: static } // Omit this field if no query params are needed return undefined; }, }, };字段用途以文档注释为准placeholder和noMatchesMessage是SuggestionInput的提示文案accessorType显示在类型徽章上icon是 HDS 图标名与accessorType一起驱动SecretTypeBadgeroute指向查看该密钥的外部路由getModels返回路由参数数组getQuery可选返回路由查询参数现有database条目用的是{ type: static }。步骤 4注册 fetcher SECRET_TYPE_FETCHERS在 ui/lib/core/addon/utils/secret-type-fetchers.ts 的SECRET_TYPE_FETCHERS中增加条目。每个 fetcher 由三个函数组成接口定义在SecretTypeFetcherexport const SECRET_TYPE_FETCHERS: RecordSecretType, SecretTypeFetcher { // ... existing fetchers your-new-type: { fetch: async (api, mountPath, value) { // Fetch suggestions from API // Example: const backend mountPath.endsWith(/) ? mountPath.slice(0, -1) : mountPath; const { keys } await api.yourService.listItems(backend); return keys || []; }, filter: (items, value, isDirectory) { // Filter items based on current input value if (!value) return items; return items.filter((item) item.toLowerCase().includes(value.toLowerCase())); }, onSelect: (item, pathToSecret) { // Return the final value when an item is selected // For simple cases: return item; // For hierarchical (like KV): return ${pathToSecret}${item}; return item; }, }, };fetch负责调用 API 拉取建议项列表backend需要去掉尾部/示例中的api.yourService.listItems(backend)是文档占位写法替换为实际 API 服务上的列表方法。filter按当前输入过滤onSelect在用户选中某一项时返回最终值。onSelect是否要拼接路径取决于引擎结构KV 这类分层引擎拼pathToSecret扁平引擎直接返回item。完整示例新增 PKI 证书类型文档给出了一个端到端的 PKI 示例各步骤的取值如下可作为替换上面占位值的参照// 1. 类型定义ui/types/vault/sync.d.ts export type SecretType kv | database | pki; // 2. 类型检测 // getSecretTypeFromMount — for new sync if (type pki) return pki; // getSecretTypeFromAccessor — for existing synced secrets if (prefix pki) return pki; // 3. 配置 pki: { placeholder: Certificate serial number, noMatchesMessage: No certificates found, accessorType: PKI, icon: certificate, route: pkiCertificateOverview, supportsExternalLink: true, getModels: (mount, serialNumber) [mount, serialNumber], }, // 4. Fetcher pki: { fetch: async (api, mountPath) { const backend mountPath.endsWith(/) ? mountPath.slice(0, -1) : mountPath; const { keys } await api.secrets.pkiListCerts(backend); return keys || []; }, filter: (certs, value) { if (!value) return certs; return certs.filter(c c.toLowerCase().includes(value.toLowerCase())); }, onSelect: (item) item, },步骤 5注册外部路由仅当 supportsExternalLink 为 true 时同步成功后的消息会显示跳转链接前提是supportsExternalLink: true此时路由必须在两处登记ui/app/app.js 中sync.dependencies.externalRoutes映射把路由名指向实际路由路径const externalRoutes { kvSecretOverview: vault.cluster.secrets.backend.kv.secret.index, databaseStaticRoleOverview: vault.cluster.secrets.backend.show, yourNewTypeOverview: vault.cluster.your.route.path, // Add your route };ui/lib/sync/addon/engine.js 中externalRoutes数组现有值含kvSecretOverview、databaseStaticRoleOverview等加入你的路由名const externalRoutes [ kvSecretOverview, databaseStaticRoleOverview, yourNewTypeOverview, // Add your route ];yourNewTypeOverview和vault.cluster.your.route.path为占位前者是自定义的路由名后者替换为目标密钥查看页在 Vault UI 中真实存在的路由路径。步骤 6确认 fetchMounts 的行为通常无需改动ui/lib/sync/addon/components/secrets/page/destinations/destination/sync.ts 的fetchMounts()调用api.sys.internalUiListEnabledVisibleMounts()拿到全部挂载逐个取出type和options.version再交给getSecretTypeFromMount(type, version)判定const secretType getSecretTypeFromMount(type, version); if (secretType) { supportedMounts.push({ name: path, id: path, engineType: type, version }); }判定通过的挂载被 push 进supportedMounts供 HDS SuperSelect 下拉展示MountOption接口定义在 secret-type-config.tsexport interface MountOption { name: string; id: string; engineType: string; version?: number; }文档对这一步的结论是由于过滤完全依赖getSecretTypeFromMount()只要步骤 2 返回非 null你的引擎类型会自动出现在挂载下拉中sync.ts 本身不需要修改。下拉项的图标与类型指示文字则读取SECRET_TYPE_CONFIGS中对应条目的icon和accessorType字段。验证新增类型是否生效文档给出的验证路径按顺序观察 UI 行为若集群中存在该引擎类型的挂载它会自动出现在 HDS SuperSelect 挂载下拉中选中该类型的挂载后密钥类型被自动检测对应detectedSecretType逻辑下拉项显示正确的图标和类型指示例如现有 KV 挂载显示为secret/ (KV v2)此为文档示例SuggestionInput按你注册的 fetcher 执行拉取与过滤占位符与无结果文案取自SECRET_TYPE_CONFIGS密钥列表按你配置的route与getModels展示各 getter 与条件分支自动使用你的配置无需逐处修改。文档特别强调的检查项系统基于挂载检测类型务必确认你的引擎类型同时出现在getSecretTypeFromMount()新建同步时用和getSecretTypeFromAccessor()展示已有同步密钥时用中。漏掉后者会导致已同步的密钥列表无法识别新类型。边界与限制KV 必须是 v2getSecretTypeFromMount中version 2才返回kvKV v1 挂载不会进入同步下拉。你的新类型如有类似版本约束也应在这个函数里处理。两个注册表必须完整SECRET_TYPE_CONFIGS与SECRET_TYPE_FETCHERS都是RecordSecretType, ...联合类型扩了但注册表没补全会导致编译错误文档称核心组件SuggestionInput、sync.ts在新增类型时无需改动改动的边界就是这两个文件加类型定义。engine 边界文档把core 组件只接收配置作为参数、不 import sync 这类 engine 专属包列为架构约束新增 fetcher 放在 core 包、类型与配置放在 sync 包正是为满足这一点。若挂载列表拉取失败例如权限不足sync.ts 的fetchMounts()会走 catch 分支用户仍可通过 FilterInput 手动输入挂载路径——这是现有代码注释中说明的行为。【免费下载链接】vaultA tool for secrets management, encryption as a service, and privileged access management项目地址: https://gitcode.com/GitHub_Trending/va/vault创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表