ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Salt 实战指南:使用 slack_notify 执行模块向 Slack 发送消息与告警

Salt 实战指南:使用 slack_notify 执行模块向 Slack 发送消息与告警 运维配置管理后端【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址https://gitcode.com/gh_mirrors/sa/salt点击查看免费下载导读slack_notify是 Salt 内置的一个执行模块execution module用于在 minion 或 master 上直接调用 Slack API实现发送消息、列出频道与用户、查找频道与用户等操作。它既可以用于日常的运维告警推送如构建完成通知、监控告警也可以被 State、Scheduler、Reactor 等 Salt 生态组件复用。读完本文你将掌握slack_notify的全部函数用法、两种鉴权方式的配置方法以及它底层如何通过salt.utils.slack.query与 Slack 官方 API 交互从而在自己的 Salt 环境中快速落地一套基于 Slack 的通知能力。模块概览与文档定位本文对应的官方文档入口为 doc/ref/modules/all/salt.modules.slack_notify.rst该文件本身是一个基于 Sphinxautomodule的自动文档占位页其正文全部由模块源码中的 docstring 自动生成。因此本指南的权威内容主体直接来自实现源码 salt/modules/slack_notify.py底层 API 交互逻辑则位于工具库 salt/utils/slack.py。两者均位于当前仓库内可作为阅读与验证的一手依据。该模块自2015.5.0版本加入见源码 docstring 中的versionadded标记模块虚拟名为slack因此在命令行与文档中通常写作slack.xxx而不是slack_notify.xxx。这一虚拟名机制在模块的__virtual__()函数中定义__virtualname__ slack def __virtual__(): Return virtual name of the module. :return: The virtual name of the module. return __virtualname__由于__virtual__()无条件返回虚拟名该模块在任意 minion 上都会默认加载无需额外启用。配置方式API Key 与 WebHookslack_notify支持两种 Slack 集成方式分别面向「以应用 Token 调用 REST API」和「以 Incoming WebHook 推送消息」两种场景对应两套配置键。1.api_keySlack 应用 Token在 minion 配置/etc/salt/minion或 master 配置中以slack为顶层键、api_key为子键配置slack: api_key: peWcBiMOS9HrZG15peWcBiMOS9HrZG15从源码看读取逻辑同时兼容点号.与冒号:两种分隔写法见 salt/modules/slack_notify.py 中的_get_api_key()def _get_api_key(): api_key __salt__config.get or __salt__config.get if not api_key: raise SaltInvocationError(No Slack API key found.) return api_key如果配置缺失会抛出SaltInvocationError(No Slack API key found.)异常。__salt__[config.get]会依次读取 minion 配置、Pillar、master 配置等来源因此你也可以把slack.api_key放进 Pillar 中以实现集中管理。需要说明的是Slack 官方对 Token 的鉴权方式有过变更——2021 年 2 月 24 日之后创建的应用不再允许把 Token 放在 URL 查询参数中必须使用 HTTPAuthorization: Bearer token请求头或在 POST body 中携带 Token。salt.utils.slack.query已遵循该要求统一通过Authorization: Bearer {api_key}头传递鉴权见 salt/utils/slack.py 中的相关注释与实现。2.hookIncoming WebHook 标识符WebHook 方式的配置键是hook注意不是identifier值为 WebHook URL 中https://hooks.slack.com/services/之后的部分slack: hook: T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX读取逻辑见_get_hook_id()def _get_hook_id(): url __salt__config.get or __salt__config.get if not url: raise SaltInvocationError(No Slack WebHook url found) return urlcall_hook函数会将其拼接到https://hooks.slack.com/services/之后组成完整 URLbase_url https://hooks.slack.com/services/ ... url urllib.parse.urljoin(base_url, identifier)函数详解list_rooms / list_users列出频道与用户这两个函数分别调用 Slack 的conversations.list与users.listAPI返回所有频道频道列表或用户成员列表信息salt * slack.list_rooms salt * slack.list_rooms api_keypeWcBiMOS9HrZG15peWcBiMOS9HrZG15 salt * slack.list_users salt * slack.list_users api_keypeWcBiMOS9HrZG15peWcBiMOS9HrZG15api_key参数均为可选——未传入时自动回退到_get_api_key()从配置读取。函数签名如下def list_rooms(api_keyNone): ... return salt.utils.slack.query(functionrooms, api_keyapi_key, opts__opts__) def list_users(api_keyNone): ... return salt.utils.slack.query(functionusers, api_keyapi_key, opts__opts__)find_room / find_user按名称查找频道与用户find_room在已获取的频道列表中按名称精确匹配并返回频道对象find_user同理匹配用户对象。两者都接收name参数未命中时返回Falsesalt * slack.find_room namerandom salt * slack.find_room namerandom api_keypeWcBiMOS9HrZG15peWcBiMOS9HrZG15 salt * slack.find_user nameThomasHatch salt * slack.find_user nameThomasHatch api_keypeWcBiMOS9HrZG15peWcBiMOS9HrZG15find_room的实现细节值得注意Slack 搜索接口返回的频道名称不带#前缀因此若传入的频道名以#开头会先剥掉#再做比对见 salt/modules/slack_notify.py 中相关注释与逻辑# search results dont include the name of the # channel with a hash, if the passed channel name # has a hash we remove it. if name.startswith(#): name name[1:] ret list_rooms(api_key) if ret[res]: rooms ret[message] if rooms: for room in rooms: if room[name] name: return room return Falsepost_message向频道发送消息post_message是使用最频繁的函数用于向 Slack 频道发送一条文本消息支持富文本扩展salt * slack.post_message channelDevelopment Room messageBuild is done完整签名如下def post_message( channel, message, from_nameNone, api_keyNone, iconNone, attachmentsNone, blocksNone, ):参数类型说明channelstr频道名必须以#普通频道或私信开头messagestr要发送的消息文本from_namestr已弃用历史上用作username覆盖值api_keystrSlack Token缺省时从配置读取iconstr已弃用历史上用作icon_url覆盖值attachmentslist随消息发送的附件自 3003 版本起支持blockslist随消息发送的 Block Kit 块自 3003 版本起支持关键行为说明如下频道名自动规范化若传入的channel不以#或开头模块会打印一条 warning 并自动补上#if not channel.startswith(#) and not channel.startswith(): log.warning( Channel name must start with a hash or . Prepending a hash and using #%s as channel name instead of %s, channel, channel, ) channel f#{channel}单元测试 tests/pytests/unit/modules/test_slack.py 也验证了这一点传入channelfake_channel后实际发送的请求体中 channel 变为#fake_channel。请求体为 URL 编码表单Slack 的chat.postMessage要求 POST body 为 urlencoded 格式模块使用urllib.parse.urlencode将参数编码后以Content-Type: application/x-www-form-urlencoded提交parameters { channel: channel, text: message, attachments: attachments or [], blocks: blocks or [], } ... result salt.utils.slack.query( functionmessage, api_keyapi_key, methodPOST, header_dict{Content-Type: application/x-www-form-urlencoded}, dataurllib.parse.urlencode(parameters), opts__opts__, )from_name与icon已弃用自 3006.28 起Slack 于 2025 年 3 月 31 日弃用了 classic/custom-bot 应用通过chat.postMessage覆盖机器人显示名称与图标的username/icon_url字段对应 issue 见 changelog/67948.fixed.md。此后现代应用再携带这些字段会被 Slack 以legacy_custom_bots_deprecated拒绝。因此新版本中若不传from_name与icon请求体中将不包含username与icon_url字段使用 Slack 应用设置中配置的显示名与图标若显式传入模块会打印 deprecation warning但仍会为向后兼容而透传给 Slack。相关逻辑与对应的回归测试test_post_message_legacy_from_name_preserved_with_warning、test_post_message_omits_username_when_from_name_absent都在仓库中可查证测试确保不传from_name时请求体不出现username与icon_url。返回值{res: True}表示发送成功失败时返回{res: False, message: ...}形式的字典。call_hook通过 Incoming WebHook 发送消息call_hook面向 Incoming WebHook 场景无需应用 Token只需 WebHook 标识符即可推送消息。它也是 reactor / scheduler 场景下最轻量的告警通道salt * slack.call_hook messageHello, from SaltStack \ identifierT00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX完整签名def call_hook( message, attachmentNone, colorgood, shortFalse, identifierNone, channelNone, usernameNone, icon_emojiNone, ):参数类型说明messagestr消息主题fallback/pretext 文本attachmentstr附件的字段值colorstr附件左侧边框颜色默认good绿色shortbool该字段值是否足够短、可与其他值并排展示identifierstrWebHook 标识符URL 中services/之后的部分缺省从配置读取channelstr覆盖 WebHook 默认频道的目标频道usernamestr覆盖 WebHook 默认用户名的展示名icon_emojistr覆盖 WebHook 默认图标的 emoji行为细节不传identifier时从配置键slack.hook读取配置示例见上文「hook 配置」小节。传了attachment时payload 会构造为 Slack 附件格式以message作为fallback与pretext以attachment作为fields[0].value并携带color与short未传attachment时payload 退化为简单的{text: message}if attachment: payload { attachments: [ { fallback: message, color: color, pretext: message, fields: [{value: attachment, short: short}], } ] } else: payload { text: message, }channel/username/icon_emoji只要传入就会被追加进 payload用于覆盖 WebHook 的默认设置。实际请求同样采用 urlencoded 表单将整个 payload JSON 序列化后放入payload表单字段data urllib.parse.urlencode({payload: salt.utils.json.dumps(payload)}) result salt.utils.http.query(url, methodPOST, datadata, statusTrue) if result[status] 201: return True else: return {res: False, message: result.get(body, result[status])}返回值HTTP 状态码 201视为成功返回True否则返回{res: False, message: ...}。底层原理salt.utils.slack.query 与 Slack API 的映射slack_notify的六个函数最终都汇聚到工具库 salt/utils/slack.py 的query()函数由它负责 URL 构造、鉴权与响应解析。query()内部维护了一个「逻辑函数 → Slack API」的映射表slack_functions { rooms: {request: conversations.list, response: channels}, users: {request: users.list, response: members}, message: {request: chat.postMessage, response: channel}, }对应关系一目了然slack_notify 函数Slack API 端点响应字段list_rooms/find_roomconversations.listchannelslist_users/find_userusers.listmemberspost_messagechat.postMessagechannelquery()的完整流程为若未显式传入api_key先尝试从__salt__[config.get]读取slack.api_key/slack:api_key读不到则记录错误并返回{res: False, message: No Slack api key found.}以https://slack.com/api/为基址拼接端点路径非 POST 请求设置Accept: application/json头统一设置Authorization: Bearer {api_key}鉴权头符合 Slack 对 2021 年 2 月 24 日后创建应用的要求详见 salt/utils/slack.py 中的注释通过salt.utils.http.query发出请求decodeTrue自动解析 JSON 响应解析响应HTTP 200且无error字段时从映射的响应字段提取数据返回HTTP 204直接返回True其他情况返回{res: False, message: 错误信息或 invalid_auth}。query()的返回值结构统一为{message: ..., res: True/False}这也是slack_notify各函数判断成功与否的依据。实战场景与 Reactor / Scheduler 组合使用slack_notify是执行模块天然可以在任意执行上下文中被调用。以下是两类常见组合以下示例仅为仓库可支持能力的展示均基于上文已介绍的模块 API结合schedule定时执行在 minion 配置中定义定时任务周期性地把系统状态推送到 Slack 频道例如每天 9 点调用post_message汇报消息具体发送内容可由你按需拼接schedule: slack_daily_report: function: slack.post_message args: - #ops-channel - Daily report: minion alive. when: 9:00am结合 State 或 Reactor 做构建/告警通知由于post_message会规范频道名并支持attachments/blocks可以在 CI 构建完成后、监控规则触发时通过 reactor 事件调用它推送富文本消息。attachments与blocks自 3003 版本起加入见 doc/topics/releases/3003.rst 中的说明可用于构造 Block Kit 交互式卡片。需要强调的是post_message走的是「应用 Token REST API」路径要求使用 Bot Token 且有chat:write权限而call_hook走的是 Incoming WebHook 路径无需 Token、配置最简单仅需slack.hook适合快速接入的轻量通知场景。两者可根据你的 Slack 应用配置灵活选用。版本演进与兼容性说明2015.5.0模块随 Salt 2015.5 加入源码 docstring 标记。2016.3.0底层工具库salt.utils.slack加入统一封装 Slack API 调用见 salt/utils/slack.py 的 docstring 标记slack_notify的查询与消息函数开始经由query()走 REST API。3003post_message增加attachments与blocks参数见 doc/topics/releases/3003.rst。3006.28from_name与icon弃用——Slack 弃用 classic/custom-bot 的username/icon_url覆盖能力后省略这两个参数时不再向chat.postMessage发送对应字段避免legacy_custom_bots_deprecated错误见 changelog/67948.fixed.md 与对应回归测试 tests/pytests/unit/modules/test_slack.py。因此在使用现代 Slack 应用时建议不在post_message中传from_name/icon改为在 Slack App 后台配置 Bot 的显示名称与图标配置键统一使用slack.api_key与slack.hook。延伸阅读模块完整源码salt/modules/slack_notify.pySlack API 工具库salt/utils/slack.py单元测试tests/pytests/unit/modules/test_slack.py官方模块文档页doc/ref/modules/all/salt.modules.slack_notify.rst相关 issue 修复记录changelog/67948.fixed.md赞分享运维配置管理后端【免费下载链接】saltSoftware to automate the management and configuration of infrastructure and applications at scale.项目地址https://gitcode.com/gh_mirrors/sa/salt点击查看免费下载相关推荐Salt 的 mdadm_raid 执行模块实战指南用 Salt 管理 Linux 软件 RAIDSalt 的 mdadm_raid 执行模块实战指南用 Salt 管理 Linux 软件 RAID 本篇技术指南围绕 Salt 发行版中 raid 执行模块运维配置管理后端Apache DolphinScheduler Slack 告警插件配置指南从 Webhook 申请到消息发送原理Apache DolphinScheduler Slack 告警插件配置指南从 Webhook 申请到消息发送原理 导读 本文讲解如何在 Apache Dol任务调度数据编排工作流自动化后端大数据Automatisch Slack 集成动作深度指南消息搜索、用户查找与消息发送实战Automatisch Slack 集成动作深度指南消息搜索、用户查找与消息发送实战 本指南以 Automatisch 开源仓库中 Slack 应用 pac工作流自动化后端前端低代码任务调度创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表