summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.markdown1
-rw-r--r--lib/puppet/provider/file_line/ruby.rb31
-rw-r--r--lib/puppet/type/file_line.rb6
-rwxr-xr-xspec/unit/puppet/provider/file_line/ruby_spec.rb51
-rwxr-xr-xspec/unit/puppet/type/file_line_spec.rb3
5 files changed, 81 insertions, 11 deletions
diff --git a/README.markdown b/README.markdown
index eef538a..090bb09 100644
--- a/README.markdown
+++ b/README.markdown
@@ -99,6 +99,7 @@ All parameters are optional, unless otherwise noted.
* `multiple`: Determines if `match` and/or `after` can change multiple lines. If set to false, an exception will be raised if more than one line matches. Valid options: 'true', 'false'. Default: Undefined.
* `name`: Sets the name to use as the identity of the resource. This is necessary if you want the resource namevar to differ from the supplied `title` of the resource. Valid options: String. Default: Undefined.
* `path`: **Required.** Defines the file in which Puppet will ensure the line specified by `line`. Must be an absolute path to the file.
+* `replace`: Defines whether the resource will overwrite an existing line that matches the `match` parameter. If set to false and a line is found matching the `match` param, the line will not be placed in the file. Valid options: true, false, yes, no. Default: true
### Functions
diff --git a/lib/puppet/provider/file_line/ruby.rb b/lib/puppet/provider/file_line/ruby.rb
index c58e27e..ea1d44d 100644
--- a/lib/puppet/provider/file_line/ruby.rb
+++ b/lib/puppet/provider/file_line/ruby.rb
@@ -1,17 +1,23 @@
Puppet::Type.type(:file_line).provide(:ruby) do
def exists?
- lines.find do |line|
- line.chomp == resource[:line].chomp
+ if !resource[:replace] and count_matches(match_regex) > 0
+ true
+ else
+ lines.find do |line|
+ line.chomp == resource[:line].chomp
+ end
end
end
def create
- if resource[:match]
- handle_create_with_match
- elsif resource[:after]
- handle_create_with_after
- else
- append_line
+ unless !resource[:replace] and count_matches(match_regex) > 0
+ if resource[:match]
+ handle_create_with_match
+ elsif resource[:after]
+ handle_create_with_after
+ else
+ append_line
+ end
end
end
@@ -32,10 +38,13 @@ Puppet::Type.type(:file_line).provide(:ruby) do
@lines ||= File.readlines(resource[:path])
end
+ def match_regex
+ resource[:match] ? Regexp.new(resource[:match]) : nil
+ end
+
def handle_create_with_match()
- regex = resource[:match] ? Regexp.new(resource[:match]) : nil
regex_after = resource[:after] ? Regexp.new(resource[:after]) : nil
- match_count = count_matches(regex)
+ 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]}'"
@@ -43,7 +52,7 @@ Puppet::Type.type(:file_line).provide(:ruby) do
File.open(resource[:path], 'w') do |fh|
lines.each do |l|
- fh.puts(regex.match(l) ? resource[:line] : l)
+ fh.puts(match_regex.match(l) ? resource[:line] : l)
if (match_count == 0 and regex_after)
if regex_after.match(l)
fh.puts(resource[:line])
diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb
index 29f9538..190105c 100644
--- a/lib/puppet/type/file_line.rb
+++ b/lib/puppet/type/file_line.rb
@@ -1,3 +1,4 @@
+require 'puppet/parameter/boolean'
Puppet::Type.newtype(:file_line) do
desc <<-EOT
@@ -78,6 +79,11 @@ Puppet::Type.newtype(:file_line) do
end
end
+ newparam(:replace, :boolean => true, :parent => Puppet::Parameter::Boolean) do
+ desc 'If true, replace line that matches. If false, do not write line if a match is found'
+ defaultto true
+ end
+
# Autorequire the file resource if it's being managed
autorequire(:file) do
self[:path]
diff --git a/spec/unit/puppet/provider/file_line/ruby_spec.rb b/spec/unit/puppet/provider/file_line/ruby_spec.rb
index 8fe3932..5eff09a 100755
--- a/spec/unit/puppet/provider/file_line/ruby_spec.rb
+++ b/spec/unit/puppet/provider/file_line/ruby_spec.rb
@@ -36,7 +36,58 @@ describe provider_class do
expect(File.read(tmpfile).chomp).to eq('foo')
end
end
+ context 'when using replace' 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 => 'foo = bar',
+ :match => '^foo\s*=.*$',
+ :replace => false,
+ }
+ )
+ @provider = provider_class.new(@resource)
+ end
+ it 'should not replace the matching line' do
+ File.open(@tmpfile, 'w') do |fh|
+ fh.write("foo1\nfoo=blah\nfoo2\nfoo3")
+ end
+ expect(@provider.exists?).to be_truthy
+ @provider.create
+ expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo=blah\nfoo2\nfoo3")
+ end
+
+ it 'should append the line if no matches are found' do
+ File.open(@tmpfile, 'w') do |fh|
+ fh.write("foo1\nfoo2")
+ end
+ expect(@provider.exists?).to be_nil
+ @provider.create
+ expect(File.read(@tmpfile).chomp).to eql("foo1\nfoo2\nfoo = bar")
+ end
+
+ it 'should raise an error with invalid values' do
+ expect {
+ @resource = Puppet::Type::File_line.new(
+ {
+ :name => 'foo',
+ :path => @tmpfile,
+ :line => 'foo = bar',
+ :match => '^foo\s*=.*$',
+ :replace => 'asgadga',
+ }
+ )
+ }.to raise_error(Puppet::Error, /Invalid value "asgadga"\. Valid values are true, false, yes, no\./)
+ end
+ end
context "when matching" do
before :each do
# TODO: these should be ported over to use the PuppetLabs spec_helper
diff --git a/spec/unit/puppet/type/file_line_spec.rb b/spec/unit/puppet/type/file_line_spec.rb
index 410d0bf..58c88e3 100755
--- a/spec/unit/puppet/type/file_line_spec.rb
+++ b/spec/unit/puppet/type/file_line_spec.rb
@@ -49,6 +49,9 @@ describe Puppet::Type.type(:file_line) do
it 'should default to ensure => present' do
expect(file_line[:ensure]).to eq :present
end
+ it 'should default to replace => true' do
+ expect(file_line[:replace]).to eq true
+ end
it "should autorequire the file it manages" do
catalog = Puppet::Resource::Catalog.new