工作流

版本 2.19

Semaphore 目前将每个任务模板视为独立单元——没有内置方法将多个模板链接成多步骤执行管道。此功能引入工作流——具有条件分支、步骤间变量传递和可选人工审批关卡的任务模板有向无环图(DAG)。设计参考了 AWX Workflow Job Templates、Rundeck 作业工作流以及 Jenkins/GitLab CI 管道概念。

Pro

  • 工作流模板 — 引入一个新的顶级实体,定义由带有条件(on_successon_failurealways)的有向边连接的任务模板节点 DAG,在项目内实现多步骤自动化管道。(#3182, #2334, #1383, #836)
  • 工作流执行引擎 — 按拓扑顺序执行工作流节点,遵守边条件并行执行独立分支,对具有多个父节点的节点采用 ALL 收敛。(#2281, #3088)
  • 工作流执行面板 — 提供工作流执行的统一视图,显示带有每个节点状态(等待中、运行中、成功、失败、跳过)的 DAG 图、可点击的节点日志和总体时间。
  • 节点间变量传递 — 允许任务模板生成输出变量(通过已知文件或 Ansible set_stats),自动作为额外变量注入到下游节点。(#3182)
  • 工作流调度和 API 触发 — 支持工作流的 cron 调度、API 触发执行和 webhook 触发,以及工作流级别的可选调查变量。(#3088)
  • 可视化工作流编辑器 — 拖拽式图形编辑器,用于在界面中设计工作流,具有实时 DAG 验证、节点定位和边上的条件选择器。
  • 节点级覆盖 — 在工作流节点级别覆盖模板的清单、凭据、变量组或 CLI 参数,允许在单个工作流内跨不同环境重用同一模板。
  • 审批关卡 — 在指定点暂停工作流执行以等待人工审批,具有可配置的超时、审批者通知以及来自界面或 API 的审批/拒绝操作。

Enterprise

  • 工作流 RBAC — 用于创建、编辑、执行和审批工作流的细粒度权限,基于角色的审批关卡分配和审计日志。
  • 跨项目工作流 — 在工作流中引用其他项目的任务模板,实现跨基础设施、应用和监控项目的组织级自动化管道。
  • 工作流版本控制和回滚 — 维护工作流定义的版本历史(含差异比较),恢复以前的版本,并记录每次运行使用的版本。

LDAP 和 OpenID 组映射

版本 2.20

Semaphore 支持 LDAP 和 OpenID Connect (OIDC) 进行认证,但集成仅限于登录——没有基于身份提供商组成员身份的自动角色或项目分配。每个 OIDC/LDAP 用户在首次登录后必须手动分配项目和角色。此外,OIDC 重定向处理、声明解析和 LDAP 配置中存在多个缺陷,导致认证体验不可靠。

Community

  • 按声明限制 OIDC 登录 — 仅允许具有特定声明值(例如必需的组成员身份或电子邮件域)的用户登录。(#2626, #2938)
  • SSO 自动登录 — 绕过登录页面直接重定向到 OIDC/SSO 提供商,并提供故障恢复 URL 以便在 SSO 不可用时恢复。(#2548, #2899)
  • OIDC PKCE 支持 — 按照 RFC 9700 的建议,在 OIDC 授权码流程中添加 Proof Key for Code Exchange。(#3072)
  • OIDC 环境变量配置 — 允许通过环境变量而非仅配置文件来配置 OIDC 提供商,简化容器中的密钥管理。(#2528, #3120)
  • 修复 web_host/web_root 下的 OIDC 重定向 — 解决 OIDC 登录后当 web_host 为空或 web_root 设置为子路径时的 404 错误。(#2681, #1524, #2532, #3121)
  • 修复 OIDC 声明处理 — 解决 username_claim 被忽略、email 声明未被识别以及 client_secret_file 产生格式错误请求的问题。(#1731, #2818, #3122)
  • 修复 LDAP 声明表达式 — 解决 LDAP 映射中损坏的模板表达式(例如 mail | {{ .username }}@domain.com 解析为 <no value>)。(#3127)
  • 修复 LDAP 用户名分配 — 确保 LDAP 用户获得其实际的 LDAP 用户名,而非随机生成的字符串。(#3688)
  • LDAP 本地认证回退 — 允许本地管理员账户在启用 LDAP 时仍然可以登录,防止 LDAP 服务器不可用时被锁定。(#1363)
  • LDAP 调试日志 — 添加 LDAP 认证失败的有用日志输出,使故障排查成为可能。(#2932)
  • OIDC/LDAP 用户与本地账户关联 — 允许将现有本地账户转换或关联到外部身份提供商,而不创建重复账户。(#3339)
  • OIDC 提供商登出 — 在退出 Semaphore 时结束 IdP 会话(例如 Keycloak),实现正确的账户切换。(#1496)

Pro

  • 将 LDAP 凭据同步到访问密钥 — 可选地在 LDAP 密码于登录时更改后自动更新访问密钥密码,保持 Ansible 凭据同步。(#3696)

Enterprise

  • OIDC 组到角色映射 — 基于 OIDC 声明(例如 groups 声明)自动分配 Semaphore 角色和项目成员身份,消除首次登录后的手动用户设置。(#1499, #2483)
  • LDAP 组到角色映射 — 将 Active Directory / LDAP 组映射到 Semaphore 角色,包括通过组成员身份分配管理员角色。(#3226, #1316)
  • 具有 LDAP/OIDC 集成的完整 RBAC — 实现细粒度的基于角色的访问控制(全局管理员、项目管理员、项目用户、只读),并从外部身份提供商组自动分配角色。(#891)
  • 可插拔认证架构 — 将认证抽象为提供商接口,以支持多个认证后端并简化添加新提供商的过程。(#465, #1820)
  • 修复用户删除留下孤立数据 — 确保删除用户时清理 project__user 映射,防止团队视图崩溃。(#3514)

内置清单管理系统

版本 2.22

如今,Semaphore 将清单视为不透明的数据块——用户要么将原始 INI/YAML 粘贴到单个文本框中,要么指向仓库中的文件。没有结构化的方法从 UI 添加主机、将主机组织成组或设置主机和组变量。此功能引入内置清单管理系统:一个结构化的、由 UI 管理的清单编辑器(类似于 AWX 清单),其中主机、组和变量是存储在 Semaphore 中并可直接在 Web 界面中编辑的一等对象,同时仍可完全导出为标准 Ansible 清单。

Community

  • 结构化的主机和组编辑器 — 通过 UI 管理主机、其地址/别名以及主机组,而非手动编辑原始清单文本框,并支持主机和组的添加/移除/重命名操作。(#836)
  • UI 中的主机和组变量 — 为每个主机和每个组将 host_varsgroup_vars 定义为结构化的键/值对,从而不再需要手动将连接设置和自定义变量嵌入清单正文中。
  • 改进的内联清单编辑器 — 用更大的、可调整大小的编辑器替换小型清单文本框,该编辑器具有 YAML/INI 语法高亮和验证,使现有的内联编辑模式真正可用。(#698, #1650)
  • 导入现有清单 — 通过导入现有的 INI/YAML 清单文件或粘贴其内容来引导托管清单,将其解析为结构化的主机、组和变量。
  • 声明式清单定义 — 通过 Semaphore 管理的 YAML 文档声明式地定义清单(主机、组、变量),实现与项目和模板并列的版本控制、可复现的清单设置。(#3109)
  • 导出为标准 Ansible 清单 — 在任务运行时将托管清单渲染为标准 Ansible 清单文件,使 playbook 和 ansible-inventory 看到完全相同的结构,无论它是如何编写的。

Pro

  • 可复用的主机组 — 一次性定义主机组并在多个清单和项目之间共享,使组成员身份或组变量的更改传播到使用该组的所有位置。
  • 清单变更历史 — 为每个清单保留修订历史记录,包含主机、组和变量更改的差异,并允许恢复以前的版本。

Enterprise

  • 范围限定的主机管理角色 — 引入一种操作员风格的角色,可以在指定清单中添加、编辑和移除主机(并运行预定义模板),而无需授予完整的项目管理权限。(#2989)
  • 清单变更审批 — 要求在对受保护清单的更改生效之前进行审查/审批,并提供审计追踪,记录谁在何时更改了哪个主机、组或变量。

灵活的通知系统

版本 2.21

Semaphore UI 中当前的通知系统仅通过 config.json 进行配置,支持有限的渠道(电子邮件、Telegram、Slack、MS Teams),并在全局级别运行,每个项目的自定义选项极少。此功能从头开始重新设计通知,使其可通过 UI 管理、可扩展,并可在项目和模板粒度上进行配置。

Community

  • 可扩展的渠道架构 — 为通知渠道定义通用接口,并针对每个渠道实现,使添加新渠道变得简单而无需修改核心逻辑。考虑采用通用通知库(例如 nikoksr/notify)或网关(例如 Apprise)来一次性覆盖多个提供商。(#2325, #1290)
  • UI 管理的通知配置 — 将通知设置从配置文件移至 Web UI,支持按项目和按模板粒度配置,并支持同一渠道类型的多个实例。(#3387, #1821, #3588)
  • 基于模板的消息自定义 — 支持用户自定义的消息模板,以文件形式存储在磁盘上而非数据库中。
  • 按项目选择渠道 — 允许用户通过项目设置按项目配置哪些通知渠道处于活跃状态。(#3588)
  • 出站 Webhook 事件 — 定义事件类型(START、SUCCESS、FAILURE),并允许按项目创建具有可配置 URL、请求头和 HMAC 认证的 Webhook 模板。(#1825, #2594, #3066)
  • 新通知渠道 — 添加对 Discord (#2924)、Ntfy (#3383)、Google Chat (#1148)、Rocket.Chat (#1091) 和 Pushover (#2594) 的支持。
  • "已修复"通知 — 在失败后首次成功运行时发送通知,类似于 GitLab CI 恢复告警。(#3380)
  • 按模板禁用所有通知 — 在现有的"禁用成功通知"复选框旁添加"禁用所有通知"选项。(#3724)
  • 成功时发送电子邮件 — 在成功通知路径中加入电子邮件(目前仅 Telegram/Slack/MS Teams 在成功时触发)。(#3503)
  • 修复通知中的任务 URL — 确保所有渠道(电子邮件、Slack、MS Teams)收到带有协议和主机名的完全限定任务 URL,而非相对路径。(#2097, #2311, #3292)
  • 修复电子邮件发送问题 — 解决 SMTP 端口 465(隐式 TLS)支持、auth-before-TLS 排序和 Date 头格式问题。(#2201, #2971, #3542, #3209)
  • Telegram 话题/主题支持 — 允许通过 message_thread_id 向特定 Telegram 群组话题发送通知,可按项目和模板配置。(#3493, #1456)
  • Slack 模板改进 — 暴露顶级字段(titletextcolor)以兼容 Slack Workflow Builder。(#2607)
  • 告警代理支持 — 允许为出站通知请求配置 HTTP 代理,而无需系统级代理。(#1484)

Pro

  • Pro 专属通知渠道 — 在 Pro 计划中支持特定的独占通知渠道。
  • 长时间运行任务告警 — 当任务超过可配置的持续时间阈值时触发通知。(#1393)

Enterprise

  • 通知审计日志 — 维护所有已发送通知的可搜索日志,包含投递状态、时间戳和收件人详细信息。改进错误日志以包含失败时的收件人上下文。(#3410)
  • 与事件管理平台集成 — 与 PagerDuty、Opsgenie 和 ServiceNow 的原生集成,用于自动创建事件和生命周期跟踪。
  • 基于角色的通知访问控制 — 根据组织角色和权限限制谁可以配置通知规则和渠道。

用户自有密钥

版本 2.21

Semaphore 的密钥库目前在所有项目成员之间共享。任何具有项目访问权限的用户都可以使用(在某些情况下还可以查看)所有存储的凭据。这在多用户环境中造成安全隐患,因为团队成员应只能访问自己的凭据。此外,密钥库在加密、密钥更新和引用完整性方面存在多个缺陷,并且缺乏与外部密钥管理系统的集成。

Community

  • 个人密钥库 — 提供按用户的密钥库,使个人凭据(SSH 密钥、sudo 密码)与其他项目成员隔离,不通过项目级密钥库共享。(#1483, #1373)
  • 修复密钥更新行为 — 解决编辑密钥环境变量看似成功但值实际未持久化的问题。(#2546)
  • 从进程列表中隐藏密钥 — 停止通过操作系统进程列表中可见的命令行参数传递密钥 extra-vars;改用安全机制(例如临时文件、stdin)。(#3219)
  • 密钥库中的 SSH 证书支持 — 允许在密钥库中将 SSH 证书与 SSH 密钥一起存储,以支持基于证书的认证工作流。(#3171)
  • 显示 SSH 公钥 — 在密钥库 UI 中显示已存储 SSH 密钥的公钥部分,方便使用。(#1643)
  • Docker 密钥支持 — 支持 _FILE env var 模式(例如 POSTGRES_PASSWORD_FILE),使 Docker/Kubernetes 密钥可以挂载并读取,而非通过环境变量传递。(#1268)
  • 修复 Docker 中的加密密钥处理 — 确保 SEMAPHORE_ACCESS_KEY_ENCRYPTION env var 被正确使用,不会在容器重启时被随机密钥覆盖。(#2228, #3068, #3204)
  • 修复密钥库重命名导致引用断裂 — 解决重命名密钥库条目会破坏所有关联清单和模板的问题。(#3188)
  • 修复 Vault 密码 API — 允许通过 REST API 设置和更新 Ansible Vault 密码,不再出现重复键约束错误。(#3413, #2773)

Pro

  • 外部密钥存储集成 — 在运行时从 HashiCorp Vault、Azure Key Vault、AWS KMS 或 Bitwarden 拉取密钥,而非存储在 Semaphore 的数据库中。(#2248, #658)

Enterprise

  • 全局访问密钥 — 通过集中管理和跨项目链接,跨项目共享密钥库条目而无需重复。(#110)
  • 密钥访问审计追踪 — 记录密钥库条目和密钥变量的所有访问和使用情况,用于合规性和取证。

requirements.yml 的凭据 阅读

版本 2.21

Ansible playbook 经常在 requirements.yml 中声明位于私有 Git 仓库中的私有角色和集合。Semaphore 目前没有一等的方法来针对这些仓库对 ansible-galaxy install 进行认证——用户只能将令牌嵌入 URL、将 SSH 密钥烘焙到运行器镜像中,或维护自定义准备脚本。此功能允许用户将一个或多个密钥库凭据附加到任务模板(或 playbook 运行),并在解析角色和集合的准备阶段自动使用它们。

Community

  • 将凭据附加到 playbook 运行 — 允许在任务模板上选择一个或多个密钥库条目(SSH 密钥、Git 令牌、用户名/密码),并在 ansible-galaxy install 期间应用,以便可以从私有 Git 仓库拉取 requirements.yml 中列出的私有角色和集合。(#3677, #3708, #897)
  • 按主机模式的凭据映射 — 当附加多个凭据时,将它们映射到主机名模式(例如 github.comgitlab.internal),使每个私有源使用正确的密钥或令牌而不发生冲突。(#3677)
  • 修复环境变量传播到 galaxy install 阶段 — 确保环境变量(包括密钥变量)在 ansible-galaxy install 期间导出,而不仅仅在 playbook 执行期间,使基于令牌的认证适用于 requirements.yml。(#2966, #3178)
  • 按 playbook 的 requirements 文件 — 允许在模板级别覆盖默认的 roles/requirements.yml / collections/requirements.yml 路径,适用于将多个具有不同依赖集的 playbook 分组的项目。(#1366)
  • 自定义 ansible-galaxy CLI 参数 — 暴露一个字段,用于传递给 ansible-galaxy install 的额外参数(例如 --ignore-certs--force、自定义服务器),覆盖隔离网络和内部 Galaxy 镜像设置。(#2348)

持久化仓库缓存

版本 2.21

目前,Semaphore 会为每个任务模板将仓库克隆(或拉取)到单独的目录中,这对于大型仓库来说速度较慢,并且浪费磁盘 I/O。此功能为每个仓库添加一个标志,切换为共享的持久化克隆,该克隆在后台定期更新——类似于 AWX 处理项目更新的方式。启用后,引用该仓库的所有模板共享一个工作副本(与 Semaphore 中本地仓库已有的模型相同),单个任务运行不再触发克隆或拉取。

Community

  • 仓库设置中的"缓存仓库"标志 — 为每个仓库添加一个开关,启用后保留单个持久化克隆,而不是每次任务运行时都进行克隆。该克隆在使用该仓库的所有模板之间共享,与本地仓库已有的行为一致。(#1212)
  • 后台定期同步 — 启用缓存标志后,在后台工作线程中按可配置的间隔(例如每 5 分钟)拉取更新,而不是在任务启动时拉取,这样任务总是能够立即针对最近的检出启动。
  • 手动同步操作 — 在仓库 UI 中提供"立即同步"按钮以及相应的 API 端点,以便在定期计划之外触发即时拉取。
  • 强制推送/历史重写容错 — 优雅地处理上游强制推送(例如 git fetch --all && git reset --hard origin/<branch>),而不是在正常拉取时失败。(#800)
  • 脏工作树恢复 — 在拉取之前自动检测并清理脏工作树(例如残留的 .retry 文件),防止"本地更改"错误。(#308)
  • 过期克隆清理 — 对已删除或 URL 已更改的仓库的缓存克隆进行垃圾回收,回收磁盘空间。(#1497, #2679)
  • 同步状态可见性 — 在仓库详情页面显示上次同步的时间戳和状态(成功/失败),以便用户了解工作副本的新鲜程度。
  • 按仓库同步计划 — 允许在单个仓库上覆盖全局同步间隔(例如高频变更仓库每分钟同步,稳定仓库每小时同步)。

每个模板多个清单

版本 2.22

Ansible CLI 原生支持传递多个 -i 参数来组合清单(例如 ansible-playbook -i common_vars.yml -i staging_hosts.yml)。Semaphore 目前将每个任务模板限制为单个清单,迫使用户采用清单脚本、合并文件或额外环境变量等变通方法。此功能取消了该限制,并解决了更广泛的清单管理问题。

Community

  • 多清单支持 — 允许将多个清单附加到单个任务模板,作为顺序 -i 参数传递给 Ansible(例如 ansible-playbook -i common_vars.yml -i staging_hosts.yml)。解决了每个模板只能使用一个清单的限制。(#2093)
  • 可选清单字段 — 对于 ansible.cfg 已指定清单来源的情况,使模板上的清单字段变为可选。(#1574)
  • URL/HTTP 清单来源 — 支持从远程 URL 或 API 端点获取清单,这对于没有文件系统访问权限的托管/SaaS 环境至关重要。(#1924)
  • 运行时清单选择 — 允许用户在任务启动时通过下拉菜单选择清单,取代当前的自由文本变通方法。(#1354)
  • 修复计划任务清单持久化 — 确保在计划对话框中选择的清单被保存并在执行时使用,而不是回退到模板默认值。(#3566, #3293)
  • 修复项目导出/恢复丢失清单仓库链接 — 清单到仓库的关联在项目导出时被丢弃,导入时未恢复。(#3369, #3177)
  • 将环境变量传递给动态清单 — 确保容器/主机环境变量可供动态清单脚本和插件使用(例如 Python 脚本、microsoft.ad.ldap)。(#2724, #2783)
  • 修复基于 git 的清单认证 — 在获取远程分支用于清单时使用仓库凭据,修复未认证的访问尝试。(#3539)
  • 按主机覆盖凭据 — 停止使用全局 --extra-vars 覆盖清单中定义的按主机 ansible_user 和连接变量。允许多用户清单模式。(#1464, #1621)
  • 在 UI 中查看清单内容 — 在 UI 中显示基于文件的和动态清单内容以供检查和调试,并提供指向外部仓库中源文件的链接。(#3169, #1555, #3543)
  • 在任务上下文中暴露清单名称 — 使清单名称在 semaphore_vars 中可用或作为环境变量,以便 playbook 可以引用当前活跃的清单。(#1580)

Pro

  • 清单到运行器的亲和性 — 将清单主机与运行器标签关联,以便任务仅被分派到对目标主机具有网络访问权限的运行器,避免多网络环境中的故障。(#3322)
  • 每个清单多个 SSH 密钥 — 允许为单个清单分配多个密钥库条目,适用于每台主机使用唯一 SSH 密钥的集群。(#3336)
  • 虚拟化平台清单集成 — 与虚拟化平台 API(VMware、Proxmox)原生集成,自动生成和刷新动态清单。(#2709)
  • 主机组管理 API — 提供 API 用于在清单组中添加/移除主机,而无需重写整个清单数据。(#1560)

Enterprise

  • 限制每个模板允许的清单 — 当模板启用"询问清单"时,将可选择的清单限制在管理员定义的允许列表中,防止误操作目标环境。(#3587)
  • 中央主机注册表 — 提供共享的主机管理层,使主机变更(例如主机名或 IP 更新)自动传播到所有引用该主机的清单,无需手动编辑。(#564)
  • 主机事实存储和可视化 — 存储每台主机的 Ansible 事实,并显示任务运行前后的状态,具备差异对比和历史记录功能。(#930)