给出以下示例:
[root@puppet ~]# cat notify_test.pp
define test (
Boolean $condition = false,
) {
if $condition {
notify { "Debug Output of Test[${title}]": }
}
}
$test_resource_name_a = 'A'
test { $test_resource_name_a:
condition => true,
}
$test_resource_name_b = 'B'
test { $test_resource_name_b: }
exec { 'TestExec':
refreshonly => true,
command => '/usr/bin/echo "Mock Service Refresh"',
logoutput => true,
subscribe => Test[$test_resource_name_a, $test_resource_name_b],
}
仅应将某些内容打印到代理,但由于资源包含,显然会刷新所有订阅资源(请参阅https://puppet.com/docs/puppet/4.10/lang_containment.html)。不需要的结果:
[root@puppet ~]# puppet apply notify_test.pp
Notice: Compiled catalog for puppet in environment production in 0.10 seconds
Notice: Debug Output of Test[A]
Notice: /Stage[main]/Main/Test[A]/Notify[Debug Output of Test[A]]/message: defined 'message' as 'Debug Output of Test[A]'
Notice: /Stage[main]/Main/Exec[TestExec]/returns: Mock Service Refresh
Notice: /Stage[main]/Main/Exec[TestExec]: Triggered 'refresh' from 1 events
Notice: Applied catalog in 1.53 seconds
因此,只要满足条件(例如,使用HTTP客户端从REST API获取数据的自定义函数,我使用的是我的清单,但对目录编译没有真正的影响),所有订阅者(例如服务)将在每个30分钟。
这种行为是不可接受的,那么如何在不通知/刷新自动包含的资源的情况下将内容打印到人偶代理(puppet agent -t
)?
答案 0 :(得分:0)
这是将Notify
建模为资源时固有的限制。根据定义和设计,如果资源最初与目标系统同步,则应用资源不会执行任何操作。为了使Notify
资源执行任何操作(即发出其消息),它们总是始终不同步,发出这些消息会使它们同步。您可以根据需要将其概念化为从“未打印”到“已打印”的过渡。
但这意味着从Puppet的角度来看,每个Notify
资源在每次应用时都会更改。这样会生成一个事件,该事件将传播到Notify
的容器中并向前传播。
这种行为是不可接受的,因此我该如何打印一些东西到 没有通知/刷新的人偶代理(
puppet agent -t
) 自动包含的资源?
如果必须在 agent 的日志中(而不是主服务器的)记录消息,那么您的选择将受到限制。实际上,我能想到的最好的办法是编写一个始终同步的自定义资源类型和提供程序,但是无论如何都会向日志中发送消息。我测试了使用带有Exec
参数的unless
来发出消息,但是Puppet似乎没有打印unless
命令的输出。当然,Notify
是正确的。
如果将消息发送到 master 的日志中就足够了,那么可以使用一组功能来实现此目的。其中notice(),info()和debug()似乎最适合您的目的。
附带说明:“自动包含的资源”一词表示还有另一种。在Puppet 6之前,您可以在顶级范围内声明资源,这些资源仅包含在目录本身中,而不会将事件传播到其他任何东西。但是容器中声明的每个资源(类或定义的类型)都包含在该容器中。对我来说,那总是很自然的。通常,使人们感到不满意的原因是,只有在明确指定时,才包含类。这样做有充分的理由,但是我在这里不再赘述。