These are the source code files for the Ruby -vs- PHP Showcase: nsupdate script Read the full story in my blog.
#!/usr/bin/env ruby require 'yaml' # http://yaml.org/ require 'cgi' # http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/ # # Ruby CGI showcase # Copyright (c) 2006 Christian W. Zuckschwerdt <zany@triq.net> # based on nsupdate.php, Copyright 2005, Chip Rosenthal <chip@unicom.com>. # # # *** Edit this to point to where your config file is installed. # config_file = '/home/zany/workspace/ruby-nsupdate/nsupdate.yml' @config = YAML.load_file config_file # # Template to generate command script for nsupdate(8). # NSUPATE_COMMAND_TEMPLATE = <<'EOT' "server #{hostinfo['nameserver']} zone #{domain} update delete #{host} update add #{host} #{hostinfo['ttl']} A #{addr} send" EOT # # Web page with form for manual entry. # NSUPDATE_MANUAL_FORM = <<'EOT' <html> <head> <title>web-nsupdate: Manual Entry</title> </head> <body> <h1>web-nsupdate: Manual Entry</h1> <form method="get"> <table border="0" cellspaceing="0" cellpadding="3"> <tr> <td><label for="host">Host Name:</label></td> <td><input type="text" name="host" /></td> </tr> <tr> <td><label for="addr">Host Address:</label></td> <td><input type="text" name="addr" /></td> </tr> <tr> <td><label for="key">Password:</label></td> <td><input type="password" name="key" /></td> </tr> <tr> <td> </td> <td> <input type="hidden" name="verbose" value="1" /> <input type="submit" /> <input type="reset" /> </td> </tr> </table> </form> <hr> <p style="font-size:smaller"> based on work © 2005 <a href="http://www.unicom.com/sw/">Unicom Systems Development</a></p> </body> </html> EOT # # Template for web page with success response for manual update. # NSUPATE_MANUAL_RESPONSE = <<'EOT' "<html> <head> <title>web-nsupdate: Manual Update Successful</title> </head> <body> <h1>web-nsupdate: Manual Update Successful</h1> <p>Host <i>#{host}</i> has been assigned address <i>#{addr}</i>.</p> <hr> <p style='font-size:smaller'>based on work © 2005 <a href='http://www.unicom.com/sw/'>Unicom Systems Development</a></p> </body> </html>" EOT # # Retrieve information from @config for a specified host. # - host Name of the host to lookup. # Returns Hash (key/value pairs) of information on the host. # The host info is a keyed with the following items # defined: key, nskey, nameserver, ttl. # Values not specified for the host are defined to the default. # An error is raised if the host is not defined. # def get_hostinfo(host) return unless @config.include? 'defaults' return unless @config.include? host defaults = @config['defaults'] || {} defaults.merge @config[host] end # # Validate an authorization key for a host. # - hostinfo Host information array. # - key Key to validate. # Returns true/false. # # def validate_host(hostinfo, key) hostinfo["key"] == key end # # Extract the domain name name portion from a fully qualified host name. # - host The fully qualified host name. # Returns The extracted domain name. # # def domain_from_hostname(host) host[host.index('.')+1..-1] rescue nil end ######################################################################## # # Main execution begins here. # cgi = CGI.new # # Retrieve input from user. # if (host = "#{cgi['host']}").empty? # If host not specified, present form for manual data entry. puts NSUPDATE_MANUAL_FORM exit 0 end if (addr = "#{cgi['addr']}").empty? raise "Required parameter \"addr\" not specified." end if (key = "#{cgi['key']}").empty? raise "Required parameter \"key\" not specified." end # # Lookup this host and validate the password. # raise "Host #{host} unknown." unless hostinfo = get_hostinfo(host) raise "Permission denied." unless validate_host(hostinfo, key) domain = domain_from_hostname(host) raise "Cannot extract domain from hostname." unless domain # # Generate a command script for nsupdate(8). # content = eval NSUPATE_COMMAND_TEMPLATE # # Run the nsupdate(8) command. # IO.popen ("nsupdate -k #{hostinfo['nskey']}", 'w') { |io| io.puts content } #raise "nsupdate command failed." unless rc # # Normally we exit quietly on success. # If we were running manually, send an HTML response. # if (cgi['verbose']) eval NSUPATE_MANUAL_RESPONSE else "OK" end