9 from monitor import config
10 auth = {'Username' : config.API_AUTH_USER,
11 'AuthMethod' : "password",
12 'AuthString' : config.API_AUTH_PASSWORD}
15 print traceback.print_exc()
16 auth = {'AuthMethod' : "anonymous"}
20 def __init__(self, args = None):
21 if not args: args = {}
22 args['known_hosts'] = os.environ['HOME'] + os.sep + ".ssh" + os.sep + "known_hosts"
24 from monitor import config
25 args['XMLRPC_SERVER'] = config.API_SERVER
27 args['XMLRPC_SERVER'] = 'https://boot.planet-lab.org/PLCAPI/'
28 print "Using default API server %s" % args['XMLRPC_SERVER']
30 self.read_knownhosts()
32 self.api = xmlrpclib.Server(args['XMLRPC_SERVER'], verbose=False, allow_none=True)
33 self.nodenetworks = {}
35 def _split_kh_entry(self, line):
38 (host,ip) = s[0].split(',')
43 key = ' '.join(s[1:3])
44 comment = ' '.join(s[3:])
45 return (host, ip, key, comment)
47 def _get_index(self, host, ip):
50 index = "%s,%s" % (host,ip)
55 def read_knownhosts(self):
56 kh_read = open(self.args["known_hosts"], 'r')
60 (host, ip, key, comment) = self._split_kh_entry(line[:-1])
61 rec = { self._get_index(host, ip) : "%s %s" % (key, comment) }
62 if 'PlanetLab' in comment:
63 self.pl_keys.update(rec)
65 self.other_keys.update(rec)
67 #for i in self.pl_keys:
69 # print self.pl_keys[i]
74 self.write_knownhosts()
76 def write_knownhosts(self):
77 f = open(self.args['known_hosts'], 'w')
78 for index in self.pl_keys:
79 print >>f, "%s %s" % (index, self.pl_keys[index])
80 for index in self.other_keys:
81 print >>f, "%s %s" % (index, self.other_keys[index])
85 l_nodes = self.getNodes()
89 name = node['hostname']
94 (host, ip, key, comment) = self._record_from_node(node, nokey_list)
95 rec = { "%s,%s" % (host,ip) : "%s %s" % (key, comment) }
96 self.pl_keys.update(rec)
100 def delete(self, host):
101 node = self.getNodes(host)
103 (host, ip, _, _) = self._record_from_node(node[0])
104 index = "%s,%s" % (host,ip)
105 if index in self.pl_keys:
106 del self.pl_keys[index]
107 if index in self.other_keys:
108 del self.other_keys[index]
111 def updateDirect(self, host):
112 cmd = os.popen("/usr/bin/ssh-keyscan -t rsa %s 2>/dev/null" % host)
114 (h, ip, key, comment) = self._split_kh_entry(line[:-1])
115 node = self.getNodes(host)
116 (host2, ip2, x, x) = self._record_from_node(node[0])
117 rec = { self._get_index(host2, ip2) : "%s %s" % (key, "DIRECT") }
120 self.other_keys.update(rec)
122 def update(self, host):
123 node = self.delete(host)
124 #node = self.getNodes(host)
126 ret = self._record_from_node(node[0])
127 (host, ip, key, comment) = ret
129 self.updateDirect(host)
131 rec = { "%s,%s" % (host,ip) : "%s %s" % (key, comment) }
132 self.pl_keys.update(rec)
134 def getNodes(self, host=None):
135 if type(host) == type(""): host = [host]
137 # get the node(s) info
138 nodes = self.api.GetNodes(self.auth,host,["hostname","ssh_rsa_key","interface_ids"])
140 # for each node's node network, update the self.nodenetworks cache
143 for net in node["interface_ids"]:
144 nodenetworks.append(net)
146 plcnodenetworks = self.api.GetInterfaces(self.auth,nodenetworks,["interface_id","ip"])
147 for n in plcnodenetworks:
148 self.nodenetworks[n["interface_id"]]=n
151 def _record_from_node(self, node, nokey_list=None):
152 host = node['hostname']
153 key = node['ssh_rsa_key']
155 nodenetworks = node['interface_ids']
156 if len(nodenetworks)==0: return (host, None, None, None)
158 # the [0] subscript to node['interface_ids'] means
159 # that this function wont work with multihomed nodes
160 l_nw = self.nodenetworks.get(nodenetworks[0],None)
161 if l_nw is None: return (host, None, None, None)
165 if nokey_list is not None: nokey_list += [node]
166 return (host, ip, None, None)
169 # TODO: check for '==' at end of key.
170 if len(key) > 0 and key[-1] != '=':
171 print "Host with corrupt key! for %s %s" % (node['boot_state'], node['hostname'])
173 s_date = time.strftime("%Y/%m/%d_%H:%M:%S",time.gmtime(time.time()))
174 #rec = { "%s,%s" % (host,ip) : "%s %s" % (key, "PlanetLab_%s" % (s_date)) }
176 return (host, ip, key, "PlanetLab_%s" % s_date)
188 if __name__ == '__main__':