13 # Load shell with default configuration
14 sys.path.append('/usr/share/plc_api')
15 from PLC.Shell import Shell
16 plc = Shell(globals())
18 parser = optparse.OptionParser()
19 parser.add_option('-l', '--linkspec', action='store_true', dest='genlinkspec', default=False, help='Generate linkspec dict.')
20 (options, args) = parser.parse_args()
23 # Links in the physical topology, gleaned from looking at the Internet2
24 # and NLR topology maps. Link (a, b) connects sites with IDs a and b.
26 links = [(2, 12), # I2 Princeton - New York
27 (4, 5), # NLR Chicago - Houston
28 (4, 6), # NLR Chicago - Atlanta
29 (4, 7), # NLR Chicago - Seattle
30 (4, 9), # NLR Chicago - New York
31 (4, 10), # NLR Chicago - Wash DC
32 (5, 6), # NLR Houston - Atlanta
33 (5, 8), # NLR Houston - Los Angeles
34 (6, 10), # NLR Atlanta - Wash DC
35 (7, 8), # NLR Seattle - Los Angeles
36 (9, 10), # NLR New York - Wash DC
37 (11, 13), # I2 Chicago - Wash DC
38 (11, 15), # I2 Chicago - Atlanta
39 (11, 16), # I2 Chicago - CESNET
40 (11, 17), # I2 Chicago - Kansas City
41 (12, 13), # I2 New York - Wash DC
42 (13, 15), # I2 Wash DC - Atlanta
43 (15, 19), # I2 Atlanta - Houston
44 (17, 19), # I2 Kansas City - Houston
45 (17, 22), # I2 Kansas City - Salt Lake City
46 (19, 20), # I2 Houston - Los Angeles
47 (20, 21), # I2 Los Angeles - Seattle
48 (20, 22), # I2 Los Angeles - Salt Lake City
49 (21, 22)] # I2 Seattle - Salt Lake City
52 def gen_adjacencies(links):
54 Generate site adjacency map from list of links
69 def is_adjacent(adjacencies, s1, s2):
71 Test whether two sites are adjacent to each other in the adjacency graph.
73 set1 = set(adjacencies[s1])
74 set2 = set(adjacencies[s2])
76 if s1 in set2 and s2 in set1:
78 elif not s1 in set2 and not s2 in set1:
81 raise Exception("Adjacency mismatch, sites %d and %d." % (s1, s2))
84 def check_adjacencies(adjacencies):
86 Check the adjacency graph for discrepancies.
88 for site in adjacencies:
89 for adj in adjacencies[site]:
91 test = is_adjacent(adjacencies, site, adj)
93 print "Error: ", e, " Fix adjacencies!"
99 return nodes[nodeid]['site_id']
100 raise Exception("Nodeid %s not found." % nodeid)
103 def get_ipaddr(nodeid):
105 return socket.gethostbyname(nodes[nodeid]['hostname'])
106 raise Exception("Nodeid %s not found." % nodeid)
109 def get_sitenodes(siteid):
111 return sites[siteid]['node_ids']
112 raise Exception("Siteid %s not found." % siteid)
115 def get_virt_ip(myid, nodeid):
117 Find the IP address assigned to a virtual interface in the topology
118 (for creating /etc/hosts)
121 virtip = "10.%d.%d.2" % (myid, nodeid)
123 virtip = "10.%d.%d.3" % (nodeid, myid)
129 Create a dictionary of site records keyed by site ID
132 for site in GetSites():
133 tmp[site['site_id']] = site
139 Create a dictionary of node records keyed by node ID
142 for node in GetNodes():
143 tmp[node['node_id']] = node
147 def ifSpecDict(nodedict):
149 Generate ifspec dict for given node dict.
151 # ifspecattrs = ['name',
159 # Assume only 1 node network per node.
160 nodenetwork = GetNodeNetworks(nodedict['nodenetwork_ids'])[0]
161 ifspecs = {'name': nodenetwork['hostname'],
162 'addr': nodenetwork['ip'],
163 'type': nodenetwork['type'],
167 'max_alloc': '1Gbps',
174 Create dict for physical topology.
176 # list of attributes in the LinkSpec
177 # (https://svn.planet-lab.org/svn/geniwrapper/trunk/rspec/model/planetlab.{ecore,xsd})
178 # linkspecattrs = ['type',
183 # 'endpoint', # <-- ifspec(S)?
186 # list of linkspecs. 1 per adjacency
188 # links maps sites. Get nodes in site, make linkspecs for each.
190 print "sites = (%s, %s) nodes = %s" %(i,j, GetNodes({'site_id':[i,j]}, ['node_id']))
191 nodeset = GetNodes({'site_id':[i,j]})
194 ifspecs.append(ifSpecDict(node))
201 'endpoints': ifspecs,
202 'start_time': int(time()),
207 adjacencies = gen_adjacencies(links)
208 check_adjacencies(adjacencies)
210 """ Need global topology information """
217 Scan the VINI Central database and create topology "rspec" attributes for
218 slices that have an EGRE key. This script to be run from a cron job.
221 for slice in GetSlices():
222 """ Create dictionary of the slice's attributes """
225 for attribute in GetSliceAttributes(slice['slice_attribute_ids']):
226 attrs[attribute['name']] = attribute['slice_attribute_id']
227 if attribute['name'] == 'topo_rspec' and attribute['node_id']:
228 topo_attr[attribute['node_id']] = attribute['slice_attribute_id']
230 if 'egre_key' in attrs:
231 #print "Virtual topology for %s:" % slice['name']
232 slicenodes = set(slice['node_ids'])
233 hosts = "127.0.0.1\t\tlocalhost\n"
235 For each node in the slice, check whether nodes at adjacent sites
236 are also in the slice's node set. If so, add a virtual link to
239 for node in slicenodes:
241 for adj in adjacencies[get_site(node)]:
242 for adj_node in get_sitenodes(adj):
243 if node != adj_node and adj_node in slicenodes:
244 link = adj_node, get_ipaddr(adj_node), "1Mbit"
246 shortname = nodes[node]['hostname'].replace('.vini-veritas.net', '')
247 hosts += "%s\t\t%s\n" % (get_virt_ip(node, adj_node),
249 topo_str = "%s" % topo
250 #print node, topo_str
251 if node in topo_attr:
252 UpdateSliceAttribute(topo_attr[node], topo_str)
255 id = slice['slice_id']
256 AddSliceAttribute(id, 'topo_rspec', topo_str, node)
260 UpdateSliceAttribute(attrs['hosts'], hosts)
262 id = slice['slice_id']
263 AddSliceAttribute(id, 'hosts', hosts)
265 #print "No EGRE key for %s" % slice['name']
267 """ Remove old topo_rspec entries """
268 for node in topo_attr:
269 DeleteSliceAttribute(topo_attr[node])
273 if __name__ == '__main__':
274 if options.genlinkspec:
278 pp.pprint(linkSpecDict())