Merge pull request #494 from CENGN/fix/master/file_line_replace

[#puppethack] Adding replace attribute to file_line
This commit is contained in:
Bryan Jen 2015-07-30 13:34:26 -07:00
commit ebf73482e5
5 changed files with 81 additions and 11 deletions

View file

@ -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

View file

@ -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])

View file

@ -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]

View file

@ -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

View file

@ -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