# Manage NetInfo POSIX objects. Probably only used on OS X, but I suppose
# it could be used elsewhere.
require 'puppet'
require 'puppet/provider/nameservice'
class Puppet::Provider::NameService
class NetInfo < Puppet::Provider::NameService
class << self
attr_writer :netinfodir
end
# We have to initialize manually because we're not using
# classgen() here.
initvars()
commands :lookupd => "/usr/sbin/lookupd"
# Attempt to flush the database, but this doesn't seem to work at all.
def self.flush
begin
lookupd "-flushcache"
rescue Puppet::ExecutionFailure
# Don't throw an error; it's just a failed cache flush
Puppet.err "Could not flush lookupd cache: %s" % output
end
end
# Similar to posixmethod, what key do we use to get data? Defaults
# to being the object name.
def self.netinfodir
if defined? @netinfodir
return @netinfodir
else
return @resource_type.name.to_s + "s"
end
end
def self.finish
case self.name
when :uid:
noautogen
when :gid:
noautogen
end
end
def self.instances
report(@resource_type.validproperties).collect do |hash|
self.new(hash)
end
end
# Convert a NetInfo line into a hash of data.
def self.line2hash(line, params)
values = line.split(/\t/)
hash = {}
params.zip(values).each do |param, value|
next if value == '#NoValue#'
hash[param] = if value =~ /^[-0-9]+$/
Integer(value)
else
value
end
end
hash
end
# What field the value is stored under.
def self.netinfokey(name)
name = symbolize(name)
self.option(name, :key) || name
end
# Retrieve the data, yo.
# FIXME This should retrieve as much information as possible,
# rather than retrieving it one at a time.
def self.report(*params)
dir = self.netinfodir()
cmd = [command(:nireport), "/", "/%s" % dir]
params.flatten!
# We require the name in order to know if we match. There's no
# way to just report on our individual object, we have to get the
# whole list.
params.unshift :name unless params.include? :name
params.each do |param|
if key = netinfokey(param)
cmd << key.to_s
else
raise Puppet::DevError,
"Could not find netinfokey for property %s" %
self.class.name
end
end
begin
output = execute(cmd)
rescue Puppet::ExecutionFailure => detail
Puppet.err "Failed to call nireport: %s" % detail
return nil
end
return output.split("\n").collect { |line|
line2hash(line, params)
}
end
# How to add an object.
def addcmd
creatorcmd("-create")
end
def creatorcmd(arg)
cmd = [command(:niutil)]
cmd << arg
cmd << "/" << "/%s/%s" % [self.class.netinfodir(), @resource[:name]]
return cmd
end
def deletecmd
creatorcmd("-destroy")
end
def destroy
delete()
end
def ensure=(arg)
super
# Because our stupid type can't create the whole thing at once,
# we have to do this hackishness. Yay.
if arg == :present
@resource.class.validproperties.each do |name|
next if name == :ensure
next unless val = @resource.should(name) || autogen(name)
self.send(name.to_s + "=", val)
end
end
end
# Retrieve a specific value by name.
def get(param)
hash = getinfo(false)
if hash
return hash[param]
else
return :absent
end
end
# Retrieve everything about this object at once, instead of separately.
def getinfo(refresh = false)
if refresh or (! defined? @infohash or ! @infohash)
properties = [:name] + self.class.resource_type.validproperties
properties.delete(:ensure) if properties.include? :ensure
@infohash = single_report(*properties)
end
return @infohash
end
def modifycmd(param, value)
cmd = [command(:niutil)]
# if value.is_a?(Array)
# warning "Netinfo providers cannot currently handle multiple values"
# end
cmd << "-createprop" << "/" << "/%s/%s" % [self.class.netinfodir, @resource[:name]]
value = [value] unless value.is_a?(Array)
if key = netinfokey(param)
cmd << key
cmd += value
else
raise Puppet::DevError,
"Could not find netinfokey for property %s" %
self.class.name
end
cmd
end
# Determine the flag to pass to our command.
def netinfokey(name)
self.class.netinfokey(name)
end
# Get a report for a single resource, not the whole table
def single_report(*properties)
self.class.report(*properties).find do |hash| hash[:name] == self.name end
end
def setuserlist(group, list)
cmd = [command(:niutil), "-createprop", "/", "/groups/%s" % group, "users", list.join(",")]
begin
output = execute(cmd)
rescue Puppet::ExecutionFailure => detail
raise Puppet::Error, "Failed to set user list on %s: %s" %
[group, detail]
end
end
end
end
# $Id: netinfo.rb 2552 2007-06-05 01:17:00Z luke $
syntax highlighted by Code2HTML, v. 0.9.1