diff --git a/dev/puppet/bind.rb b/dev/puppet/bind.rb index 4e825a53e0416c764ccec5627a11228998fc20a9..e14dbb5bddd1f2df446360b3802e9ea3318abcae 100644 --- a/dev/puppet/bind.rb +++ b/dev/puppet/bind.rb @@ -1,5 +1,7 @@ #!/usr/bin/ruby +# See also: https://www.grid5000.fr/mediawiki/index.php/DNS_server + require 'pp' require 'erb' require 'pathname' @@ -8,41 +10,35 @@ require '../lib/input_loader' refapi = load_yaml_file_hierarchy("../input/grid5000/") $output_dir = ENV['puppet_repo'] || 'output' -# Create a dns entry from: -# entry = -# {:cluster_uid=>"talc", -# :net_uid=>"eth0", -# :start=>134, -# :end=>134, -# :ip=>"172.16.66", -# :shift=>0, -# :mounted=>true} - +# Create a dns entry +# $GENERATE 1-16 graoully-$-bmc IN A 172.17.70.$ +# +# $GENERATE 1-16 graoully-$ IN A 172.16.70.$ +# $GENERATE 1-16 graoully-$-eth0 IN CNAME graoully-$ +# +# $GENERATE 1-16 graoully-$-eth0-kavlan-3 IN A 192.168.233.$ +# $GENERATE 1-16 graoully-$-kavlan-3 IN CNAME graoully-$-eth0-kavlan-3 +# def print_entry(entry) - - if entry[:start] == entry[:end] + if entry[:start].nil? range = "" - hostshort = "#{entry[:cluster_uid]}-#{entry[:start]}" - ip = "#{entry[:ip]}.#{entry[:start]+entry[:shift]}" + hostshort = entry[:uid] + ip = entry[:ip] + elsif entry[:start] == entry[:end] + range = "" + hostshort = "#{entry[:uid]}-#{entry[:start]}" # graoully-1 + ip = "#{entry[:ip]}.#{entry[:start]+entry[:shift]}" # 172.16.70.1 else range = "$GENERATE #{entry[:start]}-#{entry[:end]} " # $GENERATE 1-16 - hostshort = "#{entry[:cluster_uid]}-$" # graoully-$ + hostshort = "#{entry[:uid]}-$" # graoully-$ shift = (entry[:shift] > 0 ? '{+' + entry[:shift].to_s + '}' : '') ip = "#{entry[:ip]}.$#{shift}" # 172.16.70.$ end - - hostalias = nil - if entry[:mounted] && /^eth[0-9]$/.match(entry[:net_uid]) - # primary interface - hostalias = hostshort - elsif /^kavlan-[0-9]*$/.match(entry[:net_uid]) - # kvlan - hostalias = hostshort + "-eth0-#{entry[:net_uid]}" # graoully-$-eth0-kavlan-1 - end - hostname = hostshort + "-#{entry[:net_uid]}" # graoully-$-eth0 + hostname = entry[:hostsuffix] ? hostshort + entry[:hostsuffix] : hostshort # graoully-$-eth0 - if hostalias + if entry[:cnamesuffix] + hostalias = hostshort + entry[:cnamesuffix] return ["#{range}#{hostalias} IN A #{ip}", "#{range}#{hostname} IN CNAME #{hostalias}"].join("\n") else @@ -67,67 +63,120 @@ refapi["sites"].each { |site_uid, site| entries = {} + ["networks", "laptops", "dom0"].each { |key| + entries[key] ||= [] + + site[key].each { |uid, node| + if node['network_adapters'].nil? + puts "Warning: no network_adapters for #{uid}" + next + end + + eth_net_uid = node['network_adapters'].select{ |u, h| h['mounted'] && /^eth[0-9]$/.match(u) } # eth* interfaces + node['network_adapters'].each { |net_uid, net_hash| + hostsuffix = nil + if ! eth_net_uid.include?(net_uid) && node['network_adapters'].size > 1 + hostsuffix = "-#{net_uid}" + end + + + new_entry = { + :uid => uid, + :hostsuffix => hostsuffix, # cacahuete vs. cacahuete-eth0 + :ip => net_hash['ip'], + } + + entries[key] << new_entry + } + } + } + + # PDUs + entries['pdus'] ||= [] + site['pdus'].each { |pdu_uid, pdu| + if pdu['ip'] + + new_entry = { + :uid => pdu_uid, + :ip => pdu['ip'] + } + + entries['pdus'] << new_entry + + end + } + site.fetch("clusters").sort.each { |cluster_uid, cluster| #next if cluster_uid != 'griffon' cluster.fetch('nodes').each_sort_by_node_uid { |node_uid, node| - network_adapters = {} + # Nodes node.fetch('network_adapters').each { |net_uid, net_hash| - network_adapters[net_uid] = {"ip"=>net_hash["ip"], "mounted"=>net_hash["mounted"]} + network_adapters[net_uid] = {"ip" => net_hash["ip"], "mounted" => net_hash["mounted"]} } - + + # Kavlan node.fetch('kavlan').each { |net_uid, ip| - network_adapters[net_uid] = {"ip"=>ip, "mounted"=>nil} + network_adapters[net_uid] = {"ip" => ip, "mounted" => nil} } if node['kavlan'] # Group ip ranges network_adapters.each { |net_uid, net_hash| next unless net_hash['ip'] - - entries[cluster_uid] ||= {} - entries[cluster_uid][net_uid] ||= [] - last_entry = entries[cluster_uid][net_uid].last - + + entries["#{cluster_uid}-#{net_uid}"] ||= [] + last_entry = entries["#{cluster_uid}-#{net_uid}"].last + node_id = node_uid.to_s.split(/(\d+)/)[1].to_i # node number ip = net_hash['ip'] ip_array = ip.split('.') - - if last_entry and ip == last_entry[:ip] + '.' + (node_id + last_entry[:shift]).to_s and last_entry[:end] == node_id-1 and net_hash['mounted'] == last_entry[:mounted] + + if last_entry and ip == last_entry[:ip] + '.' + (node_id + last_entry[:shift]).to_s and last_entry[:end] == node_id-1 last_entry[:end] += 1 else - + + # CNAME entries + cnamesuffix = nil # no CNAME entry by default + if net_hash['mounted'] && /^eth[0-9]$/.match(net_uid) + # primary interface + cnamesuffix = '' + elsif /^kavlan-[0-9]*$/.match(net_uid) + # kavlan + net_primaries = network_adapters.select{ |u, h| h['mounted'] && /^eth[0-9]$/.match(u) } + cnamesuffix = "-#{net_primaries.keys.first}-#{net_uid}" # -eth0-kavlan-1 + end + # new range new_entry = { - :cluster_uid => cluster_uid, - :net_uid => net_uid, - :start => node_id, - :end => node_id, - :ip => ip_array[0..2].join("."), - :shift => ip_array[3].to_i - node_id, - :mounted => net_hash["mounted"] + :uid => cluster_uid, + :hostsuffix => "-#{net_uid}", # -eth0, -kavlan-1 + :cnamesuffix => cnamesuffix, # graoully-$-, graoully-$-eth0-kavlan-1 + :start => node_id, + :end => node_id, + :ip => ip_array[0..2].join("."), + :shift => ip_array[3].to_i - node_id, } - entries[cluster_uid][net_uid] << new_entry + entries["#{cluster_uid}-#{net_uid}"] << new_entry end } - - } # each node + } # each nodes + + } # each cluster # - # + # Output # output = [] - entries.each { |cluster_uid, cluster_entries| - cluster_entries.each { |net_uid, entries| - entries.each { |entry| - output << print_entry(entry) - } + entries.each { |type, e| + e.each { |entry| + output << print_entry(entry) } }