Skip to content

Add support for oranfstab... #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
require 'rubygems'
require 'puppetlabs_spec_helper/rake_tasks'

282 changes: 282 additions & 0 deletions lib/puppet/provider/oranfstab/oranfstab.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,282 @@
require 'puppet/provider/parsedfile'

oranfstab = case Facter.value(:operatingsystem)
when 'Solaris'
'/var/opt/oracle/oranfstab'
else
'/etc/oranfstab'
end

Puppet::Type.type(:oranfstab).provide(:oranfstab,
:parent => Puppet::Provider::ParsedFile,
:default_target => oranfstab,
:filetype => :flat
) do

text_line :footer, :match => /^\s*#\s+End Instance$/

text_line :comment, :match => %r{^\s*#},
:post_parse => proc { |record|
record[:name] = $1 if record[:line] =~ /^\s*#\s+Instance:\s+(\S{6,8})$/
}

text_line :blank, :match => /^\s*$/

record_line :nfsserver, :fields => %w{nfsserver},
:match => /^server:\s*([\w-]+)/

record_line :localip, :fields => %w{localip},
:match => %r{^local:\s*(([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5]))$}

record_line :remoteip, :fields => %w{remoteip},
:match => %r{^path:\s*(([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5]))$}

record_line :nfsmount, :fields => %w{export path},
:match => %r{^\s*export:\s+([\/\w]+)\s+mount:\s+([\/\w]+)}

#
## Local overrides of standard parsedfile defs'.
#

# Add name and environments as necessary.
def self.to_line(record)
Puppet.debug("Got to self.to_line. Record is: \n")
#ap record
str = ""
str = "# Instance: #{record[:name]}\n"
# Add nfsserver line if present
if record[:nfsserver] and record[:nfsserver] != :absent and record[:nfsserver] != [:absent]
str += "server: " + record[:nfsserver] + "\n"
end
# Add localip and remoteip if present
if record[:localips] and record[:localips] != :absent and record[:localips] != [:absent]
# Itterate arrays
@local = record[:localips]
@remote = record[:remoteips]
# Merge localips and remoteips
@local.zip(@remote).each do |local, remote|
str += "local: #{local}\n"
str += "path: #{remote}\n"
end
end
if record[:mounts] and record[:mounts] != :absent and record[:mounts] != [:absent]
mounts = record[:mounts]
mounts.each do |mount|
Puppet.debug("Export = #{mount["export"]}, Path = #{mount["path"]}\n")
str += "export: #{mount["export"]} mount: #{mount["path"]}\n"
end
end
str += "# End Instance"
Puppet.debug("Returning str: \n")
#ap str
str
end


# Return the header placed at the top of each generated file, warning
# users that modifying this file manually is probably a bad idea.
def self.header
%{# HEADER: This file was autogenerated at #{Time.now} by puppet.
# HEADER: While it can still be managed manually, it is definitely not recommended.
# HEADER: Note particularly that the comments starting with '#' should
# HEADER: not be deleted, as doing so could cause duplicate database entries.\n}
end

# See if we can match the record against an existing cron job.
def self.match(record, resources)
Puppet.debug("Got to match. \n")
Puppet.debug("Record = \n")
#ap record
#Puppet.debug("Resources = \n")
#ap resources
resources.each do |name, resource|
Puppet.debug("Name = \n")
#ap name

# Match the DB name first
Puppet.debug("record[:name] = #{record[:name]}, resource.value[:name] = #{resource.value(:name)}")
next unless record[:name] == resource.value(:name)

# Then the normal fields.
matched = true
record_type(record[:record_type]).fields.each do |field|
next if field == :name
if record[field] and ! resource.value(field)
#Puppet.info "Cron is missing %s: %s and %s" %
# [field, record[field].inspect, resource.value(field).inspect]
matched = false
break
end

if ! record[field] and resource.value(field)
#Puppet.info "Hash is missing %s: %s and %s" %
# [field, resource.value(field).inspect, record[field].inspect]
matched = false
break
end

# Yay differing definitions of absent.
next if (record[field] == :absent and resource.value(field) == "*")

# Everything should be in the form of arrays, not the normal text.
next if (record[field] == resource.value(field))
#Puppet.info "Did not match %s: %s vs %s" %
# [field, resource.value(field).inspect, record[field].inspect]
matched = false
break

end
Puppet.debug("Matched = #{matched}")
return resource if matched

end

Puppet.debug("Didn't match, returning false. \n")
false

end

def self.prefetch_hook(records)
Puppet.debug("Got to prefetch_hook. \n")
#Puppet.debug("Records =. \n")
#ap records

# Create empty placeholders
name = nil
nfsserver = nil
mounts = nil
localips = nil
remoteips = nil

result = records.each { |record|
Puppet.debug("Processing record: \n")
#ap record
case record[:record_type]
when :comment
Puppet.debug("Got a :comment record. \n")
Puppet.debug("Line = #{record[:line]}. \n")
if record[:name]
name = record[:name]
record[:skip] = true

# Start collecting data
mounts = []
localips = []
remoteips = []
end
when :blank
Puppet.debug("Got a :blank record. \n")
when :nfsserver
Puppet.debug("Got a :nfsserver record. \n")
nfsserver = record[:nfsserver]
record[:skip] = true
Puppet.debug("nfsserver looks like: \n")
#ap nfsserver
when :nfsmount
Puppet.debug("Got a :nfsmount record. \n")
if mounts
r = {}
r['export'] = record[:export]
r['path'] = record[:path]
mounts << r
r = nil
record[:skip] = true
end
Puppet.debug("mounts array looks like: \n")
#ap mounts
when :localip
Puppet.debug("Got a :localip record. \n")
localips << record[:localip]
record[:skip] = true
#ap localips
when :remoteip
Puppet.debug("Got a :remoteip. \n")
remoteips << record[:remoteip]
record[:skip] = true
#ap remoteips
else
# Set name if #appropriate.
if name
record[:name] = name
name = nil
end
# Add nfsserver value
if nfsserver.nil? or nfsserver.empty?
Puppet.debug("nfsserver is nil or empty. Setting to :absent .\n")
record[:nfsserver] = :absent
else
Puppet.debug("Populating record[:nfsserver] with nfsserver.\n")
record[:nfsserver] = nfsserver
nfsserver = nil
end
# Add localips value
if localips.nil? or localips.empty?
Puppet.debug("localips is nil or empty. Setting to :absent. \n")
record[:localips] = :absent
else
Puppet.debug("Populating record[:localips] with localips. \n")
record[:localips] = localips
localips = nil
end
# Add remoteips value
if remoteips.nil? or remoteips.empty?
Puppet.debug("remoteips is nil or empty. Setting to :absent. \n")
record[:remoteips] = :absent
else
Puppet.debug("Populating record[:remoteips] with remoteips. \n")
record[:remoteips] = remoteips
remoteips = nil
end
# Add mounts value
if mounts.nil? or mounts.empty?
Puppet.debug("mounts is nil or empty. Setting to :absent. \n")
record[:mounts] = :absent
else
Puppet.debug("Populating record[:mounts] with mounts. \n")
record[:mounts] = mounts
mounts = nil
end
end
}.reject { |record| record[:skip] }

Puppet.debug("Returning result: \n")
#ap result

result

end

def self.to_file(records)
Puppet.debug("Got to to_file. \n")
Puppet.debug("Records = \n")
#ap records
text = super
text
end

## Temporary overrides for debugging.
#
def self.match_providers_with_resources(resources)
Puppet.debug("Got to self.match_providers_with_resources... \n")
return unless resources
matchers = resources.dup
@records.each do |record|
# Skip things like comments and blank lines
Puppet.debug("Skip_record = #{skip_record?(record).to_s}. Not actually skipping though... \n")
#next if skip_record?(record)

if name = record[:name] and resource = resources[name]
Puppet.debug("Record name matches resource name. \n")
resource.provider = new(record)
elsif respond_to?(:match)
if resource = match(record, matchers)
# Remove this resource from circulation so we don't unnecessarily try to match
matchers.delete(resource.title)
record[:name] = resource[:name]
resource.provider = new(record)
end
end
end
end

end
69 changes: 69 additions & 0 deletions lib/puppet/type/oranfstab.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
require 'puppet/provider/parsedfile'

module Puppet
newtype(:oranfstab) do

@doc = "Define database mount points in /etc/oranfstab."

newparam(:name) do
desc "The instance's name."
isnamevar

validate do |value|
raise Puppet::Error, "Name must not contain whitespace: #{value}" if value =~ /\s/
raise Puppet::Error, "Name must not be empty" if value.empty?
end
end

ensurable

newproperty(:nfsserver) do
desc "The NFS Server hostname for this instance."
validate do |value|
raise Puppet::Error, "Nfsserver must contain a valid hostname: #{value}" unless value =~ /^[\w-]+$/
raise Puppet::Error, "Nfsserver must not be empty" if value.empty?
end
end

newproperty(:localips, :array_matching => :all) do
desc "The local IP(s) to use."
validate do |value|
raise Puppet::Error, "Localips should not be blank." if value.empty?
raise Puppet::Error, "Localips should contain valid IP address': #{value}" unless value =~ /^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$/
end
end

newproperty(:remoteips, :array_matching => :all) do
desc "The remote IP(s) to use."
validate do |value|
raise Puppet::Error, "Remoteips should not be blank." if value.empty?
raise Puppet::Error, "Remoteips should contain valid IP address': #{value}" unless value =~ /^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$/
end
end

newproperty(:mounts, :array_matching => :all) do
desc "Array of mounts"
validate do |value|
raise Puppet::Error, "Mounts should be an array of hashes." unless value.is_a?(Hash)
end

def insync?(is)
if is.is_a?(Array)
# array of hashes doesn't support .sort
return is.sort_by(&:hash) == @should.sort_by(&:hash)
else
return is == @should
end
end

def should_to_s(newvalue)
if newvalue == :absent
return "absent"
else
newvalue
end
end
end

end
end
Loading