diff --git a/lib/puppet/provider/swift_internal_client_config/ini_setting.rb b/lib/puppet/provider/swift_internal_client_config/ini_setting.rb new file mode 100644 index 00000000..62fddd93 --- /dev/null +++ b/lib/puppet/provider/swift_internal_client_config/ini_setting.rb @@ -0,0 +1,10 @@ +Puppet::Type.type(:swift_internal_client_config).provide( + :ini_setting, + :parent => Puppet::Type.type(:openstack_config).provider(:ini_setting) +) do + + def self.file_path + '/etc/swift/internal-client.conf' + end + +end diff --git a/lib/puppet/type/swift_internal_client_config.rb b/lib/puppet/type/swift_internal_client_config.rb new file mode 100644 index 00000000..76382e93 --- /dev/null +++ b/lib/puppet/type/swift_internal_client_config.rb @@ -0,0 +1,53 @@ +Puppet::Type.newtype(:swift_internal_client_config) do + + ensurable + + newparam(:name, :namevar => true) do + desc 'Section/setting name to manage from /etc/swift/internal-client.conf' + newvalues(/\S+\/\S+/) + end + + newproperty(:value) do + desc 'The value of the setting to be defined.' + munge do |value| + value = value.to_s.strip + value.capitalize! if value =~ /^(true|false)$/i + value + end + newvalues(/^[\S ]*$/) + + def is_to_s( currentvalue ) + if resource.secret? + return '[old secret redacted]' + else + return currentvalue + end + end + + def should_to_s( newvalue ) + if resource.secret? + return '[new secret redacted]' + else + return newvalue + end + end + end + + newparam(:secret, :boolean => true) do + desc 'Whether to hide the value from Puppet logs. Defaults to `false`.' + + newvalues(:true, :false) + + defaultto false + end + + newparam(:ensure_absent_val) do + desc 'A value that is specified as the value property will behave as if ensure => absent was specified' + defaultto('') + end + + autorequire(:anchor) do + ['swift::install::end'] + end + +end diff --git a/manifests/config.pp b/manifests/config.pp index d31cc2d0..64768218 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -28,10 +28,16 @@ # (optional) Allow configuration of arbitrary Swift Proxy configurations. # The value is an hash of swift_proxy_config resources. # +# [*swift_internal_client_config*] +# (optional) Allow configuration of arbitrary Swift internal client +# configurations. +# The value is an hash of swift_internal_client_config resources. +# class swift::config ( $swift_config = {}, $swift_container_sync_realms_config = {}, $swift_proxy_config = {}, + $swift_internal_client_config = {}, ) { include swift::deps @@ -39,8 +45,10 @@ class swift::config ( validate_legacy(Hash, 'validate_hash', $swift_config) validate_legacy(Hash, 'validate_hash', $swift_container_sync_realms_config) validate_legacy(Hash, 'validate_hash', $swift_proxy_config) + validate_legacy(Hash, 'validate_hash', $swift_internal_client_config) create_resources('swift_config', $swift_config) create_resources('swift_container_sync_realms_config', $swift_container_sync_realms_config) create_resources('swift_proxy_config', $swift_proxy_config) + create_resources('swift_internal_client_config', $swift_internal_client_config) } diff --git a/manifests/deps.pp b/manifests/deps.pp index 8967aec6..5ee7eb7c 100644 --- a/manifests/deps.pp +++ b/manifests/deps.pp @@ -41,6 +41,10 @@ class swift::deps { -> Swift_account_config<||> ~> Anchor['swift::config::end'] + Anchor['swift::config::begin'] + -> Swift_internal_client_config<||> + ~> Anchor['swift::config::end'] + Anchor['swift::config::begin'] -> File<| tag == 'swift-file' |> -> Concat<| tag == 'swift-concat' |> diff --git a/manifests/internal_client.pp b/manifests/internal_client.pp new file mode 100644 index 00000000..89344c6a --- /dev/null +++ b/manifests/internal_client.pp @@ -0,0 +1,95 @@ +# == Class: swift::internal_client +# +# Configures internal client +# +# === Parameters +# +# [*user*] +# (optional) User to run as +# Defaults to $::swift::params::user. +# +# [*pipeline*] +# (optional) The list of elements of the internal client pipeline. +# Defaults to ['catch_errors', 'proxy-logging', 'cache', 'proxy-server'] +# +# [*object_chunk_size*] +# (optional) Chunk size to read from object servers. +# Defaults to $::os_service_default. +# +# [*client_chunk_size*] +# (optional) Chunk size to read from clients. +# Defaults to $::os_service_default. +# +# [*read_affinity*] +# (optional) Configures the read affinity of internal client. +# Defaults to undef. +# +# [*write_affinity*] +# (optional) Configures the write affinity of internal client. +# Defaults to $::os_service_default. +# +# [*write_affinity_node_count*] +# (optional) Configures write_affinity_node_count for internal client. +# Optional but requires write_affinity to be set. +# Defaults to $::os_service_default. +# +# [*client_timeout*] +# (optional) Configures client_timeout for internal client. +# Defaults to $::os_service_default. +# +# [*node_timeout*] +# (optional) Configures node_timeout for internal client. +# Defaults to $::os_service_default. +# +# [*recoverable_node_timeout*] +# (optional) Configures recoverable_node_timeout for internal client. +# Defaults to $::os_service_default. +# +class swift::internal_client ( + $user = $::swift::params::user, + $pipeline = ['catch_errors', 'proxy-logging', 'cache', 'proxy-server'], + $object_chunk_size = $::os_service_default, + $client_chunk_size = $::os_service_default, + $read_affinity = undef, + $write_affinity = $::os_service_default, + $write_affinity_node_count = $::os_service_default, + $client_timeout = $::os_service_default, + $node_timeout = $::os_service_default, + $recoverable_node_timeout = $::os_service_default, +) inherits swift::params { + + include swift::deps + + validate_legacy(Array, 'validate_array', $pipeline) + + if(! member($pipeline, 'proxy-server')) { + warning('pipeline parameter must contain proxy-server') + } + + swift_internal_client_config { + 'DEFAULT/user': value => $user; + 'pipeline:main/pipeline': value => join($pipeline, ' '); + 'app:proxy-server/use': value => 'egg:swift#proxy'; + 'app:proxy-server/account_autocreate': value => true; + 'app:proxy-server/object_chunk_size': value => $object_chunk_size; + 'app:proxy-server/client_chunk_size': value => $client_chunk_size; + 'app:proxy-server/write_affinity': value => $write_affinity; + 'app:proxy-server/write_affinity_node_count': value => $write_affinity_node_count; + 'app:proxy-server/client_timeout': value => $client_timeout; + 'app:proxy-server/node_timeout': value => $node_timeout; + 'app:proxy-server/recoverable_node_timeout': value => $recoverable_node_timeout; + } + + if $read_affinity { + swift_internal_client_config { + 'app:proxy-server/sorting_method': value => 'affinity'; + 'app:proxy-server/read_affinity': value => $read_affinity; + } + } else { + swift_internal_client_config { + 'app:proxy-server/sorting_method': value => $::os_service_default; + 'app:proxy-server/read_affinity': value => $::os_service_default; + } + } + +} diff --git a/manifests/internal_client/cache.pp b/manifests/internal_client/cache.pp new file mode 100644 index 00000000..f529d600 --- /dev/null +++ b/manifests/internal_client/cache.pp @@ -0,0 +1,76 @@ +# +# Configures the swift proxy memcache server +# +# [*memcache_servers*] A list of the memcache servers to be used. Entries +# should be in the form host:port. +# +# [*tls_enabled*] +# (Optional) Global toggle for TLS usage when communicating with +# the caching servers. +# Default to false +# +# [*tls_cafile*] +# (Optional) Path to a file of concatenated CA certificates in PEM +# format necessary to establish the caching server's authenticity. +# If tls_enabled is False, this option is ignored. +# Defaults to undef +# +# [*tls_certfile*] +# (Optional) Path to a single file in PEM format containing the +# client's certificate as well as any number of CA certificates +# needed to establish the certificate's authenticity. This file +# is only required when client side authentication is necessary. +# If tls_enabled is False, this option is ignored. +# Defaults to undef +# +# [*tls_keyfile*] +# (Optional) Path to a single file containing the client's private +# key in. Otherwise the private key will be taken from the file +# specified in tls_certfile. If tls_enabled is False, this option +# is ignored. +# Defaults to undef +# +# [*memcache_max_connections*] Sets the maximum number of connections to +# each memcached server per worker +# +# == Dependencies +# +# Class['memcached'] +# +# == Examples +# +# == Authors +# +# Dan Bode dan@puppetlabs.com +# +# == Copyright +# +# Copyright 2011 Puppetlabs Inc, unless otherwise noted. +# +class swift::internal_client::cache( + $memcache_servers = ['127.0.0.1:11211'], + $tls_enabled = false, + $tls_cafile = undef, + $tls_certfile = undef, + $tls_keyfile = undef, + $memcache_max_connections = '2' +) { + + include swift::deps + + # require the memcached class if its on the same machine + if !empty(grep(any2array($memcache_servers), '127.0.0.1')) { + Class['memcached'] -> Class['swift::internal_client::cache'] + } + + swift_internal_client_config { + 'filter:cache/use': value => 'egg:swift#memcache'; + 'filter:cache/memcache_servers': value => join(any2array($memcache_servers), ','); + 'filter:cache/tls_enabled': value => $tls_enabled; + 'filter:cache/tls_cafile': value => $tls_cafile; + 'filter:cache/tls_certfile': value => $tls_certfile; + 'filter:cache/tls_keyfile': value => $tls_keyfile; + 'filter:cache/memcache_max_connections': value => $memcache_max_connections; + } + +} diff --git a/manifests/internal_client/catch_errors.pp b/manifests/internal_client/catch_errors.pp new file mode 100644 index 00000000..7ce6b8ce --- /dev/null +++ b/manifests/internal_client/catch_errors.pp @@ -0,0 +1,25 @@ +# +# Configure swift cache_errors. +# +# == Dependencies +# +# == Examples +# +# include swift::internal_client::catch_errors +# +# == Authors +# +# Francois Charlier fcharlier@ploup.net +# +# == Copyright +# +# Copyright 2012 eNovance licensing@enovance.com +# +class swift::internal_client::catch_errors() { + + include swift::deps + + swift_internal_client_config { + 'filter:catch_errors/use': value => 'egg:swift#catch_errors'; + } +} diff --git a/manifests/internal_client/proxy_logging.pp b/manifests/internal_client/proxy_logging.pp new file mode 100644 index 00000000..a1976435 --- /dev/null +++ b/manifests/internal_client/proxy_logging.pp @@ -0,0 +1,15 @@ +# +# Configure swift proxy-logging. +# +# == Authors +# +# Joe Topjian joe@topjian.net +# +class swift::internal_client::proxy_logging { + + include swift::deps + + swift_internal_client_config { + 'filter:proxy-logging/use': value => 'egg:swift#proxy_logging'; + } +} diff --git a/manifests/internal_client/symlink.pp b/manifests/internal_client/symlink.pp new file mode 100644 index 00000000..db6c4f53 --- /dev/null +++ b/manifests/internal_client/symlink.pp @@ -0,0 +1,42 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Configure swift symlink middleware. +# +# == Example +# +# include swift::internal_client::symlink +# +# == Parameters +# +# [*symloop_max*] +# Symlinks can point to other symlinks provided the number of symlinks in a +# chain does not exceed the symloop_max value. If the number of chained +# symlinks exceeds the limit symloop_max a 409 (HTTPConflict) error +# response will be produced. +# Default to $::os_service_default +# +# == Authors +# +# shi.yan@ardc.edu.au +# +class swift::internal_client::symlink( + $symloop_max = $::os_service_default, +) { + + include swift::deps + + swift_internal_client_config { + 'filter:symlink/use': value => 'egg:swift#symlink'; + 'filter:symlink/symloop_max': value => $symloop_max; + } +} diff --git a/releasenotes/notes/internal-client-ce022fa93df88aaa.yaml b/releasenotes/notes/internal-client-ce022fa93df88aaa.yaml new file mode 100644 index 00000000..aac0ceb3 --- /dev/null +++ b/releasenotes/notes/internal-client-ce022fa93df88aaa.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Now this module supports configurion options in + `/etc/swift/internal-client.conf``. diff --git a/spec/classes/swift_config_spec.rb b/spec/classes/swift_config_spec.rb index 6870edb7..41c17e4c 100644 --- a/spec/classes/swift_config_spec.rb +++ b/spec/classes/swift_config_spec.rb @@ -11,6 +11,11 @@ describe 'swift::config' do 'DEFAULT/foo' => { 'value' => 'fooValue' }, 'DEFAULT/bar' => { 'value' => 'barValue' }, 'DEFAULT/baz' => { 'ensure' => 'absent' } + }, + :swift_internal_client_config => { + 'DEFAULT/foo' => { 'value' => 'fooValue' }, + 'DEFAULT/bar' => { 'value' => 'barValue' }, + 'DEFAULT/baz' => { 'ensure' => 'absent' } } } end @@ -27,6 +32,12 @@ describe 'swift::config' do is_expected.to contain_swift_proxy_config('DEFAULT/bar').with_value('barValue') is_expected.to contain_swift_proxy_config('DEFAULT/baz').with_ensure('absent') end + + it 'configures arbitrary swift internal client configurations' do + is_expected.to contain_swift_internal_client_config('DEFAULT/foo').with_value('fooValue') + is_expected.to contain_swift_internal_client_config('DEFAULT/bar').with_value('barValue') + is_expected.to contain_swift_internal_client_config('DEFAULT/baz').with_ensure('absent') + end end on_supported_os({ diff --git a/spec/classes/swift_internal_client_cache_spec.rb b/spec/classes/swift_internal_client_cache_spec.rb new file mode 100644 index 00000000..4971a372 --- /dev/null +++ b/spec/classes/swift_internal_client_cache_spec.rb @@ -0,0 +1,78 @@ +require 'spec_helper' + +describe 'swift::internal_client::cache' do + shared_examples 'swift::internal_client::cache' do + + describe 'without memcached being included' do + it 'should raise an error' do + expect { catalogue }.to raise_error(Puppet::Error) + end + end + + describe 'with memcached dependency' do + let :pre_condition do + 'class { "memcached": max_memory => 1 }' + end + + describe 'with defaults' do + it 'should have the required classes' do + is_expected.to contain_class('swift::deps') + is_expected.to contain_class('swift::internal_client::cache') + end + + it { is_expected.to contain_swift_internal_client_config('filter:cache/use').with_value('egg:swift#memcache') } + it { is_expected.to contain_swift_internal_client_config('filter:cache/memcache_servers').with_value('127.0.0.1:11211') } + it { is_expected.to contain_swift_internal_client_config('filter:cache/tls_enabled').with_value(false) } + it { is_expected.to contain_swift_internal_client_config('filter:cache/memcache_max_connections').with_value(2) } + end + + describe 'with overridden memcache server' do + let :params do + {:memcache_servers => '10.0.0.1:1'} + end + + it { is_expected.to contain_swift_internal_client_config('filter:cache/use').with_value('egg:swift#memcache') } + it { is_expected.to contain_swift_internal_client_config('filter:cache/memcache_servers').with_value('10.0.0.1:1') } + end + + describe 'with overridden memcache server array' do + let :params do + {:memcache_servers => ['10.0.0.1:1', '10.0.0.2:2']} + end + + it { is_expected.to contain_swift_internal_client_config('filter:cache/use').with_value('egg:swift#memcache') } + it { is_expected.to contain_swift_internal_client_config('filter:cache/memcache_servers').with_value('10.0.0.1:1,10.0.0.2:2') } + end + + describe 'with overridden cache TLS enabled' do + let :params do + {:tls_enabled => true} + end + + it { is_expected.to contain_swift_internal_client_config('filter:cache/use').with_value('egg:swift#memcache') } + it { is_expected.to contain_swift_internal_client_config('filter:cache/tls_enabled').with_value(true) } + end + + describe 'with overridden memcache max connections' do + let :params do + {:memcache_max_connections => 4} + end + + it { is_expected.to contain_swift_internal_client_config('filter:cache/use').with_value('egg:swift#memcache') } + it { is_expected.to contain_swift_internal_client_config('filter:cache/memcache_max_connections').with_value(4) } + end + end + end + + on_supported_os({ + :supported_os => OSDefaults.get_supported_os + }).each do |os,facts| + context "on #{os}" do + let (:facts) do + facts.merge(OSDefaults.get_facts()) + end + + it_configures 'swift::internal_client::cache' + end + end +end diff --git a/spec/classes/swift_internal_client_catch_errors_spec.rb b/spec/classes/swift_internal_client_catch_errors_spec.rb new file mode 100644 index 00000000..72ac176f --- /dev/null +++ b/spec/classes/swift_internal_client_catch_errors_spec.rb @@ -0,0 +1,19 @@ +require 'spec_helper' + +describe 'swift::internal_client::catch_errors' do + shared_examples 'swift::internal_client::catch_errors' do + it { should contain_swift_internal_client_config('filter:catch_errors/use').with_value('egg:swift#catch_errors') } + end + + on_supported_os({ + :supported_os => OSDefaults.get_supported_os + }).each do |os,facts| + context "on #{os}" do + let (:facts) do + facts.merge(OSDefaults.get_facts()) + end + + it_configures 'swift::internal_client::catch_errors' + end + end +end diff --git a/spec/classes/swift_internal_client_spec.rb b/spec/classes/swift_internal_client_spec.rb new file mode 100644 index 00000000..a53c1a8c --- /dev/null +++ b/spec/classes/swift_internal_client_spec.rb @@ -0,0 +1,73 @@ +require 'spec_helper' + +describe 'swift::internal_client' do + shared_examples 'swift::internal_client' do + + let :pre_condition do + "class { memcached: max_memory => 1} + class { swift: swift_hash_path_suffix => string } + include swift::internal_client::catch_errors + include swift::internal_client::proxy_logging + include swift::internal_client::cache" + end + + context 'with defaults' do + it 'should configure default values' do + should contain_swift_internal_client_config('DEFAULT/user').with_value('swift') + should contain_swift_internal_client_config('pipeline:main/pipeline').with_value('catch_errors proxy-logging cache proxy-server') + should contain_swift_internal_client_config('app:proxy-server/use').with_value('egg:swift#proxy') + should contain_swift_internal_client_config('app:proxy-server/account_autocreate').with_value(true) + should contain_swift_internal_client_config('app:proxy-server/object_chunk_size').with_value('') + should contain_swift_internal_client_config('app:proxy-server/client_chunk_size').with_value('') + should contain_swift_internal_client_config('app:proxy-server/sorting_method').with_value('') + should contain_swift_internal_client_config('app:proxy-server/read_affinity').with_value('') + should contain_swift_internal_client_config('app:proxy-server/write_affinity').with_value('') + should contain_swift_internal_client_config('app:proxy-server/write_affinity_node_count').with_value('') + should contain_swift_internal_client_config('app:proxy-server/client_timeout').with_value('') + should contain_swift_internal_client_config('app:proxy-server/node_timeout').with_value('') + should contain_swift_internal_client_config('app:proxy-server/recoverable_node_timeout').with_value('') + end + end + + context 'with parameters' do + let :params do + { + :pipeline => ['catch_errors', 'proxy-logging', 'proxy-server'], + :object_chunk_size => 65536, + :client_chunk_size => 65535, + :read_affinity => 'r1z1=100, r1=200', + :write_affinity => 'r1', + :write_affinity_node_count => '2 * replicas', + :client_timeout => '120', + :node_timeout => '20', + :recoverable_node_timeout => '15', + } + end + + it 'should configure the given values' do + should contain_swift_internal_client_config('pipeline:main/pipeline').with_value('catch_errors proxy-logging proxy-server') + should contain_swift_internal_client_config('app:proxy-server/object_chunk_size').with_value(65536) + should contain_swift_internal_client_config('app:proxy-server/client_chunk_size').with_value(65535) + should contain_swift_internal_client_config('app:proxy-server/sorting_method').with_value('affinity') + should contain_swift_internal_client_config('app:proxy-server/read_affinity').with_value('r1z1=100, r1=200') + should contain_swift_internal_client_config('app:proxy-server/write_affinity').with_value('r1') + should contain_swift_internal_client_config('app:proxy-server/write_affinity_node_count').with_value('2 * replicas') + should contain_swift_internal_client_config('app:proxy-server/client_timeout').with_value('120') + should contain_swift_internal_client_config('app:proxy-server/node_timeout').with_value('20') + should contain_swift_internal_client_config('app:proxy-server/recoverable_node_timeout').with_value('15') + end + end + end + + on_supported_os({ + :supported_os => OSDefaults.get_supported_os + }).each do |os,facts| + context "on #{os}" do + let (:facts) do + facts.merge(OSDefaults.get_facts()) + end + + it_behaves_like 'swift::internal_client' + end + end +end diff --git a/spec/classes/swift_internal_client_symlink_spec.rb b/spec/classes/swift_internal_client_symlink_spec.rb new file mode 100644 index 00000000..7b3788bc --- /dev/null +++ b/spec/classes/swift_internal_client_symlink_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' + +describe 'swift::internal_client::symlink' do + shared_examples 'swift::internal_client::symlink' do + context 'when using default parameters' do + it { is_expected.to contain_swift_internal_client_config('filter:symlink/use').with_value('egg:swift#symlink') } + it { is_expected.to contain_swift_internal_client_config('filter:symlink/symloop_max').with_value('') } + end + + context 'when overriding default parameters' do + let :params do + { + :symloop_max => '3' + } + end + + it { is_expected.to contain_swift_internal_client_config('filter:symlink/use').with_value('egg:swift#symlink') } + it { is_expected.to contain_swift_internal_client_config('filter:symlink/symloop_max').with_value('3') } + end + end + + on_supported_os({ + :supported_os => OSDefaults.get_supported_os + }).each do |os,facts| + context "on #{os}" do + let (:facts) do + facts.merge(OSDefaults.get_facts()) + end + + it_behaves_like 'swift::internal_client::symlink' + end + end +end diff --git a/spec/unit/provider/swift_internal_client_config/ini_setting_spec.rb b/spec/unit/provider/swift_internal_client_config/ini_setting_spec.rb new file mode 100644 index 00000000..3315c324 --- /dev/null +++ b/spec/unit/provider/swift_internal_client_config/ini_setting_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +provider_class = Puppet::Type.type(:swift_internal_client_config).provider(:ini_setting) + +describe provider_class do + + it 'should default to the default setting when no other one is specified' do + resource = Puppet::Type::Swift_internal_client_config.new( + { + :name => 'DEFAULT/foo', + :value => 'bar' + } + ) + provider = provider_class.new(resource) + expect(provider.section).to eq('DEFAULT') + expect(provider.setting).to eq('foo') + end + + it 'should allow setting to be set explicitly' do + resource = Puppet::Type::Swift_internal_client_config.new( + { + :name => 'dude/foo', + :value => 'bar' + } + ) + provider = provider_class.new(resource) + expect(provider.section).to eq('dude') + expect(provider.setting).to eq('foo') + end + + it 'should ensure absent when is specified as a value' do + resource = Puppet::Type::Swift_internal_client_config.new( + {:name => 'dude/foo', :value => ''} + ) + provider = provider_class.new(resource) + provider.exists? + expect(resource[:ensure]).to eq :absent + end + + it 'should ensure absent when value matches ensure_absent_val' do + resource = Puppet::Type::Swift_internal_client_config.new( + {:name => 'dude/foo', :value => 'foo', :ensure_absent_val => 'foo' } + ) + provider = provider_class.new(resource) + provider.exists? + expect(resource[:ensure]).to eq :absent + end + +end diff --git a/spec/unit/type/swift_internal_client_config_spec.rb b/spec/unit/type/swift_internal_client_config_spec.rb new file mode 100644 index 00000000..19cecfaf --- /dev/null +++ b/spec/unit/type/swift_internal_client_config_spec.rb @@ -0,0 +1,19 @@ +require 'puppet' +require 'puppet/type/swift_internal_client_config' + +describe 'Puppet::Type.type(:swift_internal_client_config)' do + before :each do + @swift_internal_client_config = Puppet::Type.type(:swift_internal_client_config).new(:name => 'DEFAULT/foo', :value => 'bar') + end + + it 'should autorequire the package that install the file' do + catalog = Puppet::Resource::Catalog.new + anchor = Puppet::Type.type(:anchor).new(:name => 'swift::install::end') + catalog.add_resource anchor, @swift_internal_client_config + dependency = @swift_internal_client_config.autorequire + expect(dependency.size).to eq(1) + expect(dependency[0].target).to eq(@swift_internal_client_config) + expect(dependency[0].source).to eq(anchor) + end + +end