Skip to content

Instantly share code, notes, and snippets.

@dmerrick
Created June 8, 2009 18:22
Show Gist options
  • Save dmerrick/125973 to your computer and use it in GitHub Desktop.
Save dmerrick/125973 to your computer and use it in GitHub Desktop.
For Morgan: parses an ethers file to generate a dhcpd.conf file.
#!/usr/bin/env ruby -wKU
# This program scans your ethers file to generate a valid dhcpd.conf file
# (or at least a segment of one). In addition, it will read your hosts file
# to see if there are any known aliases it can add. It then prints the
# formatted results to standard out.
#
# Author:: Dana Merrick (mailto:letterkills+ethers@gmail.com)
# Copyright:: Copyright (c) 2009 Dana Merrick
# License:: Released under the MIT license
# This class holds the tools for parsing the ethers file. It is meant to be
# executed by calling the #parse_ethers_file method.
class EthersFile
# accessors for class variables
# TODO: change them to attr_writers?
attr_accessor :ethers_file, :hosts_file, :regexps
# Build the object with default options:
# * /etc/ethers as the ethers file
# * /etc/hosts as the hosts file
def initialize(defaults)
@ethers_file = "/etc/ethers"
@hosts_file = "/etc/hosts"
@regexps = defaults
end
# Returns an array of aliases for the given host name.
def find_aliases(host)
# read each match into an array
aliases = File.readlines(hosts_file).grep(/#{host}/)
# remove line-long comments
aliases.reject!{ |line| line =~ /^#.*/ }
# remove comments at end of line
aliases.each { |line| line.sub!(/#.*/,'') }
# combine, split again on whitespace
aliases = aliases.join.split(/\s+/)
# sort and remove duplicates
aliases.sort.uniq!
# don't include the hostname as an alias
aliases.reject! { |item| item == host }
# finally, remove anything in the regexp array
regexps.each {|re| aliases.reject! {|item| item =~ re }}
return aliases
end
# Prints the information in the dhcpd.conf format. Including aliases
# if applicable (the hostname is found in the hosts file).
def format(mac, host)
# find the aliases for the host
aliases = find_aliases(host)
# change here for formatting tweaks
puts
puts "host #{host} {"
puts " hardware ethernet #{mac}"
puts " aliases #{aliases.join(" ")}" unless aliases.empty?
puts "}"
end
# Add an exclusion rule for the aliases section. For instance, you could
# exclude IP addresses, "localhost," or any other alias you want ignored.
def add_rule(rule)
raise ArgumentError unless rule.is_a?(Regexp)
regexps << rule
end
# The main method in this class. Will read the ethers file, dig out the
# host and MAC address information, and call the #format method for each
# pair.
#--
# TODO: more robust matching for valid lines (regexps)
# TODO: can ethers files have end of line comments?
def parse_ethers_file
# open ethers file and scan each line
File.open(ethers_file).each do |line|
# ignore comments and blank lines
unless line =~ /^#.*/ or line =~ /^\s*$/
# format and print each line in the specified format
format(*line.split(/\s+/))
end
end
end
end
# Configuration options and execution process.
if $0 == __FILE__
e = EthersFile.new([])
# the name of the files we're accessing
e.ethers_file = "ethers"
#e.hosts_file = "/etc/hosts"
# add rules for items that you want removed from the aliases list
e.add_rule(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/) # IPv4 addresses
e.add_rule(/::/) # IPv6 addresses (hacky!)
# start the parsing and print
e.parse_ethers_file
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment