1 | #!/usr/bin/env python
|
---|
2 | # vim:ts=2:et:sw=2:ai
|
---|
3 | #
|
---|
4 | # Build topological network graph
|
---|
5 | # Rick van der Zwet <info@rickvanderzwet.nl>
|
---|
6 | import re
|
---|
7 | import sys
|
---|
8 | import glob
|
---|
9 | import tempfile
|
---|
10 | import subprocess
|
---|
11 | import gformat
|
---|
12 |
|
---|
13 | import urllib
|
---|
14 | import re
|
---|
15 | import yaml
|
---|
16 |
|
---|
17 | def get_yaml(gfile):
|
---|
18 | """ Get configuration yaml for 'item'"""
|
---|
19 | f = open(gfile, 'r')
|
---|
20 | datadump = yaml.load(f)
|
---|
21 | return datadump
|
---|
22 |
|
---|
23 | def write_yaml(gfile, datadump):
|
---|
24 | """ Write configuration yaml for 'item'"""
|
---|
25 | f = open(gfile, 'w')
|
---|
26 | f.write(yaml.dump(datadump, default_flow_style=False))
|
---|
27 | f.close()
|
---|
28 |
|
---|
29 | CACHE_FILE = '/tmp/rd2etrs.yaml'
|
---|
30 | coordinates = None
|
---|
31 |
|
---|
32 | def rd2etrs(xrd, yrd, hnap=0.0):
|
---|
33 | """ Convert rd to etrs """
|
---|
34 | global coordinates
|
---|
35 | if coordinates == None:
|
---|
36 | try:
|
---|
37 | coordinates = get_yaml(CACHE_FILE)
|
---|
38 | if coordinates.has_key((xrd, yrd)):
|
---|
39 | return coordinates[(xrd, yrd)]
|
---|
40 | except (IOError,AttributeError):
|
---|
41 | coordinates = dict()
|
---|
42 | pass
|
---|
43 |
|
---|
44 | item = dict()
|
---|
45 | item['xrd'] = xrd
|
---|
46 | item['yrd'] = yrd
|
---|
47 | item['hnap'] = hnap
|
---|
48 | f = urllib.urlopen('http://www.rdnap.nl/cgi-bin/rdetrs.pl?func=rd2etrs&xrd=%(xrd)s&yrd=%(yrd)s&hnap=%(hnap)s' % item)
|
---|
49 | raw = f.read()
|
---|
50 |
|
---|
51 | r = re.compile('name="([a-z_]+)" value="([0-9\.]+)"')
|
---|
52 | for i in r.finditer(raw):
|
---|
53 | name, value = i.group(1,2)
|
---|
54 | value = float(value)
|
---|
55 | item[name] = value
|
---|
56 |
|
---|
57 | lam = item['lam_deg'] + (item['lam_min'] + (item['lam_sec'] / 60)) / 60
|
---|
58 | phi = item['phi_deg'] + (item['phi_min'] + (item['phi_sec'] / 60)) / 60
|
---|
59 | coordinates[(xrd, yrd)] = (phi, lam)
|
---|
60 | write_yaml(CACHE_FILE, coordinates)
|
---|
61 | return (lam, phi)
|
---|
62 |
|
---|
63 | OUTFILE = 'network.png'
|
---|
64 |
|
---|
65 | def make_graph():
|
---|
66 | f = open('kmlfile.kml', 'w')
|
---|
67 | f.write("""
|
---|
68 | <?xml version="1.0" encoding="UTF-8"?>
|
---|
69 | <kml xmlns="http://earth.google.com/kml/2.0">
|
---|
70 | <Document>
|
---|
71 | <name>KML Samples</name>
|
---|
72 | <open>1</open>
|
---|
73 | <description>Unleash your creativity with the help of these examples!</description>
|
---|
74 | <Style id="downArrowIcon">
|
---|
75 | <IconStyle>
|
---|
76 | <Icon>
|
---|
77 | <href>http://maps.google.com/mapfiles/kml/pal4/icon28.png</href>
|
---|
78 | </Icon>
|
---|
79 | </IconStyle>
|
---|
80 | </Style>
|
---|
81 | <Style id="globeIcon">
|
---|
82 | <IconStyle>
|
---|
83 | <Icon>
|
---|
84 | <href>http://maps.google.com/mapfiles/kml/pal3/icon19.png</href>
|
---|
85 | </Icon>
|
---|
86 | </IconStyle>
|
---|
87 | <LineStyle>
|
---|
88 | <width>2</width>
|
---|
89 | </LineStyle>
|
---|
90 | </Style>
|
---|
91 | <Style id="transPurpleLineGreenPoly">
|
---|
92 | <LineStyle>
|
---|
93 | <color>7fff00ff</color>
|
---|
94 | <width>4</width>
|
---|
95 | </LineStyle>
|
---|
96 | <PolyStyle>
|
---|
97 | <color>7f00ff00</color>
|
---|
98 | </PolyStyle>
|
---|
99 | </Style>
|
---|
100 | <Style id="yellowLineGreenPoly">
|
---|
101 | <LineStyle>
|
---|
102 | <color>7f00ffff</color>
|
---|
103 | <width>4</width>
|
---|
104 | </LineStyle>
|
---|
105 | <PolyStyle>
|
---|
106 | <color>7f00ff00</color>
|
---|
107 | </PolyStyle>
|
---|
108 | </Style>
|
---|
109 | <Style id="thickBlackLine">
|
---|
110 | <LineStyle>
|
---|
111 | <color>87000000</color>
|
---|
112 | <width>10</width>
|
---|
113 | </LineStyle>
|
---|
114 | </Style>
|
---|
115 | <Style id="redLineBluePoly">
|
---|
116 | <LineStyle>
|
---|
117 | <color>ff0000ff</color>
|
---|
118 | </LineStyle>
|
---|
119 | <PolyStyle>
|
---|
120 | <color>ffff0000</color>
|
---|
121 | </PolyStyle>
|
---|
122 | </Style>
|
---|
123 | <Style id="blueLineRedPoly">
|
---|
124 | <LineStyle>
|
---|
125 | <color>ffff0000</color>
|
---|
126 | </LineStyle>
|
---|
127 | <PolyStyle>
|
---|
128 | <color>ff0000ff</color>
|
---|
129 | </PolyStyle>
|
---|
130 | </Style>
|
---|
131 | <Style id="transRedPoly">
|
---|
132 | <LineStyle>
|
---|
133 | <width>1.5</width>
|
---|
134 | </LineStyle>
|
---|
135 | <PolyStyle>
|
---|
136 | <color>7d0000ff</color>
|
---|
137 | </PolyStyle>
|
---|
138 | </Style>
|
---|
139 | <Style id="transBluePoly">
|
---|
140 | <LineStyle>
|
---|
141 | <width>1.5</width>
|
---|
142 | </LineStyle>
|
---|
143 | <PolyStyle>
|
---|
144 | <color>7dff0000</color>
|
---|
145 | </PolyStyle>
|
---|
146 | </Style>
|
---|
147 | <Style id="transGreenPoly">
|
---|
148 | <LineStyle>
|
---|
149 | <width>1.5</width>
|
---|
150 | </LineStyle>
|
---|
151 | <PolyStyle>
|
---|
152 | <color>7d00ff00</color>
|
---|
153 | </PolyStyle>
|
---|
154 | </Style>
|
---|
155 | <Style id="transYellowPoly">
|
---|
156 | <LineStyle>
|
---|
157 | <width>1.5</width>
|
---|
158 | </LineStyle>
|
---|
159 | <PolyStyle>
|
---|
160 | <color>7d00ffff</color>
|
---|
161 | </PolyStyle>
|
---|
162 | </Style>
|
---|
163 | <Style id="noDrivingDirections">
|
---|
164 | <BalloonStyle>
|
---|
165 | <text><![CDATA[
|
---|
166 | <b>$[name]</b>
|
---|
167 | <br /><br />
|
---|
168 | $[description]
|
---|
169 | ]]></text>
|
---|
170 | </BalloonStyle>
|
---|
171 | </Style>
|
---|
172 | <Folder>
|
---|
173 | <name>Paths</name>
|
---|
174 | <visibility>0</visibility>
|
---|
175 | <description>Examples of paths. Note that the tessellate tag is by default
|
---|
176 | set to 0. If you want to create tessellated lines, they must be authored
|
---|
177 | (or edited) directly in KML.</description>
|
---|
178 | """)
|
---|
179 |
|
---|
180 | poel = {}
|
---|
181 | link_type = {}
|
---|
182 | node = {}
|
---|
183 |
|
---|
184 | nodes = []
|
---|
185 | links = []
|
---|
186 | try:
|
---|
187 | for host in gformat.get_proxylist() + gformat.get_nodelist():
|
---|
188 | print "## Processing host", host
|
---|
189 | datadump = gformat.get_yaml(host)
|
---|
190 | iface_keys = [elem for elem in datadump.keys() if (elem.startswith('iface_') and not "lo0" in elem)]
|
---|
191 | for iface_key in iface_keys:
|
---|
192 | l = datadump[iface_key]['ip']
|
---|
193 | addr, mask = l.split('/')
|
---|
194 |
|
---|
195 | addr = gformat.parseaddr(addr)
|
---|
196 | mask = int(mask)
|
---|
197 | addr = addr & ~((1 << (32 - mask)) - 1)
|
---|
198 | if poel.has_key(addr):
|
---|
199 | poel[addr] += [host]
|
---|
200 | else:
|
---|
201 | poel[addr] = [host]
|
---|
202 | # Assume all eth2wifibridge to be 11a for a moment
|
---|
203 | if datadump[iface_key].has_key('eth2wifibridge'):
|
---|
204 | link_type[addr] = '11a'
|
---|
205 | else:
|
---|
206 | link_type[addr] = datadump[iface_key]['type']
|
---|
207 | print "### %s [%s] is of type %s" % (gformat.showaddr(addr), iface_key, link_type[addr])
|
---|
208 | lam, phi = rd2etrs(datadump['rdnap_x'], datadump['rdnap_y'])
|
---|
209 | node[host] = (lam, phi)
|
---|
210 | f.write("""
|
---|
211 | <Placemark>
|
---|
212 | <name>Blue Icon</name>
|
---|
213 | <description>Just another blue icon.</description>
|
---|
214 | <styleUrl>./styles.kml#blueIcons</styleUrl>
|
---|
215 | <Point>
|
---|
216 | <coordinates>%s,%s,630</coordinates>
|
---|
217 | </Point>
|
---|
218 | </Placemark>
|
---|
219 | """ % (lam, phi))
|
---|
220 | nodes += [("POINT(%s, %s)" % (lam, phi))]
|
---|
221 | except (KeyError, ValueError), e:
|
---|
222 | print "[FOUT] in '%s' interface '%s'" % (host,iface_key)
|
---|
223 | print e
|
---|
224 | sys.exit(1)
|
---|
225 |
|
---|
226 | for addr,leden in poel.iteritems():
|
---|
227 | if link_type[addr] == '11a':
|
---|
228 | color = 'red'
|
---|
229 | weight = 4
|
---|
230 | elif link_type[addr] == 'eth':
|
---|
231 | color = 'blue'
|
---|
232 | weight = 8
|
---|
233 | else:
|
---|
234 | color = 'black'
|
---|
235 | weight = 1
|
---|
236 | leden = sorted(set(leden))
|
---|
237 | for index,lid in enumerate(leden[:-1]):
|
---|
238 | for buur in leden[index + 1:]:
|
---|
239 | f.write("""
|
---|
240 | <Placemark>
|
---|
241 | <name>Untessellated</name>
|
---|
242 | <visibility>0</visibility>
|
---|
243 | <description><![CDATA[If the <tessellate> tag has a value of 0, the line follow a simple straight-line path from point to point]]></description>
|
---|
244 | <LineString>
|
---|
245 | <tessellate>0</tessellate>
|
---|
246 | <coordinates> %s, %s, 0
|
---|
247 | %s , %s, 0 </coordinates>
|
---|
248 | </LineString>
|
---|
249 | </Placemark>
|
---|
250 | """ % (node[lid][0], node[lid][1], node[buur][0], node[buur][1]))
|
---|
251 | f.write("""
|
---|
252 | </Folder>
|
---|
253 | </Document>
|
---|
254 | </kml>
|
---|
255 | """)
|
---|
256 | f.close()
|
---|
257 |
|
---|
258 |
|
---|
259 | if __name__ == "__main__":
|
---|
260 | make_graph()
|
---|
261 |
|
---|