diff options
author | Bryan Kearney <bkearney@redhat.com> | 2009-01-05 11:11:16 -0500 |
---|---|---|
committer | James Turnbull <james@lovedthanlost.net> | 2009-01-13 17:32:06 +1100 |
commit | 1f6dce51a9cf7c423e94fd02f54322217d415a77 (patch) | |
tree | a1fa79194fc81cbd8289368b23813fc6aa3488b6 | |
parent | 8142981571b438d4fe19f4097fe331378a322b33 (diff) | |
download | puppet-1f6dce51a9cf7c423e94fd02f54322217d415a77.tar.gz puppet-1f6dce51a9cf7c423e94fd02f54322217d415a77.tar.xz puppet-1f6dce51a9cf7c423e94fd02f54322217d415a77.zip |
Fix #1835 : Add whitespace/quote parsing to
-rw-r--r-- | lib/puppet/provider/augeas/augeas.rb | 54 | ||||
-rw-r--r-- | spec/unit/provider/augeas/augeas.rb | 232 |
2 files changed, 192 insertions, 94 deletions
diff --git a/lib/puppet/provider/augeas/augeas.rb b/lib/puppet/provider/augeas/augeas.rb index 0ffddebb0..919b377e7 100644 --- a/lib/puppet/provider/augeas/augeas.rb +++ b/lib/puppet/provider/augeas/augeas.rb @@ -22,9 +22,9 @@ require 'augeas' if Puppet.features.augeas? Puppet::Type.type(:augeas).provide(:augeas) do #class Puppet::Provider::Augeas < Puppet::Provider include Puppet::Util - - confine :true => Puppet.features.augeas? - + + confine :true => Puppet.features.augeas? + has_features :parse_commands, :need_to_run?,:execute_changes # Extracts an 2 dimensional array of commands which are in the @@ -38,10 +38,27 @@ Puppet::Type.type(:augeas).provide(:augeas) do if data.is_a?(String) data.each_line do |line| cmd_array = Array.new() - tokens = line.split(" ") - cmd = tokens.shift() - file = tokens.shift() - other = tokens.join(" ") + single = line.index("'") + double = line.index('"') + tokens = nil + delim = " " + if ((single != nil) or (double != nil)) + single = 99999 if single == nil + double = 99999 if double == nil + delim = '"' if double < single + delim = "'" if single < double + end + tokens = line.split(delim) + # If the length of tokens is 2, thn that means the pattern was + # command file "some text", therefore we need to re-split + # the first line + if tokens.length == 2 + tokens = (tokens[0].split(" ")) << tokens[1] + end + cmd = tokens.shift().strip() + delim = "" if delim == " " + file = tokens.shift().strip() + other = tokens.join(" ").strip() cmd_array << cmd if !cmd.nil? cmd_array << file if !file.nil? cmd_array << other if other != "" @@ -64,7 +81,7 @@ Puppet::Type.type(:augeas).provide(:augeas) do debug("Opening augeas with root #{root}, lens path #{load_path}, flags #{flags}") Augeas.open(root, load_path,flags) end - + # Used by the need_to_run? method to process get filters. Returns # true if there is a match, false if otherwise # Assumes a syntax of get /files/path [COMPARATOR] value @@ -94,8 +111,8 @@ Puppet::Type.type(:augeas).provide(:augeas) do end end return_value - end - + end + # Used by the need_to_run? method to process match filters. Returns # true if there is a match, false if otherwise def process_match(cmd_array) @@ -132,8 +149,8 @@ Puppet::Type.type(:augeas).provide(:augeas) do end end return_value - end - + end + # Determines if augeas acutally needs to run. def need_to_run? return_value = true @@ -153,8 +170,8 @@ Puppet::Type.type(:augeas).provide(:augeas) do end end return_value - end - + end + # Actually execute the augeas changes. def execute_changes aug = open_augeas @@ -164,7 +181,8 @@ Puppet::Type.type(:augeas).provide(:augeas) do fail("invalid command #{cmd_array.join[" "]}") if cmd_array.length < 2 command = cmd_array[0] cmd_array.shift() - cmd_array[0]=File.join(context, cmd_array[0]) + loc = cmd_array[0] + cmd_array[0]=File.join(context, loc) debug("sending command '#{command}' with params #{cmd_array.inspect}") begin case command @@ -183,7 +201,7 @@ Puppet::Type.type(:augeas).provide(:augeas) do fail("Save failed with return code #{success}") end - return :executed - end - + return :executed + end + end diff --git a/spec/unit/provider/augeas/augeas.rb b/spec/unit/provider/augeas/augeas.rb index 1bbf18f83..083448b4a 100644 --- a/spec/unit/provider/augeas/augeas.rb +++ b/spec/unit/provider/augeas/augeas.rb @@ -10,167 +10,247 @@ describe provider_class do provider = provider_class.new() tokens = provider.parse_commands("set /Jar/Jar Binks") tokens.size.should == 1 - tokens[0].size.should == 3 + tokens[0].size.should == 3 tokens[0][0].should == "set" tokens[0][1].should == "/Jar/Jar" - tokens[0][2].should == "Binks" + tokens[0][2].should == "Binks" end - + it "should break apart a multiple line into six tokens" do provider = provider_class.new() tokens = provider.parse_commands("set /Jar/Jar Binks\nrm anakin skywalker") tokens.size.should == 2 - tokens[0].size.should == 3 - tokens[1].size.should == 3 + tokens[0].size.should == 3 + tokens[1].size.should == 3 tokens[0][0].should == "set" tokens[0][1].should == "/Jar/Jar" - tokens[0][2].should == "Binks" + tokens[0][2].should == "Binks" tokens[1][0].should == "rm" tokens[1][1].should == "anakin" - tokens[1][2].should == "skywalker" - end - + tokens[1][2].should == "skywalker" + end + it "should handle arrays" do provider = provider_class.new() commands = ["set /Jar/Jar Binks", "rm anakin skywalker"] tokens = provider.parse_commands(commands) tokens.size.should == 2 - tokens[0].size.should == 3 - tokens[1].size.should == 3 + tokens[0].size.should == 3 + tokens[1].size.should == 3 tokens[0][0].should == "set" tokens[0][1].should == "/Jar/Jar" - tokens[0][2].should == "Binks" + tokens[0][2].should == "Binks" tokens[1][0].should == "rm" tokens[1][1].should == "anakin" - tokens[1][2].should == "skywalker" - end - + tokens[1][2].should == "skywalker" + end + it "should concat the last values" do provider = provider_class.new() tokens = provider.parse_commands("set /Jar/Jar Binks is my copilot") tokens.size.should == 1 - tokens[0].size.should == 3 + tokens[0].size.should == 3 tokens[0][0].should == "set" tokens[0][1].should == "/Jar/Jar" - tokens[0][2].should == "Binks is my copilot" + tokens[0][2].should == "Binks is my copilot" + end + + it "should accept spaces and and single ticks" do + provider = provider_class.new() + tokens = provider.parse_commands("set 'Jar Jar' Binks") + tokens.size.should == 1 + tokens[0].size.should == 3 + tokens[0][0].should == "set" + tokens[0][1].should == "Jar Jar" + tokens[0][2].should == "Binks" + end + + it "should accept spaces in the value and and single ticks" do + provider = provider_class.new() + tokens = provider.parse_commands("set 'Jar Jar' 'Binks is my copilot'") + tokens.size.should == 1 + tokens[0].size.should == 3 + tokens[0][0].should == "set" + tokens[0][1].should == "Jar Jar" + tokens[0][2].should == "Binks is my copilot" + end + + it "should accept spaces and and double ticks" do + provider = provider_class.new() + tokens = provider.parse_commands('set "Jar Jar" Binks') + tokens.size.should == 1 + tokens[0].size.should == 3 + tokens[0][0].should == "set" + tokens[0][1].should == 'Jar Jar' + tokens[0][2].should == 'Binks' + end + + it "should accept spaces in the value and and double ticks" do + provider = provider_class.new() + tokens = provider.parse_commands('set "Jar Jar" "Binks is my copilot"') + tokens.size.should == 1 + tokens[0].size.should == 3 + tokens[0][0].should == "set" + tokens[0][1].should == 'Jar Jar' + tokens[0][2].should == 'Binks is my copilot' + end + + it "should accept mixed ticks" do + provider = provider_class.new() + tokens = provider.parse_commands('set "Jar Jar" "Some \'Test\'"') + tokens.size.should == 1 + tokens[0].size.should == 3 + tokens[0][0].should == "set" + tokens[0][1].should == 'Jar Jar' + tokens[0][2].should == "Some \'Test\'" + end + + it "should accept only the last value using ticks" do + provider = provider_class.new() + tokens = provider.parse_commands('set /Jar/Jar "Binks is my copilot"') + tokens.size.should == 1 + tokens[0].size.should == 3 + tokens[0][0].should == "set" + tokens[0][1].should == '/Jar/Jar' + tokens[0][2].should == "Binks is my copilot" end + + it "should accept only the first value using ticks" do + provider = provider_class.new() + tokens = provider.parse_commands('set "Jar Jar" copilot') + tokens.size.should == 1 + tokens[0].size.should == 3 + tokens[0][0].should == "set" + tokens[0][1].should == 'Jar Jar' + tokens[0][2].should == "copilot" + end + + it "should accept only the first value using ticks and the last values being concatenated" do + provider = provider_class.new() + tokens = provider.parse_commands('set "Jar Jar" Binks is my copilot') + tokens.size.should == 1 + tokens[0].size.should == 3 + tokens[0][0].should == "set" + tokens[0][1].should == 'Jar Jar' + tokens[0][2].should == "Binks is my copilot" + end end - + describe "get filters" do before do augeas_stub = stub("augeas", :get => "value") - @provider = provider_class.new() - @provider.stubs(:open_augeas).returns(augeas_stub) + @provider = provider_class.new() + @provider.stubs(:open_augeas).returns(augeas_stub) end - + it "should return false for a = nonmatch" do command = ["get", "fake value", "==", "value"] @provider.process_get(command).should == true end - + it "should return true for a != match" do command = ["get", "fake value", "!=", "value"] @provider.process_get(command).should == false - end - + end + it "should return true for a =~ match" do command = ["get", "fake value", "=~", "val*"] @provider.process_get(command).should == true - end - + end + it "should return false for a == nonmatch" do command = ["get", "fake value", "=~", "num*"] @provider.process_get(command).should == false - end + end end - + describe "match filters" do before do augeas_stub = stub("augeas", :match => ["set", "of", "values"]) - @provider = provider_class.new() - @provider.stubs(:open_augeas).returns(augeas_stub) + @provider = provider_class.new() + @provider.stubs(:open_augeas).returns(augeas_stub) end - + it "should return true for size match" do command = ["match", "fake value", "size", "==", "3"] @provider.process_match(command).should == true end - + it "should return false for a size non match" do command = ["match", "fake value", "size", "<", "3"] @provider.process_match(command).should == false - end - + end + it "should return true for includes match" do command = ["get", "fake value", "include", "values"] @provider.process_match(command).should == true - end - + end + it "should return false for includes non match" do command = ["get", "fake value", "include", "JarJar"] @provider.process_match(command).should == false - end - + end + it "should return true for an array match" do command = ["get", "fake value", "==", "['set', 'of', 'values']"] @provider.process_match(command).should == true - end - + end + it "should return false for an array non match" do command = ["get", "fake value", "==", "['this', 'should', 'not', 'match']"] @provider.process_match(command).should == false - end - end - + end + end + describe "need_to_run" do it "should handle no filters" do resource = stub("resource", :[] => "") provider = provider_class.new(resource) - provider.need_to_run?.should == true + provider.need_to_run?.should == true end - + it "should return true when a get filter matches" do resource = stub("resource", :[] => "get path == value") provider = provider_class.new(resource) augeas_stub = stub("augeas", :get => "value") - provider.stubs(:open_augeas).returns(augeas_stub) - provider.need_to_run?.should == true - end - + provider.stubs(:open_augeas).returns(augeas_stub) + provider.need_to_run?.should == true + end + it "should return false when a get filter does not match" do resource = stub("resource", :[] => "get path == another value") provider = provider_class.new(resource) augeas_stub = stub("augeas", :get => "value") - provider.stubs(:open_augeas).returns(augeas_stub) - provider.need_to_run?.should == false - end - + provider.stubs(:open_augeas).returns(augeas_stub) + provider.need_to_run?.should == false + end + it "should return true when a match filter matches" do resource = stub("resource", :[] => "match path size == 3") provider = provider_class.new(resource) augeas_stub = stub("augeas", :match => ["set", "of", "values"]) - provider.stubs(:open_augeas).returns(augeas_stub) - provider.need_to_run?.should == true - end - + provider.stubs(:open_augeas).returns(augeas_stub) + provider.need_to_run?.should == true + end + it "should return false when a match filter does not match" do resource = stub("resource", :[] => "match path size == 2") provider = provider_class.new(resource) augeas_stub = stub("augeas", :match => ["set", "of", "values"]) - provider.stubs(:open_augeas).returns(augeas_stub) - provider.need_to_run?.should == false - end + provider.stubs(:open_augeas).returns(augeas_stub) + provider.need_to_run?.should == false + end end - + describe "augeas integration" do - + before do @resource = stub("resource") @provider = provider_class.new(@resource) @augeas = stub("augeas") @provider.stubs(:open_augeas).returns(@augeas) end - + it "should handle set commands" do command = [["set", "/Jar/Jar", "Binks"]] context = "/some/path" @@ -179,7 +259,7 @@ describe provider_class do @augeas.expects(:save).returns(true) @provider.execute_changes.should == :executed end - + it "should handle rm commands" do command = [["rm", "/Jar/Jar"]] context = "" @@ -187,8 +267,8 @@ describe provider_class do @augeas.expects(:rm).with("/Jar/Jar") @augeas.expects(:save).returns(true) @provider.execute_changes.should == :executed - end - + end + it "should handle remove commands" do command = [["remove", "Jar/Jar"]] context = "" @@ -196,8 +276,8 @@ describe provider_class do @augeas.expects(:rm).with("/Jar/Jar") @augeas.expects(:save).returns(true) @provider.execute_changes.should == :executed - end - + end + it "should handle clear commands" do command = [["clear", "/Jar/Jar"]] context = "/foo" @@ -205,8 +285,8 @@ describe provider_class do @augeas.expects(:clear).with("/foo/Jar/Jar") @augeas.expects(:save).returns(true) @provider.execute_changes.should == :executed - end - + end + it "should handle insert commands" do command = [["insert", "/Jar/Jar"]] context = "/foo" @@ -214,8 +294,8 @@ describe provider_class do @augeas.expects(:insert).with("/foo/Jar/Jar") @augeas.expects(:save).returns(true) @provider.execute_changes.should == :executed - end - + end + it "should handle ins commands" do command = [["ins", "/Jar/Jar"]] context = "/foo" @@ -223,16 +303,16 @@ describe provider_class do @augeas.expects(:insert).with("/foo/Jar/Jar") @augeas.expects(:save).returns(true) @provider.execute_changes.should == :executed - end - + end + it "should handle multiple commands" do command = [["ins", "/Jar/Jar"], ["clear", "/Jar/Jar"]] context = "/foo" @resource.expects(:[]).times(2).returns(command).then.returns(context) @augeas.expects(:insert).with("/foo/Jar/Jar") - @augeas.expects(:clear).with("/foo/Jar/Jar") + @augeas.expects(:clear).with("/foo/Jar/Jar") @augeas.expects(:save).returns(true) @provider.execute_changes.should == :executed - end + end end end |