#!/usr/bin/ruby # # NAME # # symbiosis-dns-generate - Generate DNS snippet files for Symbiosis domains. # # USAGE # # symbiosis-dns-generate [ --sleep SEC | -s SEC ] [ --template TEMPLATE | -t TEMPLATE ] # [ --force | -f ] [ --verbose | -v ] # [ --help | -h ] [ DOMAIN ] # # SYNOPSIS # # --sleep SEC sleep for a random amount of time before doing # anything, up to a maximum of SEC seconds. # # --template TEMPLATE Specify an alternative template file to read. # # --force Force the re-creation of all DNS data. # --help Show the help information for this script. # --verbose Show debugging information. # # DETAILS # # This script is designed to iterate over the domains hosted upon a Symbiosis # system, and create DNS snippets for each one. This can then be published # using the Mythic Beasts DNS API. # # Domains can also be specified manually on the command line, in which case # only those domains will be processed. # # AUTHOR # # Steve Kemp # Adapted for Mythic Beasts by Ben Charlton # require 'getoptlong' # # Entry point to the code # force = false help = false $VERBOSE = false # # The root directory -- '/' by default. # root = "/" dns_template = nil sleep_for = nil opts = GetoptLong.new( [ '--force', '-f', GetoptLong::NO_ARGUMENT ], [ '--help', '-h', GetoptLong::NO_ARGUMENT ], [ '--sleep', '-s', GetoptLong::REQUIRED_ARGUMENT ], [ '--template', '-t', GetoptLong::REQUIRED_ARGUMENT ], [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ] ) opts.each do |opt, arg| case opt when '--help' help = true when '--verbose' $VERBOSE = true when '--template' dns_template = arg when '--sleep' sleep_for = arg when '--root' root = arg when '--force' force = true end end # # CAUTION! Here be quality kode. # if help # Open the file, stripping the shebang line lines = File.open(__FILE__){|fh| fh.readlines}[2..-1] lines.each do |line| line.chomp! break if line.empty? puts line[2..-1].to_s end exit 0 end def verbose(s) puts s if $VERBOSE end require 'symbiosis/domains' require 'symbiosis/domain' require 'symbiosis/config_files/mythicdns' # # Set the default paths. # dns_template = File.join(root, "/etc/symbiosis/dns.d/mythicdns.template.erb") if dns_template.nil? # # Bail out if the template is missing # unless File.file?(dns_template) verbose "Unable generate DNS data because the template #{dns_template.inspect} is missing." exit 1 end # # Work out if we need to sleep. # unless sleep_for.nil? sleep_for = (sleep_for =~ /(\d+)/ ? rand($1.to_i) : 0) verbose "Sleeping for #{sleep_for}s before starting work" sleep sleep_for end # # Any arguments on the command line specify which domains to do. # domains_to_configure = ARGV string_to_hash = [] # # For each domain. # Symbiosis::Domains.each do |domain| verbose "Domain: #{domain.name} " next unless domains_to_configure.empty? or domains_to_configure.include?(domain.name) begin output = File.join(domain.config_dir, "dns", domain.name+".txt") output_dir = File.dirname(output) config = Symbiosis::ConfigFiles::Tinydns.new(output, "#") config.domain = domain config.template = dns_template # # Should the snippet be created? # do_create = false if ( force ) verbose "\tForcing re-creation of snippet due to --force." do_create = true elsif config.exists? if config.changed? verbose "\tNot updating snippet, as it has been edited by hand." elsif config.outdated? verbose "\tRe-creating snippet as it is out of date." do_create = true else verbose "\tDomain already present and up-to date." end else verbose "\tConfiguring site for the first time" do_create = true end # # # Check the TinyDNS syntax.. TODO! # if do_create if config.ok? verbose "\tWriting snippet to #{output}" # # Create directory with the same ownership as the parent # domain.create_dir(output_dir) unless File.exist?(output_dir) # # Write the snippet # config.write # # Make sure the ownership is correct. # File.chown(domain.uid, domain.gid, config.filename) else verbose "\tThe new DNS snippet is invalid -- no changes have been made." end end # # Rescue errors for this domain, but continue for others. # rescue StandardError => err verbose "\tUnable to create DNS data for #{domain.name} because #{err.to_s}" verbose "\t"+err.backtrace.join("\n\t") end end begin upload_script = "/usr/sbin/symbiosis-dns-mythic" fflag = "" vflag = "" if force fflag = "--force" end if $VERBOSE vflag = "--verbose" end verbose "Uploading using #{upload_script}" IO.popen("#{upload_script} #{fflag} #{vflag} 2>&1","r") do |io| while !io.eof? do verbose io.readline end end unless 0 == $? raise StandardError, "#{upload_script.inspect} failed." end rescue StandardError => err warn "Unable to upload DNS data because #{err.to_s}" verbose "\t"+err.backtrace.join("\n\t") exit 1 end # # All done. # exit 0