]> gitweb.fluxo.info Git - puppet-stdlib.git/commitdiff
allow `match` parameter to influence `ensure => absent` behavior.
authorJohnson Earls <johnson.earls@oracle.com>
Thu, 6 Aug 2015 20:00:11 +0000 (13:00 -0700)
committerJohnson Earls <johnson.earls@oracle.com>
Thu, 6 Aug 2015 20:44:32 +0000 (13:44 -0700)
Split the `destroy` method of the file_type::ruby provider into two
private methods:  `handle_destroy_line` which is the same as the previous
`destroy` method, and `handle_destroy_with_match` which will destroy any
line which matches the `match` parameter, raising an error if multiple
lines match and the `multiple` parameter is not `true`.  This new
behavior is only used if the new boolean parameter `match_for_absence`
is `true` (it defaults to `false`).

lib/puppet/provider/file_line/ruby.rb
lib/puppet/type/file_line.rb
spec/unit/puppet/provider/file_line/ruby_spec.rb

index d4cdfec131863bb7d34e44eacf05d7af7cc9ef1b..aab6fe28921241ba056fbc8c25419791b5b8207b 100644 (file)
@@ -22,9 +22,10 @@ Puppet::Type.type(:file_line).provide(:ruby) do
   end
 
   def destroy
-    local_lines = lines
-    File.open(resource[:path],'w') do |fh|
-      fh.write(local_lines.reject{|l| l.chomp == resource[:line] }.join(''))
+    if resource[:match_for_absence].to_s == 'true' and resource[:match]
+      handle_destroy_with_match
+    else
+      handle_destroy_line
     end
   end
 
@@ -93,6 +94,25 @@ Puppet::Type.type(:file_line).provide(:ruby) do
     lines.select{|l| l.match(regex)}.size
   end
 
+  def handle_destroy_with_match
+    match_count = count_matches(match_regex)
+    if match_count > 1 && resource[:multiple].to_s != 'true'
+     raise Puppet::Error, "More than one line in file '#{resource[:path]}' matches pattern '#{resource[:match]}'"
+    end
+
+    local_lines = lines
+    File.open(resource[:path],'w') do |fh|
+      fh.write(local_lines.reject{|l| match_regex.match(l) }.join(''))
+    end
+  end
+
+  def handle_destroy_line
+    local_lines = lines
+    File.open(resource[:path],'w') do |fh|
+      fh.write(local_lines.reject{|l| l.chomp == resource[:line] }.join(''))
+    end
+  end
+
   ##
   # append the line to the file.
   #
index 4a96ba7ad37ef3649ef37ea6abce755290e5622a..446f103eb847fc18c7d9511fe81831cd90078271 100644 (file)
@@ -34,6 +34,20 @@ Puppet::Type.newtype(:file_line) do
     In this code example match will look for a line beginning with export 
     followed by HTTP_PROXY and replace it with the value in line.
 
+    Match Example With `ensure => absent`:
+
+        file_line { 'bashrc_proxy':
+          ensure            => absent,
+          path              => '/etc/bashrc',
+          line              => 'export HTTP_PROXY=http://squid.puppetlabs.vm:3128',
+          match             => '^export\ HTTP_PROXY\=',
+          match_for_absence => true,
+        }
+
+    In this code example match will look for a line beginning with export
+    followed by HTTP_PROXY and delete it.  If multiple lines match, an
+    error will be raised unless the `multiple => true` parameter is set.
+
     **Autorequires:** If Puppet is managing the file that will contain the line
     being managed, the file_line resource will autorequire that file.
 
@@ -55,6 +69,14 @@ Puppet::Type.newtype(:file_line) do
          ' match an exception will be raised. '
   end
 
+  newparam(:match_for_absence) do
+    desc 'An optional value to determine if match should be applied when ensure => absent.' +
+         ' If set to true and match is set, the line that matches match will be deleted.' +
+         ' If set to false (the default), match is ignored when ensure => absent.'
+    newvalues(true, false)
+    defaultto false
+  end
+
   newparam(:multiple) do
     desc 'An optional value to determine if match can change multiple lines.' +
          ' If set to false, an exception will be raised if more than one line matches'
index 792391a75c98ef8f98d07816316d4baa9abae3e0..23e649cc911d084f4a0f488bb53790a119a1304e 100755 (executable)
@@ -341,4 +341,100 @@ describe provider_class do
       expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n")
     end
   end
+
+  context "when removing with a match" do
+    before :each do
+      # TODO: these should be ported over to use the PuppetLabs spec_helper
+      #  file fixtures once the following pull request has been merged:
+      # https://github.com/puppetlabs/puppetlabs-stdlib/pull/73/files
+      tmp = Tempfile.new('tmp')
+      @tmpfile = tmp.path
+      tmp.close!
+      @resource = Puppet::Type::File_line.new(
+        {
+          :name              => 'foo',
+          :path              => @tmpfile,
+          :line              => 'foo2',
+          :ensure            => 'absent',
+          :match             => 'o$',
+          :match_for_absence => true,
+        }
+      )
+      @provider = provider_class.new(@resource)
+    end
+
+    it 'should remove one line if it matches' do
+      File.open(@tmpfile, 'w') do |fh|
+        fh.write("foo1\nfoo\nfoo2")
+      end
+      @provider.destroy
+      expect(File.read(@tmpfile)).to eql("foo1\nfoo2")
+    end
+
+    it 'should raise an error if more than one line matches' do
+      File.open(@tmpfile, 'w') do |fh|
+        fh.write("foo1\nfoo\nfoo2\nfoo\nfoo")
+      end
+      expect { @provider.destroy }.to raise_error(Puppet::Error, /More than one line/)
+    end
+
+    it 'should remove multiple lines if :multiple is true' do
+      @resource = Puppet::Type::File_line.new(
+        {
+          :name              => 'foo',
+          :path              => @tmpfile,
+          :line              => 'foo2',
+          :ensure            => 'absent',
+          :match             => 'o$',
+          :multiple          => true,
+          :match_for_absence => true,
+        }
+      )
+      @provider = provider_class.new(@resource)
+      File.open(@tmpfile, 'w') do |fh|
+        fh.write("foo1\nfoo\nfoo2\nfoo\nfoo")
+      end
+      @provider.destroy
+      expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n")
+    end
+
+    it 'should ignore the match if match_for_absense is not specified' do
+      @resource = Puppet::Type::File_line.new(
+        {
+          :name     => 'foo',
+          :path     => @tmpfile,
+          :line     => 'foo2',
+          :ensure   => 'absent',
+          :match    => 'o$',
+        }
+      )
+      @provider = provider_class.new(@resource)
+      File.open(@tmpfile, 'w') do |fh|
+        fh.write("foo1\nfoo\nfoo2")
+      end
+      @provider.destroy
+      expect(File.read(@tmpfile)).to eql("foo1\nfoo\n")
+    end
+
+    it 'should ignore the match if match_for_absense is false' do
+      @resource = Puppet::Type::File_line.new(
+        {
+          :name              => 'foo',
+          :path              => @tmpfile,
+          :line              => 'foo2',
+          :ensure            => 'absent',
+          :match             => 'o$',
+          :match_for_absence => false,
+        }
+      )
+      @provider = provider_class.new(@resource)
+      File.open(@tmpfile, 'w') do |fh|
+        fh.write("foo1\nfoo\nfoo2")
+      end
+      @provider.destroy
+      expect(File.read(@tmpfile)).to eql("foo1\nfoo\n")
+    end
+
+  end
+
 end