拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Puppet V3 Facts HTTP API 详解:节点事实上报、Schema 约束与间接层实现原理

运维DevOpsIaC【免费下载链接】puppetServer automation framework and application项目地址https://gitcode.com/gh_mirrors/pu/puppet点击查看免费下载导读facts端点是 Puppet V3 HTTP API 中用于**按节点名写入保存事实facts**的专用通道Puppet agent 在每次运行前把通过 Facter 采集到的节点事实以 JSON 形式 PUT 到 Puppet Server服务端据此生成该节点的 catalog。本文以 api/docs/http_facts.md 为核心完整讲解该端点的请求规范、JSON 请求体字段语义、facts.json 校验 Schema 的约束细节并结合仓库源码REST 间接层、Node::Facts 数据模型、HTTP 服务客户端还原一条 PUT 请求从客户端组装、网络传输到服务端处理的完整链路帮助开发者在自定义 Agent 工具或调试上报问题时快速定位。一、端点定位facts 是 V3 API 间接层端点之一在 Puppet 4 中Puppet 的 HTTP API 按职责拆分为配置服务前缀/puppet与证书服务前缀/puppet-ca所有配置类端点显式携带版本号facts即属于/puppet/v3下的配置端点。根据 api/docs/http_api_index.md 的说明V3 API 中每个派发到内部 indirector 框架的端点都遵循统一形式/puppet/v3/:indirection/:key?environment:environment其中:indirection为间接层名称此处为facts:key为间接层调用的键此处为节点名:nodename:environment为本次请求生效的环境名——即使某些端点不真正依赖环境该查询参数也必须显式给出。另外该文档特别强调服务器会忽略它不期望接收的任何多余参数因此请求方无需担心多带参数导致失败但也不能依赖未声明的参数生效。从路由实现看facts是一个特殊的单数形式间接层lib/puppet/network/http/api/indirected_routes.rb 的plurality方法为facts单独返回:singular因此端点路径是/facts/:nodename而非/factss/...HTTP 方法到间接层操作的映射也按单数集合处理。二、Save 操作PUT 请求完整规范原文档定义的唯一受支持操作是Save保存事实请求格式如下PUT /puppet/v3/facts/:nodename?environment:environment支持的 HTTP 方法PUT将请求体中的 JSON 事实存入指定节点。支持的格式application/json请求体必须以 JSON 编码。参数原文档声明None无额外参数。这一点在源码中得到印证lib/puppet/indirector/facts/rest.rb 的save方法第一行即为raise ArgumentError, _(PUT does not accept options) unless request.options.empty?即一旦请求携带任何 options服务端间接层会直接以ArgumentError拒绝这从实现层面证实了 Parameters: None 的契约。环境仍通过 URL 查询串中的environment传递属于端点的通用约定而非 PUT 专用参数。请求示例原文档原始内容说明为便于阅读事实列表已做精简JSON 已做格式化。PUT /puppet/v3/facts/elmo.mydomain.com?environmentenv Content-Type: application/json { name: elmo.mydomain.com, values: { architecture: x86_64, kernel: Darwin, domain: local, macaddress: 70:11:24:8c:33:a9, osfamily: Darwin, operatingsystem: Darwin, facterversion: 1.7.2, fqdn: elmo.mydomain.com, }, timestamp: 2013-09-09 15:49:27 -0700, expiration: 2013-09-09 16:19:27 -0700 }成功时服务端返回HTTP/1.1 200 OK Content-Type: application/json三、请求体字段语义对照 facts.json Schema请求体是一个四字段 JSON 对象四个字段全部为必填required且顶层不允许出现未声明字段additionalProperties: false字段类型必填语义namestring是事实所属的节点名须与 URL 中的:nodename一致valuesobject是该节点的全部事实键值对键名必须匹配^[a-z][a-z0-9_]*$timestampstring是事实采集时间注意不遵循 JSON 标准的 date-time 格式expirationstring是事实过期时间同样不遵循 JSON date-time 格式几点值得注意的约束细节values的键名白名单Schema 通过patternProperties限定事实键必须是小写字母开头、后续只能是[a-z0-9_]的正则形态同时additionalProperties: false禁止出现任何不匹配该模式的键。例如fqdn、macaddress合法而FQDN、os-family含连字符这类键会被判定非法。这对应 Puppet/Facter 长期沿用的小写下划线事实命名规范。timestamp/expiration的格式宽容性Schema 只要求它们是 string并显式注明不遵循 JSON 的 date-time 格式。示例中的2013-09-09 15:49:27 -0700RFC 2822 风格正是典型用法而在 lib/puppet/node/facts.rb 的to_data_hash序列化路径中Time 对象会被输出为iso8601(9)格式两种字符串格式在反序列化时都能被Time.parse正确解析见该文件initialize_from_hashlib/puppet/node/facts.rb#L43-L61。expiration与timestamp的间距示例中两者相差 30 分钟15:49:27 → 16:19:27表达这份事实在半小时内有效的生命周期语义过期后的事实应被视为不可靠数据。四、源码视角一条 PUT 请求的完整链路4.1 客户端组装Agent 侧Agent 侧的事实保存由 REST 间接层终结器发起。lib/puppet/indirector/facts/rest.rb 的save方法在通过空 options 校验后从全局 HTTP session 路由到 puppet API并调用 lib/puppet/http/service/compiler.rb 的put_factsdef put_facts(name, environment:, facts:) formatter Puppet::Network::FormatHandler.format_for(Puppet[:preferred_serialization_format]) headers add_puppet_headers( Accept get_mime_types(Puppet::Node::Facts).join(, ), Content-Type formatter.mime ) response client.put( with_base_url(/facts/#{name}), serialize(formatter, facts), headers: headers, params: { environment: environment } ) process_response(response) response end可以看到请求 URL 正是with_base_url(/facts/#{name})环境通过params: { environment: environment }注入查询串与文档的端点形式一一对应。序列化格式由Puppet[:preferred_serialization_format]设置决定Content-Type与Accept均按该格式协商。4.2 服务端间接层派发服务端收到PUT /puppet/v3/facts/:nodename后按 indirector 框架将facts间接层映射到对应终结器terminus终结器由facts_terminus设置决定lib/puppet/node/facts.rb 中indirects :facts, :terminus_setting :facts_terminus。仓库中提供的主要终结器包括RESTlib/puppet/indirector/facts/rest.rb本端点的客户端实现负责远程 find/saveFacterlib/puppet/indirector/facts/facter.rb本地采集终结器allow_remote_requests?返回false只用于从本机 Facter 读取事实destroy/save均直接抛错因为代码存储只用于从 Facter 取事实YAML / JSONlib/puppet/indirector/facts/yaml.rb、lib/puppet/indirector/facts/json.rb把事实序列化为扁平文件落盘分别存放于yamldir/facts/*.yaml服务端模式或clientyamldir/facts/*.yaml客户端模式等路径StoreConfigslib/puppet/indirector/facts/store_configs.rbstoreconfigs 功能的组成部分同样禁止远程请求。4.3 保存后的缓存联动NodeExpirer事实保存并不只是写一份数据它还会触发节点缓存的失效。lib/puppet/node/facts.rb 中定义了NodeExpirer模块并注入间接层module NodeExpirer def save(instance, key nil, options {}) Puppet::Node.indirection.expire(instance.name, options) super end end即在保存事实的同时expire对应节点的已缓存 node 数据确保下次 catalog 编译使用最新事实避免陈旧缓存导致的配置漂移。4.4 事实值的清洗与本地补充服务端/客户端在保存前还会对事实做归一化处理sanitizelib/puppet/node/facts.rb把非 String/Boolean/Numeric/Array/Hash 的值统一to_s转成字符串并尽力转码为 UTF-8add_local_factslib/puppet/node/facts.rb补充clientcert取certname、clientversion取Puppet.version、clientnoop取noop设置三个本地事实。五、Schema 校验与错误处理5.1 Schema 文件请求体必须严格遵循 api/schemas/facts.json。其完整约束要点已在第三节列出核心是四个必填字段 values键名模式 顶层与values的additionalProperties: false。任何缺失必填字段、出现未声明字段或非法事实键名都会导致校验失败。5.2 服务端错误响应lib/puppet/network/http/api/indirected_routes.rb 展示了媒体类型协商失败的典型响应当客户端发送的Content-Type不在支持集合内时服务端抛出HTTPUnsupportedMediaTypeError携带UNSUPPORTED_MEDIA_TYPEissue因此务必使用application/json。REST 终结器的save在发生Puppet::HTTP::ResponseError时始终将其转换为 HTTP 错误抛出与 find 不同find 在fail_on_404为 false 时可对 404 返回 nil见 rest.rb。六、配套能力事实检索、过滤与数据模型虽然本端点的文档主体是 Save但同一间接层还提供了互补能力理解它们有助于完整掌握 facts 数据流6.1 FindGET 读取lib/puppet/http/service/compiler.rb 的get_facts实现GET /puppet/v3/facts/:name?environment:environment返回反序列化后的Puppet::Node::Facts对象供需要读取远端节点事实的场景使用。6.2 事实过滤检索searchYAML/JSON 终结器通过include Puppet::Indirector::FactSearchlib/puppet/indirector/fact_search.rb支持按条件检索节点过滤条件形如facts.fact_name.operator或meta.timestamp.operator可用操作符为eq、le、ge、lt、gt、ne数值比较基于to_f字符串比较基于to_s。例如facts.kerneleqDarwin可筛选内核为 Darwin 的节点。6.3 数据模型与序列化Puppet::Node::Factslib/puppet/node/facts.rb是事实的承载模型name、values、timestamp为属性to_data_hash输出name/values/timestamp/expiration四字段结构from_data_hashinitialize_from_hash负责反序列化并可兼容 YAML 老格式中藏在values[_timestamp]里的时间戳。也就是说文档中定义的 JSON 形态正是该模型在网络与磁盘两个维度上的统一表示。七、实战要点小结URL 必须带环境PUT /puppet/v3/facts/:nodename?environment:environment:nodename与请求体name保持一致只用 PUT application/json其他方法或媒体类型会被间接层路由/协商逻辑拒绝不要携带额外 optionssave在request.options非空时直接抛ArgumentError四个字段缺一不可name、values、timestamp、expiration均为必填values键名必须匹配^[a-z][a-z0-9_]*$时间字段用字符串表达timestamp/expiration不遵循 JSON date-time示例使用2013-09-09 15:49:27 -0700这类可被Time.parse解析的格式即可保存事实会顺带清理节点缓存借助NodeExpirer避免 catalog 使用陈旧节点数据。以上内容同时以 api/docs/http_facts.md 的接口定义和仓库内间接层源码为双重依据读者可继续查阅 api/schemas/facts.json校验规则、lib/puppet/indirector/facts/rest.rbREST 终结器与 lib/puppet/node/facts.rb数据模型进行深入验证。赞分享运维DevOpsIaC【免费下载链接】puppetServer automation framework and application项目地址https://gitcode.com/gh_mirrors/pu/puppet点击查看免费下载相关推荐PyPTO ceil_div 整数上取整除法API 约束、TileShape 配置与底层实现原理PyPTO ceil_div 整数上取整除法API 约束、TileShape 配置与底层实现原理 本文围绕 PyPTO Tensor API 中的 ceil_人工智能编译器模型编译深度学习高性能计算CANNAscendPhysijs约束系统详解如何实现点对点和铰链约束Physijs约束系统详解如何实现点对点和铰链约束 Physijs作为Three.js的物理引擎插件为3D场景带来了强大的约束系统功能。约束系统是物理引擎中游戏开发EMQX Schema Registry 支持上传 Protobuf 源码包BundleHTTP API 与实现原理EMQX Schema Registry 支持上传 Protobuf 源码包BundleHTTP API 与实现原理 EMQX 的 Schema Regi后端物联网消息队列通信上一篇为什么选择SJVideoPlayeriOS视频播放器的终极解决方案下一篇音乐相似度分析利器SongSim自相似性矩阵完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门