summaryrefslogtreecommitdiffstats
path: root/lib/puppet/provider/augeas/augeas.rb
diff options
context:
space:
mode:
authorDavid Lutterkort <lutter@redhat.com>2009-05-30 22:43:55 -0700
committerJames Turnbull <james@lovedthanlost.net>2009-06-03 23:34:51 +1000
commit7c5125bb6dec630d2509905e3c202e0dfe59d959 (patch)
treef297ee552f018e3514b53def3e2e2ba66cc5a9c6 /lib/puppet/provider/augeas/augeas.rb
parent6ce81546ccfab2aefbec7fced5c38226bdd83297 (diff)
downloadpuppet-7c5125bb6dec630d2509905e3c202e0dfe59d959.tar.gz
puppet-7c5125bb6dec630d2509905e3c202e0dfe59d959.tar.xz
puppet-7c5125bb6dec630d2509905e3c202e0dfe59d959.zip
Brought in lutters parse_commands patch and integrated it into the type.
This includes reworking the get and match commands as well. This change introduces a few small changes. These are: 1) There can be no ' or " characters around path elements. 2) The context is now only prepended to relative paths. So, if a path is specified as /foo/bar the context will not be appended. It will only be appended if it is foo/bar 3) The syntax for array matching in the onlyif is now eq or noteq. It was == before. 4) The get and set commnands used to concatenate all items at the end of a string so "set path to some value" would be interpreted as "set" "path" "to some value". This is no longer supported. The caller must put ' or " around the "to some value" for it to work" Cherry-pick of 9a2642 from 0.24.x Conflicts: lib/puppet/provider/augeas/augeas.rb
Diffstat (limited to 'lib/puppet/provider/augeas/augeas.rb')
-rw-r--r--lib/puppet/provider/augeas/augeas.rb165
1 files changed, 108 insertions, 57 deletions
diff --git a/lib/puppet/provider/augeas/augeas.rb b/lib/puppet/provider/augeas/augeas.rb
index 841bdc6c1..35ab50652 100644
--- a/lib/puppet/provider/augeas/augeas.rb
+++ b/lib/puppet/provider/augeas/augeas.rb
@@ -18,6 +18,7 @@
# Author: Bryan Kearney <bkearney@redhat.com>
require 'augeas' if Puppet.features.augeas?
+require 'strscan'
Puppet::Type.type(:augeas).provide(:augeas) do
include Puppet::Util
@@ -29,6 +30,22 @@ Puppet::Type.type(:augeas).provide(:augeas) do
SAVE_NOOP = "noop"
SAVE_OVERWRITE = "overwrite"
+ COMMANDS = {
+ "set" => [ :path, :string ],
+ "rm" => [ :path ],
+ "clear" => [ :path ],
+ "insert" => [ :string, :string, :path ],
+ "get" => [ :path, :comparator, :string ],
+ "match" => [ :path, :glob ],
+ "size" => [:comparator, :int],
+ "include" => [:string],
+ "eq" => [:glob],
+ "noteq" => [:glob]
+ }
+
+ COMMANDS["ins"] = COMMANDS["insert"]
+ COMMANDS["remove"] = COMMANDS["rm"]
+
attr_accessor :aug
# Extracts an 2 dimensional array of commands which are in the
@@ -38,42 +55,76 @@ Puppet::Type.type(:augeas).provide(:augeas) do
# - A string with many commands per line
# - An array of strings.
def parse_commands(data)
- commands = Array.new()
+ context = resource[:context]
+ # Add a trailing / if it is not there
+ if (context.length > 0)
+ context << "/" if context[-1, 1] != "/"
+ end
+
if data.is_a?(String)
- data.each_line do |line|
- cmd_array = Array.new()
- 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]
+ s = data
+ data = []
+ s.each_line { |line| data << line }
+ end
+ args = []
+ data.each do |line|
+ argline = []
+ sc = StringScanner.new(line)
+ cmd = sc.scan(/\w+/)
+ formals = COMMANDS[cmd]
+ fail("Unknown command #{cmd}") unless formals
+ argline << cmd
+ narg = 0
+ formals.each do |f|
+ sc.skip(/\s+/)
+ narg += 1
+ if f == :path
+ start = sc.pos
+ nbracket = 0
+ begin
+ sc.skip(/[^\]\[\s]+/)
+ ch = sc.getch
+ nbracket += 1 if ch == "["
+ nbracket -= 1 if ch == "]"
+ fail("unmatched [") if nbracket < 0
+ end until nbracket == 0 && (sc.eos? || ch =~ /\s/)
+ len = sc.pos - start
+ len -= 1 unless sc.eos?
+ unless p = sc.string[start, len]
+ fail("missing path argument #{narg} for #{cmd}")
+ end
+ if p[0,1] != "$" && p[0,1] != "/"
+ argline << context + p
+ else
+ argline << p
+ end
+ elsif f == :string
+ delim = sc.peek(1)
+ if delim == "'" || delim == "\""
+ sc.getch
+ argline << sc.scan(/([^\\#{delim}]|(\\.))*/)
+ sc.getch
+ else
+ argline << sc.scan(/[^\s]+/)
+ end
+ unless argline[-1]
+ fail(raise Exception, "missing string argument #{narg} for #{cmd}")
+ end
+ elsif f == :comparator
+ argline << sc.scan(/(==|!=|=~|<|<=|>|>=)/)
+ unless argline[-1]
+ puts sc.rest()
+ fail(raise Exception, "invalid comparator for command #{cmd}")
+ end
+ elsif f == :int
+ argline << sc.scan(/\d+/).to_i
+ elsif f== :glob
+ argline << sc.rest()
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 != ""
- commands << cmd_array
- end
- elsif data.is_a?(Array)
- data.each do |datum|
- commands.concat(parse_commands(datum))
end
+ args << argline
end
- return commands
+ return args
end
@@ -137,32 +188,43 @@ Puppet::Type.type(:augeas).provide(:augeas) do
return_value = false
#validate and tear apart the command
- fail("Invalid command: #{cmd_array.join(" ")}") if cmd_array.length < 4
+ fail("Invalid command: #{cmd_array.join(" ")}") if cmd_array.length < 3
cmd = cmd_array.shift()
path = cmd_array.shift()
- verb = cmd_array.shift()
+
+ # Need to break apart the clause
+ clause_array = parse_commands(cmd_array.shift())[0]
+ verb = clause_array.shift()
#Get the values from augeas
result = @aug.match(path) || ''
# Now do the work
unless (result.nil?)
case verb
- when "size"
- fail("Invalid command: #{cmd_array.join(" ")}") if cmd_array.length != 2
- comparator = cmd_array.shift()
- arg = cmd_array.shift().to_i
+ when "size":
+ fail("Invalid command: #{cmd_array.join(" ")}") if clause_array.length != 2
+ comparator = clause_array.shift()
+ arg = clause_array.shift()
return_value = true if (result.size.send(comparator, arg))
- when "include"
- arg = cmd_array.join(" ")
+ when "include":
+ arg = clause_array.shift()
return_value = true if result.include?(arg)
- when "=="
+ when "eq":
begin
- arg = cmd_array.join(" ")
+ arg = clause_array.shift()
new_array = eval arg
return_value = true if result == new_array
rescue
fail("Invalid array in command: #{cmd_array.join(" ")}")
end
+ when "noteq":
+ begin
+ arg = clause_array.shift()
+ new_array = eval arg
+ return_value = true if result != new_array
+ rescue
+ fail("Invalid array in command: #{cmd_array.join(" ")}")
+ end
end
end
return_value
@@ -188,11 +250,9 @@ Puppet::Type.type(:augeas).provide(:augeas) do
self.open_augeas()
filter = resource[:onlyif]
unless (filter == "")
- cmd_array = filter.split
+ cmd_array = parse_commands(filter)[0]
command = cmd_array[0];
- cmd_array[1]= File.join(resource[:context], cmd_array[1])
begin
- data = nil
case command
when "get"; return_value = process_get(cmd_array)
when "match"; return_value = process_match(cmd_array)
@@ -244,35 +304,26 @@ Puppet::Type.type(:augeas).provide(:augeas) do
# Actually execute the augeas changes.
def do_execute_changes
- commands = resource[:changes].clone()
- context = resource[:context]
+ commands = parse_commands(resource[:changes])
commands.each do |cmd_array|
- cmd_array = cmd_array.clone()
fail("invalid command #{cmd_array.join[" "]}") if cmd_array.length < 2
command = cmd_array[0]
cmd_array.shift()
begin
case command
when "set"
- cmd_array[0]=File.join(context, cmd_array[0])
debug("sending command '#{command}' with params #{cmd_array.inspect}")
aug.set(cmd_array[0], cmd_array[1])
when "rm", "remove"
- cmd_array[0]=File.join(context, cmd_array[0])
debug("sending command '#{command}' with params #{cmd_array.inspect}")
aug.rm(cmd_array[0])
when "clear"
- cmd_array[0]=File.join(context, cmd_array[0])
debug("sending command '#{command}' with params #{cmd_array.inspect}")
@aug.clear(cmd_array[0])
when "insert", "ins"
- ext_array = cmd_array[1].split(" ") ;
- if cmd_array.size < 2 or ext_array.size < 2
- fail("ins requires 3 parameters")
- end
label = cmd_array[0]
- where = ext_array[0]
- path = File.join(context, ext_array[1])
+ where = cmd_array[1]
+ path = cmd_array[2]
case where
when "before"; before = true
when "after"; before = false