运维DevOpsIaC【免费下载链接】puppetServer automation framework and application项目地址https://gitcode.com/gh_mirrors/pu/puppet点击查看免费下载导读puppet device是 Puppet 项目中专门用于管理远程网络设备交换机、路由器等无法直接运行 agent 的设备的子命令。它通过在普通 Puppet agent 上作为代理运行为远程设备完成证书申请、事实收集、目录获取/应用与报告上报的完整闭环。读完本文你将掌握 device.conf 的编写语法、puppet device全部命令行参数与退出码语义、四种工作模式常规运行 / --facts / --resource / --apply的用法并从源码层面理解每个行为背后的实现原理。本文基于当前仓库中由源码自动生成的官方手册 references/man/device.md并对照 lib/puppet/application/device.rb、lib/puppet/util/network_device/config.rb 等源码与 spec/unit/application/device_spec.rb 测试用例展开。一、概述为什么要用 proxy agent 管理网络设备puppet-device的功能一句话概括是Retrieves catalogs from the Puppet master and applies them to remote devices——从 Puppet 主服务器获取目录catalog并将它们应用到远程设备上。绝大多数网络设备如 Cisco IOS、华为等设备无法安装完整的 Puppet agent。因此 Puppet 设计了代理 agent模式一台可以访问这些设备的普通 Puppet agent 节点充当 proxy代表设备与 Puppet 主服务器通信。文档原文明确说明了这一架构Devices require a proxy Puppet agent to request certificates, collect facts, retrieve and apply catalogs, and store reports.也就是说proxy agent 为每台设备承担四类工作request certificates—— 以设备的 certname 申请并维护证书每台设备拥有独立的 SSL 目录collect facts—— 通过设备专属的 facts terminusnetwork_device从设备采集事实retrieve and apply catalogs—— 从主服务器拉取目录并应用到设备store reports—— 把运行报告回传给主服务器。该子命令可以手动运行也可以借助 cron、计划任务等工具周期性执行This subcommand can be run manually; or periodically using cron, a scheduled task, or a similar tool.在源码中lib/puppet/application/device.rb 通过app_defaults定义了该子命令的专属默认值从侧面印证了上述架构对应测试见 spec/unit/application/device_spec.rb 中的 defaults the catalog_terminus setting to rest 等用例def app_defaults super.merge({ :catalog_terminus :rest, # 目录从主服务器(REST)获取 :catalog_cache_terminus :json, # 目录本地 JSON 缓存 :node_terminus :rest, # 节点信息走 REST :facts_terminus :network_device, # 事实从网络设备采集 }) end注意puppet device以:agent运行模式启动run_mode :agent因此它继承了 agent 的证书、目录缓存等行为。二、USAGE完整命令行语法puppet device的完整用法如下与官方手册及puppet device --help输出一致puppet device [-h|--help] [-v|--verbose] [-d|--debug] [-l|--logdest syslog|file|console] [--detailed-exitcodes] [--deviceconfig file] [-w|--waitforcert seconds] [--libdir directory] [-a|--apply file] [-f|--facts] [-r|--resource type [name]] [-t|--target device] [--useruser] [-V|--version]一个最典型的最小化运行示例$ puppet device --target remotehost --verbose这条命令的含义是只对device.conf中 certname 为remotehost的那台设备执行一次完整设备运行拉取目录、应用配置、上报报告并开启 verbose 日志。重要通用规则任何在配置文件puppet.conf中合法的设置项都可以作为长参数传入例如server是合法配置参数因此可以直接写--server servername。三、device.conf设备的注册清单3.1 文件位置与格式被puppet device管理的设备配置在device.conf中默认路径$confdir/device.conf可通过--deviceconfig file参数或$deviceconfig设置项覆盖。对应设置项定义在 lib/puppet/defaults.rbsettings 分组:devicesettings.define_settings(:device, :devicedir { :default $vardir/devices, :type :directory, :mode 0750, :owner service, :group service, :desc The root directory of devices $vardir., }, :deviceconfig { :default $confdir/device.conf, :desc Path to the device config file for puppet device., } )device.conf 是一个INI 风格文件每个设备一个 section格式如下[DEVICE_CERTNAME] type TYPE url URL debug各部分语义行含义[DEVICE_CERTNAME]section 名即该设备的certname证书名称type TYPE设备类型provider对应具体的网络设备实现url URL设备访问地址type与url的具体取值随设备类型而异debug可选属性开启传输层调试仅 telnet 与 ssh 传输可用3.2 解析器源码语法细节与校验逻辑lib/puppet/util/network_device/config.rb 实现了 device.conf 的解析其parse方法揭示了若干容易被忽略的细节注释与空行以#开头的行和空行会被跳过section 匹配只接受形如^\[([\w.-])\]$的 section 名单词字符、点、连字符重复定义同一设备会直接报错Duplicate device found at ...指令白名单每一行只允许type、url、debug三种指令正则^\s*(type|url|debug)(\s(.)\s*)*$其他内容一律报 Invalid entry at ...url 校验url指令的值会先经过URI.parse校验非法 URL 会报 ...is an invalid urldebug 开关debug指令会把device.options[:debug]置为true见parse_directive。解析结果被包装为OpenStruct包含namecertname、providertype 值、url、options等字段。3.3 type 与 url 的语义从设备基类看传输层解析type的值决定了加载哪个设备实现。在 lib/puppet/util/network_device.rb 的init方法中def self.init(device) require puppet/util/network_device/#{device.provider}/device current Puppet::Util::NetworkDevice.const_get(device.provider.capitalize).const_get(:Device).new(device.url, device.options) rescue detail raise detail, _(Cant load %{provider} for %{device}: %{detail}) % { provider: device.provider, device: device.name, detail: detail } end即type直接对应puppet/util/network_device/type/device下的实现类加载失败时会明确提示 Cant load for 。设备基类 lib/puppet/util/network_device/base.rb 则展示了url的完整解析约定url按URI解析scheme决定传输类型ssh、telnet 等通过 Autoloader 加载对应transport/scheme实现端口默认值未显式指定端口时ssh默认 22、telnet默认 23用户名与密码从 URL 的user:passwordhost部分提取用于建立传输连接。典型的url形如ssh://user:passtesthost或https://user:passtesthost/some/path后者可见于测试用例 spec/unit/application/device_spec.rb 的 device_hash 定义。四、OPTIONS全部命令行参数详解通用规则再强调一次任何在配置文件里合法的设置项都可以作为长参数传给本命令例如--server servername。参数说明--help, -h打印帮助信息--verbose, -v开启 verbose 报告--debug, -d开启完整调试输出--logdest, -l日志去向syslogPOSIX syslog 服务、console或日志文件路径支持逗号分隔多目的地如/path/file1,console,/path/file2。开启 debug/verbose 时默认console否则默认syslog。以.json结尾的路径接收 JSON 结构化日志由于日志是追加写入文件末尾不会自动补]需手动追加以构成合法 JSON--detailed-exitcodes通过退出码携带事务信息见下文退出码语义--deviceconfig设备配置文件路径默认$confdir/device.conf--waitforcert, -w仅对尚未持有证书的目标生效默认启用且值为 120秒即每 2 分钟轮询主服务器请求签署证书设为 0 可关闭等待。适用于目标设备的初始配置--libdir用本地目录覆盖每设备的 libdir指定 libdir 同时会禁用 pluginsync适合测试场景。以.jsonl结尾的路径接收 JSON Lines 结构化输出--apply针对远程目标应用一份 manifest必须同时指定--target--facts显示远程目标的事实必须同时指定--target--resource以 Puppet 代码形式显示资源状态功能近似于puppet resource可按 title 过滤必须同时指定--target--target指定 device.conf 中的某台设备/证书只对这台设备执行设备运行--to_yaml以 YAML 格式输出发现的资源适合配合 Hiera 与create_resources使用--user以指定用户身份运行4.1 参数校验逻辑源码确认lib/puppet/application/device.rb 的main方法开头对参数组合做了强校验对应测试见 spec/unit/application/device_spec.rb--resource未指定--target→ 报错resource command requires target--facts未指定--target→ 报错facts command requires target--apply未指定--target→ 报错missing argument: --target is required when using --apply--apply指定的 manifest 文件不存在 → 报错file does not exist, cannot apply--target指定的设备不在 device.conf 中 → 报错Target device / certificate name not found in deviceconfigdevice.conf 中没有任何设备 → 输出错误并exit(1)。4.2 各参数在源码中的对应实现--target、--waitforcert、--apply、--resource、--facts、--to_yaml、--libdir、--logdest、--detailed-exitcodes均在option声明中注册见lib/puppet/application/device.rb的option(...)区块--waitforcert的值被转为整数存入options[:waitforcert]随后在setup_context中传给Puppet::SSL::StateMachine.new(waitforcert: ...)用于证书签发等待测试 defaults waitforcert to 0、uses a default value for waitforcert when --onetime and --waitforcert are not specified 验证了默认 120 秒的行为运行--resource/--facts/--apply三种模式时setup方法会把日志目的地强制设为:console因为它们本质是交互式查询。五、四种工作模式puppet device依据参数组合进入四种不同模式5.1 常规设备运行默认模式不带--resource/--facts/--apply时对所有或--target指定的设备执行完整运行为设备创建专属目录并设置隔离的ssldir/confdir/libdir/vardir/certname见下文多设备隔离调用setup_context建立 SSL 上下文必要时等待证书签发未指定--libdir时执行 pluginsync下载设备插件通过Puppet::Util::NetworkDevice.init(device)初始化设备单例创建Puppet::Configurer并调用configurer.run(:network_device true, :pluginsync false)完成目录获取、应用与报告上报。启动日志会打印目标与连接信息形如starting applying configuration to device1 at ssh://testhost5.2 --facts查看远程设备事实$ puppet device --target remotehost --facts通过Puppet::Node::Facts.indirection.find从设备采集事实并以:console渲染器输出。事实的采集实现位于 lib/puppet/indirector/facts/network_device.rbdef find(request) result Puppet::Node::Facts.new(request.key, Puppet::Util::NetworkDevice.current.facts) result.add_local_facts result.sanitize result end即从当前设备单例的facts方法取得事实再补充本地事实并做清洗处理。该 terminus 明确禁止远程请求allow_remote_requests?返回false且destroy/save都会抛出DevError——它只负责从远程设备读取事实。5.3 --resource查看设备资源状态$ puppet device --target remotehost --resource user $ puppet device --target remotehost --resource user jim用法与puppet resource类似可指定类型与可选的 title指定 name →Puppet::Resource.indirection.find(type/name)查找单个资源不指定 name →Puppet::Resource.indirection.search(type/, {})搜索该类型全部资源。输出为 Puppet 代码形式的资源声明如user { jim: ensure absent }。配合--to_yaml时输出 YAML形如--- user: title: ensure: absent适用于 Hiera 数据与create_resources。注意未指定类型时直接报错You must specify the type to display类型不存在时报Could not find type type。5.4 --apply直接把 manifest 应用到设备$ puppet device --target remotehost --apply site.pp针对远程目标应用本地 manifest。从源码看该模式会把报告 terminus 改为:yaml避免向服务器上报纯本地应用关闭目录缓存catalog_cache_terminus nil将node_terminus设为:plain、catalog_terminus设为:compiler本地编译目录保持facts_terminus :network_device事实仍从设备采集在:network_device true覆盖下复用puppet apply的执行逻辑Puppet::Application::Apply.new(...).run_command。六、退出码语义--detailed-exitcodes启用--detailed-exitcodes后退出码携带完整的事务信息退出码含义1至少一台设备发生编译失败2至少一台设备发生资源变更4至少一台设备发生资源失败3/5/6/7上述退出码的按位组合例如31|2既有编译失败又有资源变更71|2|4三类情况同时发生。源码实现lib/puppet/application/device.rb的main结尾每台设备的运行结果被收集后在--detailed-exitcodes下用按位或合并exit(returns.compact.reduce(:|))。测试用例也覆盖了这些语义例如 exits 6 when --detailed-exitcodes and failed run6 2|4与 exits 1 when --detailed-exitcodes and failed parse7 1|2|4。未启用--detailed-exitcodes时任一设备返回 1 则整体退出 1否则退出 0。七、多设备隔离机制每设备独立的目录与证书这是puppet device区别于普通 agent 的关键设计。在 lib/puppet/application/device.rb 的main中处理每台设备时会临时覆盖本地设置并在ensure中恢复设置每设备取值说明ssldir$deviceconfdir/设备certname/ssl设备独立的 SSL 目录confdir$devicedir/设备certname设备独立的 conf 目录libdir--libdir指定值或$devicedir/设备certname/lib设备插件目录vardir$devicedir/设备certname设备独立的数据目录certname设备 section 名设备身份其中$devicedir默认$vardir/devices$deviceconfdir默认$confdir/devices见 lib/puppet/defaults.rb 中的:devicedir与:deviceconfdir定义两者目录模式均为0750。对应测试用例 sets ssldir relative to the global confdir、sets vardir to the device vardir、sets certname to the device certname 等对此做了逐一验证。两点实现细节值得注意SSL 目录符号链接PUP-8736 的 workaroundSSL 证书实际存放在缓存目录之外并在$confdir/设备/ssl保留符号链接防止缓存清理时误删证书运行后恢复全局设置每台设备处理完含异常路径都会在ensure块中把libdir/vardir/confdir/ssldir/certname恢复为初始值确保多台设备之间互不污染测试 resets the vardir setting after the run、resets the certname setting after the run 验证了这一行为。八、networking 与 Provider 机制从资源到设备的调用链设备 provider 的基类位于 lib/puppet/provider/network_device.rb它定义了从设备读取资源 → 与 catalog 期望对比 → 生成变更的抽象骨架prefetch(resources)批量预取——对每个资源通过Puppet::Util::NetworkDevice.current当前设备单例或device(resource[:device_url])取得设备再调用lookup(device, name)查询真实状态据此为资源装配 provider存在则ensure :present否则ensure :absentcreate/destroy/flush在property_hash中维护期望状态最终由具体 provider 实现落盘到设备instances默认为空实现具体设备 provider 需自行实现。结合 lib/puppet/util/network_device.rb 的单例初始化与 lib/puppet/indirector/facts/network_device.rb 的事实 terminus整个数据流可以概括为puppet device └─ Puppet::Util::NetworkDevice.init(device) # 按 type 加载设备实现并建立传输 ├─ facts terminus (network_device) # 设备事实 → catalog 编译输入 └─ provider 基类 prefetch/lookup # 设备实时状态 → 资源对账即事实经 network_device terminus 进入目录编译资源状态经 provider 基类的 prefetch 机制与目录期望对比最终由设备实现把变更写回设备。九、与 puppet agent 的关系及适用场景适用场景网络设备如交换机、路由器、防火墙无法承载完整 agent需要通过一台可达这些设备的 proxy agent 代为管理puppet device正是这一场景的标准入口周期性运行文档明确指出可用 cron、计划任务等方式周期调用实现设备的持续配置管理证书生命周期--waitforcert默认 120 秒的轮询机制专门服务于新设备首次接入CSR 等待主服务器签署签署完成后即可正常执行测试友好--libdir覆盖本地目录并禁用 pluginsync便于在不依赖插件分发的情况下调试设备 provider。十、常见问题速查现象原因与处理resource command requires target--resource/--facts必须与--target搭配missing argument: --target is required when using --apply--apply必须指定--targetTarget device / certificate xxx not found in ...device.conf 中不存在该 certname检查 section 名与--deviceconfig路径Duplicate device found at ...device.conf 中重复定义了同一设备 sectionCant load type for devicetype值没有对应的设备实现puppet/util/network_device/type/device退出码3/5/6/7--detailed-exitcodes下按位组合1编译失败、2资源变更、4资源失败首次接入设备一直等待--waitforcert 120默认每 2 分钟轮询一次请求签署证书可去主服务器侧签署或设-w 0跳过等待延伸阅读仓库内命令入口与全部模式实现lib/puppet/application/device.rbdevice.conf 解析器INI 语法、校验、报错信息lib/puppet/util/network_device/config.rb设备单例初始化与 provider 按 type 加载lib/puppet/util/network_device.rb设备实现基类URL/传输解析约定lib/puppet/util/network_device/base.rb设备事实 terminuslib/puppet/indirector/facts/network_device.rb网络设备 provider 基类lib/puppet/provider/network_device.rb相关设置项devicedir/deviceconfig/deviceconfdirlib/puppet/defaults.rb单元测试参数、隔离、退出码、四种模式的行为验证spec/unit/application/device_spec.rb官方手册原文references/man/device.md本文依据仓库内 references/man/device.md 编写相关实现与行为均对照 lib/puppet/application/device.rb 等源码及 spec/unit/application/device_spec.rb 测试用例核实。赞分享运维DevOpsIaC【免费下载链接】puppetServer automation framework and application项目地址https://gitcode.com/gh_mirrors/pu/puppet点击查看免费下载相关推荐Developer Device Platform通过 Device Catalog 查询设备详情Describe Device并预留远程 Android 设备实战Developer Device Platform通过 Device Catalog 查询设备详情Describe Device并预留远程 AndroidAI 技能人工智能大模型Salt Delta Proxy Minion 安装与配置实战指南用单个 minion 管理海量网络设备Salt Delta Proxy Minion 安装与配置实战指南用单个 minion 管理海量网络设备 本指南是 Salt 项目官方文档 doc/ref/运维配置管理后端终极指南如何使用Netmiko实现网络设备配置的批量自动化管理终极指南如何使用Netmiko实现网络设备配置的批量自动化管理 Netmiko作为一款多厂商网络设备SSH连接管理库能够帮助网络工程师轻松实现对Cisco、网络通信后端上一篇深入解析Graphtage结构化数据的语义比较与合并工具下一篇MinIO 使用 KMS 加密 IAM 与配置数据MINIO_KMS_SECRET_KEY 静态密钥与 KES 接入实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考