summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorroot <root@collector.localdomain>2010-03-11 20:23:27 -0600
committerroot <root@collector.localdomain>2010-03-11 20:23:27 -0600
commit9882c5ddb540ce1e36e7b72a47fe578abe79c9b4 (patch)
treecd117f327dd1d37526edc7a906aaa96d3db210cd /lib
First commit for sudoers module.
This doesnt work... yet.
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet/provider/sudoers/parsed.rb123
-rw-r--r--lib/puppet/type/sudoers.rb94
2 files changed, 217 insertions, 0 deletions
diff --git a/lib/puppet/provider/sudoers/parsed.rb b/lib/puppet/provider/sudoers/parsed.rb
new file mode 100644
index 0000000..520eef5
--- /dev/null
+++ b/lib/puppet/provider/sudoers/parsed.rb
@@ -0,0 +1,123 @@
+require 'puppet/provider/parsedfile'
+sudoers = "/etc/sudoers"
+
+#
+# crontab does the same thing, it uses a comment to specify uniqueness
+#
+
+Puppet::Type.type(:sudoers).provide(
+ :parsed,
+ :parent => Puppet::Provider::ParsedFile,
+ :default_target => '/etc/sudoers',
+ # what the heck does this mean?
+ :filetype => :flat
+) do
+
+ desc "The sudoers provider that uses the ParsedFile class"
+
+ commands :visudo => 'visudo'
+
+ # this is just copied from hosts
+ text_line :comment, :match => %r{^#}, :post_parse => proc { |record|
+ # we determine the name from the comment above user spec lines
+ if record[:line] =~ /Puppet Name: (.+)\s*$/
+# ok, we set record name, but how is this applied to the next line?
+ record[:name] = $1
+ end
+ }
+
+ text_line :blank, :match => /^\s*$/;
+
+ # ignore for now, I will support this line later
+ text_line :defaults, :match => /^Defaults/
+
+# I need to parse the , delim list into an array
+# I am pretty sure that I would do this with a block statement
+
+#
+# it seems like I have to put type here for it to be accessible to
+# to_line
+#
+
+
+# not bothering to specify match or fields, I will determine all of this
+# in post_parse
+
+# parse everything else?
+ record_line :parsed, :fields => %w{line},
+ :match => /(.*)/,
+ :post_parse => proc { |hash|
+ puts "\npost_parse"
+ puts hash[:line]
+ if (hash[:line] =~ /^\s*(User_Alias|Runas_Alias|Host_Alias|Cmnd_Alias)\s+(\S+)\s*=\s*(.+)$/)
+ hash[:sudo_alias] = $1
+ hash[:name] = $2
+ hash[:items] = $3
+ hash[:items]=hash[:items].gsub(/\s/, '').split(',')
+ #puts hash.to_yaml
+ elsif (hash[:line] =~ /^(.*)?=(.*)$/)
+ # should name already be set when get get here?
+ hash = parse_user_spec($1, $2)
+ else
+ raise ArgumentError, "unexpected line #{hash[:line]}"
+ end
+ }
+
+ def self.parse_user_spec(lhs, rhs)
+ lhs_array = lhs.split(',')
+ end
+
+ def self.to_line(hash)
+ puts "\nEntering self.to_line for #{hash[:name]}"
+ puts hash.to_yaml
+ # dynamically call a function based on the value of hash[:type]
+ if(hash[:type] == 'alias')
+ self.alias_to_line(hash)
+ elsif(hash[:type] == 'spec')
+ spec_to_line(hash)
+ elsif(hash[:type] == 'default')
+ default_to_line(hash)
+ end
+ end
+
+ def self.spec_to_line(hash)
+ "spec"
+ end
+
+ def self.alias_to_line(hash)
+ # do I need to ensure that the required elements are here?
+ # shouldnt the type do that? check file, its similar
+ # since different attributes make sense based on ensure value (dir/file/symlink)
+ items=hash[:items]
+ items=items.join(',') if items.class == Array
+ "#{hash[:sudo_alias]} #{hash[:name]}=#{items}"
+ end
+
+ def default_to_line(hash)
+ "default"
+ end
+
+ def self.flush(record)
+# a little pre-flush host visudo action
+#
+ super(record)
+ end
+
+# lets assume that runas is always there and lets not deal with options yet
+# record_line :spec, :fields => %w{users hosts runas specs type},
+# :match => %r{(\S+)\s+(\S+)=(\(\S+\))\s+(.+)},
+# :post_parse => proc { |hash|
+# puts 'spec'
+# }
+
+# I dont know if I can properly support multiple commands
+# because they are composite, one command, one runas, multiple tags
+# record_line :spec, :fields => %w{user host runas tags commands name},
+# :match => %r{^\s*(\S+)\s+(\S+)\s*=\s*(\(\S+\))?(.+)$},
+# :optional => %w{runas tags}
+
+# I need to override flush to validate sudoers
+#
+#
+#
+end
diff --git a/lib/puppet/type/sudoers.rb b/lib/puppet/type/sudoers.rb
new file mode 100644
index 0000000..6c94269
--- /dev/null
+++ b/lib/puppet/type/sudoers.rb
@@ -0,0 +1,94 @@
+Puppet::Type.newtype(:sudoers) do
+ @doc = "Manage the contents of /etc/sudoers
+
+there are two types of things here:
+
+ sudoer{'NAME':
+ ensure => (absent|present)
+ type => (alias|spec) # required??
+ alias => (User_alias|Runas_alias|Host_alias|Cmnd_alias),
+ items => [] # this is only for aliases
+ user_list => []
+ host_list => []
+ operator_list => []
+ # NOPASSWD, PASSWD, NOEXEC, EXEC, SETENV and NOSETENV
+ tag_list => []
+ command_list => []
+ }
+
+ alias NAME - starts with CAP ([A-Z]([A-Z][0-9]_)*)
+
+aliases, user specifications
+ User_alias
+ Runas_alias
+ Host_alias
+ Cmnd_alias
+
+alias spec:
+
+ Alias_Type NAME = item1, item2, item3 : NAME = item4, item5
+
+
+order matters!!
+
+
+ "
+ # we can either remove or add lines
+ # they should also be purgable?(whats the namesvar for specs?)
+ ensurable
+
+ newparam(:name) do
+ desc "Either the name of the alias to create
+ or for user specification, a random string in a comment that serves as a place holder (kind of ugly, but its true)
+ "
+
+ isnamevar
+ end
+
+#
+# this has to be a property to be found by parsedfile, but
+# its really a parameter
+
+ newproperty(:type) do
+ desc "Either determines which type of sudo configuration line is
+ is being managed. Either user_spec or alias"
+ end
+
+ newproperty(:sudo_alias) do
+ desc "Types of alias."
+ end
+
+ newproperty(:items, :array_matching => :all) do
+ desc "list of items applied to an alias"
+ end
+
+ newproperty(:target) do
+ desc "Location of the shells file"
+
+ defaultto do
+ if
+ @resource.class.defaultprovider.ancestors.include?(Puppet::Provider::ParsedFile)
+ @resource.class.defaultprovider.default_target
+ else
+ nil
+ end
+ end
+ end
+
+ newproperty(:users, :array_matching => :all) do
+ desc "list of users for user spec"
+ end
+
+ newproperty(:hosts, :array_matching => :all) do
+ desc "list of hosts for user spec"
+ end
+
+ newproperty(:runas, :array_matching => :all) do
+ desc "user to run commands as"
+ end
+ newproperty(:commands, :array_matching => :all) do
+ desc "commands to run"
+ end
+
+end
+