运行 Rspec 如果可以将变量传递给 Puppet 中的 class 则失败

Running Rspec fails if variables can be passed to a class in Puppet

问题

如果可以将变量传递给 Puppet class,例如:

class module_name (
  $variable='hello_world'
) {
  package { 'package_name': }
}

rspec 是 运行 它失败了,即:

[user@host module_name]$ rspec
...............................FFFFFFFFFFFF..........................................

Failures:

  1) opsview should contain Class[module_name]
     Failure/Error: it { should contain_class('module_name') }
     Puppet::Error:
       Error from DataBinding 'hiera' while looking up 'module_name::variable': 
       FileSystem implementation expected Pathname, got: 'Hash' on node host
     # /usr/share/ruby/vendor_ruby/puppet/resource.rb:393:
         in `rescue in lookup_with_databinding'
     # /usr/share/ruby/vendor_ruby/puppet/resource.rb:387:
         in `lookup_with_databinding'
     # /usr/share/ruby/vendor_ruby/puppet/resource.rb:381:
         in `lookup_external_default_for'

主要问题

Error from DataBinding while looking up FileSystem implementation expected Pathname, 
got: 'Hash' on node

配置

版本

[vagrant@vm-one opsview]$ puppet --version
3.7.5
[vagrant@vm-one opsview]$ rspec --version
3.2.2

Spec_helper

[vagrant@vm-one opsview]$ cat spec/spec_helper.rb
require 'rspec-puppet'
require 'hiera-puppet-helper'

fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures'))

RSpec.configure do |c|
  c.module_path = File.join(fixture_path, 'modules')
  c.manifest_dir = File.join(fixture_path, 'manifests')
  c.hiera_config = '/etc/puppet/hiera.yaml'
end

at_exit { RSpec::Puppet::Coverage.report! }

尝试

  1. 根据 this Q&A hiera-puppet-helper 导致 问题。 Rspec-puppet 似乎支持测试 hiera 和 'hiera-puppet-helper' 可以替换。好的,也许这可以解决问题,但是导致问题的原因是什么?
  2. This post 包含相同的问题,但不是解决方案 问题
  3. This post表示去掉class参数可以解决问题,但是这个class被多个模块使用,所以不是解决方案。

hiera_config有问题,应该是:

c.hiera_config = 'spec/fixtures/hiera/hiera.yaml'

假设您的目录结构如下:

  \spec
    \fixtures
      \hiera
        hiera.yaml
        default.yaml

hiera.yaml

---
:backends:
  - yaml
:hierarchy:
  - '%{::clientcert}'
  - default
:yaml:
  :datadir: './spec/fixtures/hiera'

hiera-puppet-helper gem 确实不需要,实际上不应该有。我建议使用 Garethr's skeleton 生成模块结构,它已经包含了 Hiera 的工作设置并且可以节省你很多时间。