bind.rb 5.38 KB
Newer Older
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
1
2
#!/usr/bin/ruby

Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
3
4
5
6
7
if RUBY_VERSION < "2.1"
  puts "This script requires ruby >= 2.1"
  exit
end

8
9
# See also: https://www.grid5000.fr/mediawiki/index.php/DNS_server

Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
10
11
require 'pp'
require 'erb'
12
require 'pathname'
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
13
14
require '../lib/input_loader'

15
16
refapi = load_yaml_file_hierarchy("../input/grid5000/")
$output_dir = ENV['puppet_repo'] || 'output'
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
17

18
19
20
21
22
23
24
25
26
# 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
#
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
27
def print_entry(entry)
28
  if entry[:start].nil?
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
29
    range     = ""
30
31
32
33
34
35
    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
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
36
37
  else
    range     = "$GENERATE #{entry[:start]}-#{entry[:end]} "                  # $GENERATE 1-16
38
    hostshort = "#{entry[:uid]}-$"                                    # graoully-$
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
39
40
41
42
    shift     = (entry[:shift] > 0 ? '{+' + entry[:shift].to_s  + '}' : '')   
    ip        = "#{entry[:ip]}.$#{shift}"                                     # 172.16.70.$
  end

43
  hostname  = entry[:hostsuffix] ? hostshort + entry[:hostsuffix] : hostshort # graoully-$-eth0
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
44

45
46
  if entry[:cnamesuffix]
    hostalias = hostshort + entry[:cnamesuffix]
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
47
48
49
50
    return ["#{range}#{hostalias} IN A #{ip}",
            "#{range}#{hostname} IN CNAME #{hostalias}"].join("\n")
  else
    return "#{range}#{hostname} IN A #{ip}"
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
51
  end 
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
52
  
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
53
end
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
54

Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
55
# Loop over Grid'5000 sites
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
56

57
refapi["sites"].each { |site_uid, site|
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
58
  next if site_uid != 'nancy'
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
59
60
61

  entries = {}

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  ["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
  }
  
105
  site.fetch("clusters").sort.each { |cluster_uid, cluster|
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
106
    #next if cluster_uid != 'griffon'
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
107

108
    cluster.fetch('nodes').each_sort_by_node_uid { |node_uid, node|
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
109
      network_adapters = {}
110

111
      # Nodes
112
      node.fetch('network_adapters').each { |net_uid, net_hash|
113
        network_adapters[net_uid] = {"ip" => net_hash["ip"], "mounted" => net_hash["mounted"]}
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
114
      }
115
116
      
      # Kavlan
117
      node.fetch('kavlan').each { |net_uid, ip|
118
        network_adapters[net_uid] = {"ip" => ip, "mounted" => nil}
119
      } if node['kavlan']
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
120

121
122
123
124
125
      # Mic
      if node['mic'] && node['mic']['ip']
        network_adapters['mic0'] = {"ip" => node['mic']['ip']}
      end
      
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
126
      # Group ip ranges
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
127
      network_adapters.each { |net_uid, net_hash|
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
128
        next unless net_hash['ip']
129
130
131
132
        
        entries["#{cluster_uid}-#{net_uid}"] ||= []
        last_entry = entries["#{cluster_uid}-#{net_uid}"].last
        
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
133
        node_id = node_uid.to_s.split(/(\d+)/)[1].to_i # node number
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
134
135
        ip = net_hash['ip']
        ip_array = ip.split('.')
136
137
        
        if last_entry and ip == last_entry[:ip] + '.' + (node_id + last_entry[:shift]).to_s and last_entry[:end] == node_id-1
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
138
          last_entry[:end] += 1
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
139
        else
140
141
142
143
144
145
146
147
148
149
150
151
          
          # 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
          
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
152
153
          # new range
          new_entry = {
154
155
156
157
158
159
160
            :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,
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
161
162
          }
          
163
          entries["#{cluster_uid}-#{net_uid}"] << new_entry
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
164
165
        end
      }
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
166

167
168
169
    } # each nodes
    
    
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
170
171
172
173
  } # each cluster
  

  #
174
  # Output
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
175
176
177
  #

  output = []
178
179
180
  entries.each { |type, e|
    e.each { |entry|
      output << print_entry(entry)
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
181
182
    }
  }
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
183
  
184
  output_file = Pathname("#{$output_dir}/modules/bindg5k/files/zones/#{site_uid}/#{site_uid}-clusters.db")
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
185
186
187
188
  output_file.dirname.mkpath()
  File.write(output_file, output.join("\n"))
  
} # each sites
Jérémie Gaidamour's avatar
Jérémie Gaidamour committed
189