我正在尝试基于puppetlabs rabbitmq module中存在的现有提供程序为RabbitMQ开发自定义类型提供程序。
如果exists?
方法返回false - 一切正常。
但是,如果exists?
返回true,则puppet将失败并显示undefined method 'pattern'
异常(stacktrace bellow)。
请注意,pattern是我类型的参数之一。
我在CentOS上使用Puppet 3.1.1。
stacktrace:
Error: /Stage[main]//Node[rabbitmq]/Rabbitmq_policy[ha-all@DMITRY_CBMS]: Could not evaluate: undefined method `pattern' for #<Puppet::Type::Rabbitmq_policy::ProviderRabbitmqctl:0x7f5e647471f0>
/usr/lib/ruby/site_ruby/1.8/puppet/property.rb:462:in `send'
/usr/lib/ruby/site_ruby/1.8/puppet/property.rb:462:in `retrieve'
/usr/lib/ruby/site_ruby/1.8/puppet/type.rb:1027:in `retrieve'
/usr/lib/ruby/site_ruby/1.8/puppet/type.rb:1022:in `each'
/usr/lib/ruby/site_ruby/1.8/puppet/type.rb:1022:in `retrieve'
/usr/lib/ruby/site_ruby/1.8/puppet/type.rb:1041:in `retrieve_resource'
/usr/lib/ruby/site_ruby/1.8/puppet/transaction/resource_harness.rb:32:in `perform_changes'
/usr/lib/ruby/site_ruby/1.8/puppet/transaction/resource_harness.rb:133:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/transaction.rb:48:in `apply'
/usr/lib/ruby/site_ruby/1.8/puppet/transaction.rb:83:in `eval_resource'
/usr/lib/ruby/site_ruby/1.8/puppet/transaction.rb:103:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/util.rb:351:in `thinmark'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/usr/lib/ruby/site_ruby/1.8/puppet/util.rb:350:in `thinmark'
/usr/lib/ruby/site_ruby/1.8/puppet/transaction.rb:103:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/transaction.rb:382:in `traverse'
/usr/lib/ruby/site_ruby/1.8/puppet/transaction.rb:98:in `evaluate'
/usr/lib/ruby/site_ruby/1.8/puppet/resource/catalog.rb:144:in `apply'
/usr/lib/ruby/site_ruby/1.8/puppet/configurer.rb:122:in `apply_catalog'
/usr/lib/ruby/site_ruby/1.8/puppet/util.rb:179:in `benchmark'
/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/usr/lib/ruby/site_ruby/1.8/puppet/util.rb:178:in `benchmark'
/usr/lib/ruby/site_ruby/1.8/puppet/configurer.rb:121:in `apply_catalog'
/usr/lib/ruby/site_ruby/1.8/puppet/configurer.rb:179:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/agent.rb:45:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/agent/locker.rb:20:in `lock'
/usr/lib/ruby/site_ruby/1.8/puppet/agent.rb:45:in `run'
/usr/lib/ruby/1.8/sync.rb:230:in `synchronize'
/usr/lib/ruby/site_ruby/1.8/puppet/agent.rb:45:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/agent.rb:119:in `with_client'
/usr/lib/ruby/site_ruby/1.8/puppet/agent.rb:42:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/agent.rb:89:in `run_in_fork'
/usr/lib/ruby/site_ruby/1.8/puppet/agent.rb:86:in `fork'
/usr/lib/ruby/site_ruby/1.8/puppet/agent.rb:86:in `run_in_fork'
/usr/lib/ruby/site_ruby/1.8/puppet/agent.rb:41:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:179:in `call'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:179:in `controlled_run'
/usr/lib/ruby/site_ruby/1.8/puppet/agent.rb:39:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/daemon.rb:205:in `run_event_loop'
/usr/lib/ruby/site_ruby/1.8/puppet/daemon.rb:167:in `loop'
/usr/lib/ruby/site_ruby/1.8/puppet/daemon.rb:167:in `run_event_loop'
/usr/lib/ruby/site_ruby/1.8/puppet/daemon.rb:145:in `start'
/usr/lib/ruby/site_ruby/1.8/puppet/application/agent.rb:357:in `main'
/usr/lib/ruby/site_ruby/1.8/puppet/application/agent.rb:313:in `run_command'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:364:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:456:in `plugin_hook'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:364:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/util.rb:504:in `exit_on_fail'
/usr/lib/ruby/site_ruby/1.8/puppet/application.rb:364:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/util/command_line.rb:132:in `run'
/usr/lib/ruby/site_ruby/1.8/puppet/util/command_line.rb:86:in `execute'
类型定义:
Puppet::Type.newtype(:rabbitmq_policy) do
desc 'Type for defining rabbitmq policies'
ensurable do
defaultto(:present)
newvalue(:present) do
provider.create
end
newvalue(:absent) do
provider.destroy
end
end
newparam(:name, :namevar => true) do
desc 'combination of policy-name@vhost to setup the policy'
newvalues(/^\S+@\S+$/)
end
newproperty(:pattern) do
desc 'regexp representing configuration permissions'
validate do |value|
resource.validate_permissions(value)
end
end
newproperty(:definition) do
desc 'definition of this policit, e.g: {"ha-mode":"all"}'
end
autorequire(:rabbitmq_vhost) do
[self[:name].split('@')[1]]
end
autorequire(:rabbitmq_policy) do
[self[:name].split('@')[0]]
end
# I may want to dissalow whitespace
def validate_permissions(value)
begin
Regexp.new(value)
rescue RegexpError
raise ArgumentError, "Invalid regexp #{value}"
end
end
end
提供商定义:
Puppet::Type.type(:rabbitmq_policy).provide(:rabbitmqctl) do
commands :rabbitmqctl => 'rabbitmqctl'
defaultfor :feature => :posix
def policy_name
if @cached_policy_name
@cached_policy_name
else
@cached_policy_name = resource[:name].split('@')[0]
end
end
def vhost
if @cached_vhost
@cached_vhost
else
@cached_vhost = resource[:name].split('@')[1]
end
end
def create
Puppet.debug "rabbitmq_policy.create"
rabbitmqctl('set_policy','-p', vhost, policy_name, resource[:pattern], resource[:definition])
end
def destroy
Puppet.debug "rabbitmq_policy.destroy"
rabbitmqctl('clear_policy', '-p', vhost, policy_name)
end
def exists?
out = rabbitmqctl('list_policies', '-p', vhost).split(/\n/)[1..-2].collect do |line|
parts = line.split(/\s+/)
Puppet.debug "rabbitmq_policy::list_policies line: #{line}| #{parts[1]} == #{policy_name} => #{parts[1] == policy_name} "
if parts[1] == policy_name
true
else
false
end
end
out = out.detect do |obj| obj end
Puppet.debug "rabbitmq_policy.exists: #{out.to_s}"
out
end
#def exists?
# false
#end
end
非常感谢任何帮助。
谢谢
答案 0 :(得分:1)
找到答案(感谢Daniel在ask.puppetlabs.com)。
在类型定义中使用newproperty
定义的每个属性都必须在提供程序中具有相应的getter和setter。并且属性仅对其属性可以单独更新的类型有意义。
对于简单的情况,应该使用newparam
。