Skip to content

Instantly share code, notes, and snippets.

@marcinbunsch
Created November 5, 2010 17:26
Show Gist options
  • Save marcinbunsch/664487 to your computer and use it in GitHub Desktop.
Save marcinbunsch/664487 to your computer and use it in GitHub Desktop.
Simple hostfile manager
#!/usr/bin/env ruby
#
# Simple hostfile manager
#
# Only tested on OSX
#
# Usage:
#
# To list defined entries in the hostfile, call:
#
# sudo domain list [FILTER]
#
# If FILTER is not supplied, all entries will be listed. If it is supplied, list will only display entries matching the filter
#
# To add an entry to the hostfile, call:
#
# sudo domain add NAME [IP]
#
# IP is optional and will default to 127.0.0.1 if not specified
#
# To remove an entry to the hostfile, call:
#
# sudo domain remove NAME
#
#
# Examples:
# >> sudo domain add example.com
# Added example.com at 127.0.0.1 to /etc/hosts
# >> sudo domain add subdomain.example.com 127.0.0.1
# Added subdomain.example.com at 127.0.0.1 to /etc/hosts
# >> sudo domain list example
# 127.0.0.1 => example.com
# 127.0.0.1 => subdomain.example.com
# >> sudo domain remove subdomain.example.com
# Removed subdomain.example.com from /etc/hosts
#
#
# LICENSE
#
# Copyright (c) 2010 Marcin Bunsch <[email protected]>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
abort "You need to have root access to manage domains, please run 'sudo domain#{ARGV.size > 0 ? ' ' + ARGV.join(' ') : ''}'" unless ENV['SUDO_USER']
class HostFile
HOSTFILE = '/etc/hosts'
SEPARATOR = ' '
UNREMOVABLES = ['localhost']
HEADER = <<-STR
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
STR
attr_accessor :entries
def initialize
self.entries = File.open(HOSTFILE).read.split("\n").collect do |line|
next if line.strip[0] == 35
next if line.strip == ''
line.strip.split(/\s+/)
end.compact
end
def filename
HOSTFILE
end
def has?(name)
entries.find { |entry| entry[1] == name }
end
def removable?(name)
!UNREMOVABLES.include?(name)
end
def save
content = ([HEADER] + entries.compact.collect { |entry| "#{entry[0]}#{SEPARATOR}#{entry[1]}"}).join("\n")
f = File.open(HOSTFILE, 'w')
f.write(content)
f.close
end
def add(name, ip = "127.0.0.1")
self.entries << [(ip || "127.0.0.1"), name]
end
def add!(name, ip = "127.0.0.1")
add(name, ip)
save
end
def remove(name)
self.entries.reject! { |entry| entry[1] == name }
end
def remove!(name)
remove(name)
save
end
end
hostfile = HostFile.new
case command = ARGV[0]
when 'list'
filter = ARGV[1]
hostfile.entries.each do |entry|
if !filter or (filter and entry[1].match(filter))
puts "#{entry[0]} => #{entry[1]}"
end
end
when 'add'
name = ARGV[1]
abort "#{name} is already in #{hostfile.filename}" if hostfile.has?(name)
hostfile.add!(name, ARGV[2])
puts "Added #{hostfile.entries.last[1]} at #{hostfile.entries.last[0]} to #{hostfile.filename}"
when 'remove'
name = ARGV[1]
abort "#{name} is not in #{hostfile.filename}" unless hostfile.has?(name)
abort "#{name} cannot be removed from #{hostfile.filename}" unless hostfile.removable?(name)
hostfile.remove!(name)
puts "Removed #{name} from #{hostfile.filename}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment