(`/puppet/v3/catalog`)從請(qǐng)求到響應(yīng)的完整解析)
運(yùn)維DevOpsIaC【免費(fèi)下載鏈接】puppetServer automation framework and application項(xiàng)目地址https://gitcode.com/gh_mirrors/pu/puppet點(diǎn)擊查看免費(fèi)下載catalog端點(diǎn)是 Puppet 配置管理體系中連接 agent 與 master 的核心樞紐agent 把本機(jī) facts 提交給服務(wù)端服務(wù)端依據(jù)節(jié)點(diǎn)聲明與環(huán)境配置編譯出該節(jié)點(diǎn)的資源目錄Catalog并返回 JSON。本篇指南以倉庫中的 http_catalog.md 為骨架結(jié)合 catalog.json、facts.json 兩份 schema 以及l(fā)ib/puppet/indirector/catalog/compiler.rb、lib/puppet/http/service/compiler.rb等源碼實(shí)現(xiàn)完整講解該端點(diǎn)的請(qǐng)求方法、參數(shù)語義、靜態(tài)目錄static catalog擴(kuò)展字段與響應(yīng)結(jié)構(gòu)讀完即可獨(dú)立構(gòu)造一次目錄請(qǐng)求并對(duì)響應(yīng)做逐字段解析。端點(diǎn)概述一次請(qǐng)求拿到整臺(tái)節(jié)點(diǎn)的“期望狀態(tài)”catalog端點(diǎn)根據(jù)給定的節(jié)點(diǎn)名nodename與 facts返回針對(duì)該節(jié)點(diǎn)的資源目錄。一次典型的請(qǐng)求鏈?zhǔn)莂gent 收集 facts → 通過 HTTP 調(diào)用本端點(diǎn) → 服務(wù)端 compiler 根據(jù) facts、節(jié)點(diǎn)聲明ENC、環(huán)境與清單manifests編譯目錄 → 以application/json返回。Puppet 隨后依據(jù)該目錄完成資源收斂converge。POST /puppet/v3/catalog/:nodename GET /puppet/v3/catalog/:nodename?environment:environment支持的 HTTP 方法POSTGET支持的響應(yīng)格式application/json為什么 POST 與 GET 等價(jià)卻仍要保留兩種按原文檔說明POST 與 GET功能上完全等價(jià)兩者都提供下文列出的參數(shù)POST 將參數(shù)放入請(qǐng)求體GET 將參數(shù)放入查詢字符串。Puppet 最初只使用 GET之所以后來增加 POST是因?yàn)椴糠?Web 服務(wù)器對(duì) URI 長度有上限典型如 1024 字節(jié)而facts參數(shù)序列化后很容易超過該上限。因此本文示例統(tǒng)一使用 POST 方法。這一“雙重轉(zhuǎn)義”的細(xì)節(jié)在源碼中可以得到印證客戶端在 compiler.rbHTTP Service 中先用Puppet::Util.uri_query_encode(facts_as_string)編碼一次拼入application/x-www-form-urlencoded請(qǐng)求體服務(wù)端 catalog/compiler.rb 的convert_wire_facts再執(zhí)行CGI.unescape(facts)還原同時(shí)兼容已廢棄的pson格式Puppet::Node::Facts.convert_from(pson, CGI.unescape(facts))以支持舊版 agent。請(qǐng)求參數(shù)詳解POST 與 GET 需要提供四類核心參數(shù)另有若干可選參數(shù)參數(shù)必需性說明environment必需環(huán)境名稱例如productionfacts_format必需必須是application/jsonfacts必需facts 哈希的 JSON 序列化。由于 facts 中可能包含同時(shí)也是 HTTP 查詢參數(shù)分隔符因此 facts 必須雙重轉(zhuǎn)義transaction_uuid必需標(biāo)識(shí)整個(gè)事務(wù)的 UUID該值也會(huì)出現(xiàn)在 report 中用于把目錄與報(bào)表關(guān)聯(lián)起來靜態(tài)目錄static catalog場景下還需兩個(gè)可選參數(shù)參數(shù)必需性說明static_catalog靜態(tài)目錄必需布爾值請(qǐng)求服務(wù)端在可用時(shí)返回靜態(tài)目錄實(shí)踐中應(yīng)始終為truechecksum_type靜態(tài)目錄必需以點(diǎn)號(hào)分隔的、agent 支持的校驗(yàn)和類型列表用于靜態(tài)目錄中 File 資源的校驗(yàn)順序表示優(yōu)先級(jí)越靠前優(yōu)先級(jí)越高其他可選參數(shù)參數(shù)說明configured_environment客戶端上配置的環(huán)境名稱??商峁┙o ENC外部節(jié)點(diǎn)分類器用于告知其客戶端請(qǐng)求了特定環(huán)境而該環(huán)境可能與客戶端自認(rèn)為的當(dāng)前環(huán)境不一致job_id觸發(fā)本次目錄請(qǐng)求的編排orchestration任務(wù) ID請(qǐng)求參數(shù)的客戶端實(shí)現(xiàn)細(xì)節(jié)從源碼看agent 側(cè) compiler.rbHTTP Service 的post_catalog會(huì)把參數(shù)組裝成keyvalue...形式的請(qǐng)求體body { facts_format: facts_format, facts: Puppet::Util.uri_query_encode(facts_as_string), environment: environment, configured_environment: configured_environment || environment, check_environment: !!check_environment, transaction_uuid: transaction_uuid, job_uuid: job_uuid, static_catalog: static_catalog, checksum_type: checksum_type.join(.) }.map do |key, value| #{key}#{Puppet::Util.uri_query_encode(value.to_s)} end.join()值得注意的幾點(diǎn)出于歷史兼容原因environment即使已放入請(qǐng)求體也會(huì)同時(shí)作為查詢參數(shù)再發(fā)送一次見該文件第 120-121 行注釋for legacy reasons we always send environment as a query parameter too。job_uuid即文檔中的job_id用于把目錄與 orchestrator 發(fā)起的任務(wù)經(jīng) pxp-agent關(guān)聯(lián)。check_environment控制是否讓服務(wù)端校驗(yàn)請(qǐng)求環(huán)境與節(jié)點(diǎn)聲明的服務(wù)端環(huán)境是否一致服務(wù)端在 catalog/compiler.rb 中檢測到不一致時(shí)會(huì)打印告警并返回一個(gè)空目錄僅含節(jié)點(diǎn)名與環(huán)境避免 agent 在錯(cuò)誤環(huán)境下執(zhí)行資源。facts_format在默認(rèn)配置下取自 JSON 格式化器的 mime 類型application/json若preferred_serialization_format設(shè)為pson則回退為pson文件第 85-92 行。facts 參數(shù)的 schema 約束facts參數(shù)需要符合 facts schema。該 schema 要求對(duì)象包含四個(gè)必需字段namestring節(jié)點(diǎn)名valuesobject該節(jié)點(diǎn)的 facts 哈希鍵名須匹配^[a-z][a-z0-9_]*$且不允許額外屬性timestampstringfacts 收集時(shí)間注意不遵循 JSON 標(biāo)準(zhǔn)的date-time格式expirationstringfacts 過期時(shí)間同樣不遵循標(biāo)準(zhǔn)date-time格式。服務(wù)端 catalog/compiler.rb 的extract_facts_from_request會(huì)校驗(yàn) facts 中的節(jié)點(diǎn)名必須與請(qǐng)求 key 一致否則拋錯(cuò)Catalog for ... was requested with fact definition for the wrong node若提供了 facts 但沒有facts_format則直接報(bào)Facts but no fact format provided。隨后save_facts_from_request會(huì)把 facts 通過Puppet::Node::Facts.indirection.save存入服務(wù)端帶transaction_uuid供后續(xù)報(bào)表關(guān)聯(lián)使用。完整請(qǐng)求與響應(yīng)示例示例一普通目錄Catalog foundPOST /puppet/v3/catalog/elmo.mydomain.com environmentenvconfigured_environmentcanary_envfacts_formatapplication%2Fjsonfacts%257B%2522name%2522%253A%2522elmo.mydomain.com%2522%252C%2522values%2522%253A%257B%2522architecture%2522%253A%2522x86_64%2522%257D%257Dtransaction_uuidaff261a2-1a34-4647-8c20-ff662ec11c4c響應(yīng)HTTP 200 OK Content-Type: application/json{ tags: [settings, multi_param_class, class], name: elmo.mydomain.com, version: 1377473054, code_id: null, catalog_uuid: 827a74c8-cf98-44da-9ff7-18c5e4bee41e, catalog_format: 1, environment: production, resources: [ { type: Stage, title: main, tags: [stage], exported: false, parameters: { name: main } }, { type: Class, title: Settings, tags: [class, settings], exported: false }, { type: Class, title: main, tags: [class], exported: false, parameters: { name: main } }, { type: Class, title: Multi_param_class, tags: [class, multi_param_class], line: 10, exported: false, parameters: { one: hello, two: world } }, { type: Notify, title: foo, tags: [notify, foo, class, multi_param_class], line: 4, exported: false, parameters: { message: One is hello, two is world } } ], edges: [ { source: Stage[main], target: Class[Settings] }, { source: Stage[main], target: Class[main] }, { source: Stage[main], target: Class[Multi_param_class] }, { source: Class[Multi_param_class], target: Notify[foo] } ], classes: [settings, multi_param_class] }響應(yīng)中的edges數(shù)組刻畫了目錄中的包含關(guān)系containmentStage[main]包含Class[Settings]、Class[main]與Class[Multi_param_class]而Class[Multi_param_class]又包含Notify[foo]這正是 Puppet 依賴圖dependency graph的序列化形態(tài)。示例二靜態(tài)目錄Static Catalog foundPOST /puppet/v3/catalog/elmo.mydomain.com environmentenvconfigured_environmentcanary_envfacts_formatapplication%2Fjsonfacts%7B%22name%22%3A%22elmo.mydomain.com%22%2C%22values%22%3A%7B%22architecture%22%3A%22x86_64%22%7Dtransaction_uuidaff261a2-1a34-4647-8c20-ff662ec11c4cstatic_catalogtruechecksum_typesha256.md5響應(yīng)節(jié)選核心差異部分{ code_id: arbitrary_code_id_string, resources: [ { type: File, title: /tmp/foo, tags: [file, class], line: 12, exported: false, parameters: { ensure: file, source: puppet:///modules/a_module/foo } }, { type: File, title: /tmp/bar, tags: [file, class], line: 16, exported: false, parameters: { ensure: present, source: puppet:///modules/a_module/bar, recurse: true } } ], metadata: { /tmp/foo: { checksum: { type: sha256, value: {sha256}5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03 }, content_uri: puppet:///modules/a_module/files/foo, destination: null, group: 20, links: manage, mode: 420, owner: 501, path: /etc/puppetlabs/code/environments/production/modules/a_module/files/foo.txt, relative_path: null, source: puppet:///modules/a_module/foo, type: file } }, recursive_metadata: { /tmp/bar: { puppet:///modules/a_module/bar: [ { checksum: { type: ctime, value: {ctime}2016-02-19 17:38:36 -0800 }, content_uri: puppet:///modules/a_module/files/bar, destination: null, group: 20, links: manage, mode: 420, owner: 501, path: /etc/puppetlabs/code/environments/production/modules/a_module/files/bar, relative_path: ., source: null, type: directory }, { checksum: { type: sha256, value: {sha256}962dbd7362c34a20baac8afd13fba734d3d51cc2944477d96ee05a730e5edcb7 }, content_uri: puppet:///modules/a_module/files/bar/baz, destination: null, group: 20, links: manage, mode: 420, owner: 501, path: /etc/puppetlabs/code/environments/production/modules/a_module/files/bar, relative_path: baz, source: null, type: file } ] } } }靜態(tài)目錄與普通目錄的關(guān)鍵差異在于code_id普通目錄中為null靜態(tài)目錄中攜帶一個(gè)代碼版本標(biāo)識(shí)示例為arbitrary_code_id_string用于標(biāo)識(shí)本次編譯對(duì)應(yīng)的代碼版本metadata非遞歸non-recursiveFile 資源到其元數(shù)據(jù)的映射內(nèi)含checksum、content_uri、owner/group/mode等使 agent 無需二次請(qǐng)求即可校驗(yàn)文件內(nèi)容recursive_metadata遞歸 File 資源如示例中recurse true的/tmp/bar按“source → 元數(shù)據(jù)數(shù)組”組織的映射數(shù)組中包含目錄本身relative_path為.type為directory及其下每個(gè)文件如baz的元數(shù)據(jù)。靜態(tài)目錄的服務(wù)端生成邏輯靜態(tài)目錄并非單純的數(shù)據(jù)透傳而是由 catalog/compiler.rb 的compile方法在普通編譯之后額外完成的“元數(shù)據(jù)內(nèi)聯(lián)”inline后處理當(dāng)node.environment.static_catalogs?、請(qǐng)求帶static_catalog且提供code_id時(shí)先通過common_checksum_type第 141-149 行在 agent 提供的checksum_type列表以.分隔與服務(wù)端known_checksum_types之間求第一個(gè)交集找不到公共校驗(yàn)和類型則直接拋錯(cuò)避免后續(xù)階段失敗inline_metadata第 207-306 行遍歷目錄中所有File資源跳過ensure absent、無source或 source 非puppet://協(xié)議的資源對(duì)recurse資源走Puppet::FileServing::Metadata.indirection.search填充recursive_metadata對(duì)單文件資源走indirection.find填充metadata內(nèi)聯(lián)只對(duì)位于environmentpath之下、形如$codedir/environments/$environment/*/*/files/**的模塊文件生效inlineable_metadata?第 183-190 行環(huán)境之外的資源會(huì)被跳過并記錄 profiler 事件log_file_outside_environmentcontent_uri由get_content_uri第 151-161 行基于源文件相對(duì)環(huán)境目錄的真實(shí)路徑構(gòu)造保留用戶指定的 server 與端口。agent 側(cè) catalog/rest.rbindirector terminus 在發(fā)起請(qǐng)求前同樣會(huì)處理checksum_type若請(qǐng)求顯式提供了則以.拆分否則使用Puppet[:supported_checksum_types]配置值隨后調(diào)用Puppet::HTTP::Service::Compiler#post_catalog完成網(wǎng)絡(luò)請(qǐng)求并把 404 響應(yīng)轉(zhuǎn)換為可讀的 Puppet 錯(cuò)誤fail_on_404為 false 時(shí)返回nil。響應(yīng) Schemacatalog.json 逐字段說明目錄響應(yīng)的結(jié)構(gòu)由 catalog schema 定義其頂層required字段為tags、name、version、code_id、catalog_uuid、catalog_format、environment、resources、edges、classes且不允許額外屬性。各字段含義如下字段類型說明tagsarray[string]目錄標(biāo)簽tag 需匹配\A[[:alnum:]_][[:alnum:]_:.-]*\Znamestring目錄所屬節(jié)點(diǎn)名versionstring 或 integer目錄版本示例中為整數(shù)時(shí)間戳1377473054code_idstring 或 null代碼版本標(biāo)識(shí)靜態(tài)目錄中非空catalog_uuidstring本次目錄的唯一標(biāo)識(shí)用于與報(bào)表關(guān)聯(lián)catalog_formatinteger目錄格式版本號(hào)當(dāng)前示例為1environmentstring編譯目錄所用環(huán)境resourcesarray目錄中的資源數(shù)組edgesarray目錄中的包含關(guān)系數(shù)組classesarray[string]目錄中包含的類名列表resources 與 edgesresources中每個(gè)資源的required字段為type、title、tags、exported可選字段包括line清單行號(hào)、kind、file清單文件路徑、sensitive_parameters需按敏感參數(shù)處理的參數(shù)名列表與parameters參數(shù)名須匹配^[a-z][a-z0-9_]*$。edges中每條邊由source與target組成例如Stage[main] → Class[Settings]描述資源的包含/依賴層級(jí)。metadata 與 recursive_metadata靜態(tài)目錄專屬metadata是“非遞歸 File 資源標(biāo)題 → file_metadata 對(duì)象”的映射recursive_metadata是“遞歸 File 資源標(biāo)題 →source → file_metadata 數(shù)組”的兩層映射。file_metadata定義schema 中definitions.file_metadata的必需字段為path、relative_path、links、owner、group、mode、type、destination、checksum并含可選的source、content_urilinks取值限于manage/followtype取值限于file/directory/linkchecksum.type取值限于md5/sha256/ctimevalue為帶類型前綴的校驗(yàn)和字符串如{sha256}...mode、owner、group均為整數(shù)示例中的420即八進(jìn)制0644的十進(jìn)制表示。常見調(diào)試路徑與延伸閱讀服務(wù)端編譯入口catalog/compiler.rbfind→compile→inline_metadata的完整鏈路agent 端 REST 終結(jié)器catalog/rest.rbindirectorHTTP 客戶端封裝compiler.rbHTTP Service其中post_catalogv3與post_catalog4v4 私有接口展示了兩種請(qǐng)求裝配方式數(shù)據(jù)約束catalog.json 與 facts.json相關(guān)端點(diǎn)節(jié)點(diǎn)信息見 http_node.mdfacts 上報(bào)見 http_facts.md報(bào)表提交見 http_report.md全部 HTTP API 總覽見 http.md。小結(jié)/puppet/v3/catalog端點(diǎn)是 Puppet 編譯與分發(fā)流程的事實(shí)標(biāo)準(zhǔn)接口POST/GET 兩種方法等價(jià)四類核心參數(shù)environment、facts_format、facts、transaction_uuid配以靜態(tài)目錄擴(kuò)展參數(shù)static_catalog、checksum_type與兩個(gè)可選參數(shù)configured_environment、job_id即可驅(qū)動(dòng)服務(wù)端完成從節(jié)點(diǎn)定位、facts 校驗(yàn)、目錄編譯到可選文件元數(shù)據(jù)內(nèi)聯(lián)的完整流程。響應(yīng)體結(jié)構(gòu)完全由 catalog.json 約束resources/edges描述期望狀態(tài)metadata/recursive_metadata則為靜態(tài)目錄場景下的文件校驗(yàn)提供一站式元數(shù)據(jù)——理解這些字段與源碼實(shí)現(xiàn)無論是排查 agent 編譯問題、二次開發(fā)外部工具還是深入理解 Puppet 的“期望狀態(tài)引擎”都能做到有的放矢。贊分享運(yùn)維DevOpsIaC【免費(fèi)下載鏈接】puppetServer automation framework and application項(xiàng)目地址https://gitcode.com/gh_mirrors/pu/puppet點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Puppet HTTP API 完全指南/puppet/v3 與 /puppet-ca/v1 端點(diǎn)架構(gòu)、調(diào)用方式與源碼解析Puppet HTTP API 完全指南 /puppet/v3 與 /puppet ca/v1 端點(diǎn)架構(gòu)、調(diào)用方式與源碼解析 Puppet 服務(wù)端Puppe運(yùn)維DevOpsIaCPuppet Catalog 深度解析Resource Catalog 與 RAL Catalog 兩種形態(tài)及其在測試與 Settings 中的應(yīng)用Puppet Catalog 深度解析Resource Catalog 與 RAL Catalog 兩種形態(tài)及其在測試與 Settings 中的應(yīng)用 導(dǎo)讀P運(yùn)維DevOpsIaCPuppet Certificate HTTP API 詳解通過 /puppet-ca/v1/certificate 端點(diǎn)獲取與管理證書Puppet Certificate HTTP API 詳解通過 /puppet ca/v1/certificate 端點(diǎn)獲取與管理證書 本指南以 Puppe運(yùn)維DevOpsIaC創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考