Skip to content

Instantly share code, notes, and snippets.

@GeorgeDewar
Last active August 29, 2015 13:57
Show Gist options
  • Save GeorgeDewar/9881807 to your computer and use it in GitHub Desktop.
Save GeorgeDewar/9881807 to your computer and use it in GitHub Desktop.
Ruby script for converting SYDI XML files to readable Markdown
#!/usr/bin/env ruby
require 'xmlsimple'
require 'pp'
# Table widths will be padded in multiples of 10, so that small increases in maximum length will not always
# modify every line of the table (by increasing the width of the column)
PAD_MULTIPLE=10
# Map one or more hashes to strings within a table row by composing a string from the values in the hash. Fields
# can be a string or an array of fields. It can take a string (the single element to use as the value), or a lambda
# in the form |val| new_val
def map(row, fields, mapping, join=', ')
fields = [fields] if fields.kind_of? String
new_mapping = (mapping.kind_of? String) ? lambda { |val| val[mapping] } : mapping
fields.each { |field| row[field] = row[field].map(&new_mapping).join(join) if row[field] }
end
# Print a hash as a table in GFM, with consistent column widths for plain text readability
def print_table(data)
# Determine the width of each column, based on the maximum width of the rows
lengths = data[0].map do |k,v|
{ k => [data.map { |row| (row[k] || '').to_s.length }.max, k.length].max / PAD_MULTIPLE * PAD_MULTIPLE + PAD_MULTIPLE }
end.reduce({}, :merge)
puts data[0].map{ |k,v| k.ljust(lengths[k]) }.join ' | '
puts data[0].map{ |k,v| '-' * [lengths[k], 5].max }.join ' | '
data.each do |row|
puts (row.map{ |k,v| (v.to_s.strip! || v.to_s).ljust(lengths[k] || 0) }.join ' | ') + ' '
end
end
##
## Begin procedural code
##
# Read the XML document
doc = XmlSimple.xml_in(File.read(ARGV[0]))
# Show the IP routes in a table
if (doc['network'][0]['ip4routes'][0]['route'] rescue nil)
doc['network'][0]['ip4routes'] = doc['network'][0]['ip4routes'][0]['route']
end
# Comma-separate group member names
if (doc['localgroups'][0]['group'] rescue nil)
doc['localgroups'][0]['group'].each { |group| map group, 'member', 'name' }
end
# Format disk partitions
doc['storage'][0]['drives'].each do |device|
map device, 'partition', lambda { |val| "#{val['name']}, #{val['filesystem']}, #{val['size']}GB" }, '<br />'
end if (doc['storage'][0]['drives'] rescue nil)
# Format network adapters
doc['network'][0]['adapter'].each do |adapter|
map adapter, 'ip', lambda { |val| "#{val['address']}/#{val['subnetmask']}" }, '<br />'
map adapter, ['gateway', 'dnsserver', 'primarywins', 'secondarywins', 'dhcpserver'], 'address'
map adapter, 'dnsdomain', 'name'
end if (doc['network'][0]['adapter'] rescue nil)
# Format Microsoft IIS v2
doc['microsoftiisv2'][0]['iiswebserversetting'].each do |setting|
map setting, 'homedirectory', 'path'
map setting, 'serverbindings', lambda { |val| (val['hostname'] + ' ' + val['ip']).strip + ':' + val['port'] }
end if (doc['microsoftiisv2'][0]['iiswebserversetting'] rescue nil)
# Print a heading
puts "# Configuration for #{doc['system'][0]['name']}"
# Print each category
doc.each do |cat_name, cat|
puts "\n## #{cat_name}"
cat[0].each do |subcat_name, subcat_value|
if subcat_value.kind_of? String
puts "**#{subcat_name}**: #{subcat_value}"
else
puts "\n### #{subcat_name}\n\n" unless cat[0].length == 1
print_table(subcat_value)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment