diff --git a/lib/puppet/type/acl.rb b/lib/puppet/type/acl.rb index 6770f28..d99c6b1 100644 --- a/lib/puppet/type/acl.rb +++ b/lib/puppet/type/acl.rb @@ -1,4 +1,5 @@ require 'set' +require 'pathname' Puppet::Type.newtype(:acl) do desc <<-EOT @@ -67,11 +68,41 @@ defaultto :lazy end - autorequire(:file) do - if self[:path] - [self[:path]] + # Credits to @itdoesntwork + # http://stackoverflow.com/questions/26878341/how-do-i-tell-if-one-path-is-an-ancestor-of-another + def self.is_descendant?(a, b) + a_list = File.expand_path(a).split('/') + b_list = File.expand_path(b).split('/') + + b_list[0..a_list.size-1] == a_list + end + + # Snippet based on upstream Puppet (ASL 2.0) + [:acl, :file].each do | autorequire_type | + autorequire(autorequire_type) do + req = [] + path = Pathname.new(self[:path]) + if autorequire_type != :acl + if self[:recursive] == :true + catalog.resources.find_all { |r| + r.is_a?(Puppet::Type.type(:acl)) and self.class.is_descendant?(self[:path], r[:path]) + }.each do | found | + req << found[:path] + end + end + req << self[:path] + end + if !path.root? + # Start at our parent, to avoid autorequiring ourself + parents = path.parent.enum_for(:ascend) + if found = parents.find { |p| catalog.resource(autorequire_type, p.to_s) } + req << found.to_s + end + end + req end end + # End of Snippet newproperty(:permission, :array_matching => :all) do desc "ACL permission(s)." @@ -105,7 +136,7 @@ def strip_perms(pl) value = [] pl.each do |perm| if !(perm =~ /^(((u(ser)?)|(g(roup)?)|(m(ask)?)|(o(ther)?)):):/) - perm = perm.split(':')[0..-2].join(':') + perm = perm.split(':',-1)[0..-2].join(':') value << perm end end @@ -214,10 +245,10 @@ def insync?(is) def self.pick_default_perms(perms) non_default = perms.reject { |perm| perm =~ /^d/ } default = perms.reject { |perm| perm !~ /^d/ }.map { - |perm| perm.split(':')[1..-1].join(':') + |perm| perm.split(':',-1)[1..-1].join(':') } Set.new((non_default + default).map { |perm| - key = perm.split(':')[0..1].join(':') + key = perm.split(':',-1)[0..1].join(':') matching_default = default.reject { |tmp_perm| tmp_perm !~ /^#{key}:/ } if (matching_default.length > 0) matching_default diff --git a/spec/unit/puppet/type/acl_spec.rb b/spec/unit/puppet/type/acl_spec.rb index 2969827..766d1b1 100644 --- a/spec/unit/puppet/type/acl_spec.rb +++ b/spec/unit/puppet/type/acl_spec.rb @@ -133,12 +133,24 @@ basic_perms = ['user:foo:rwx', 'group:foo:rwx'] advanced_perms = ['user:foo:rwx', 'group:foo:rwx', 'default:user:foo:---'] advanced_perms_results = ['user:foo:---', 'group:foo:rwx'] + mysql_perms = [ + "user:mysql:rwx", + "d:user:mysql:rw", + "mask::rwx", + ] + mysql_perms_results = [ + "user:mysql:rw", + "mask::rwx", + ] it 'should not do anything with no defaults' do expect(acl_type.pick_default_perms(basic_perms)).to match_array(basic_perms) end it 'should override defaults' do expect(acl_type.pick_default_perms(advanced_perms)).to match_array(advanced_perms_results) end + it 'should override defaults with d: and a mask' do + expect(acl_type.pick_default_perms(mysql_perms)).to match_array(mysql_perms_results) + end end end