2 # Functions for interacting with the pcus table in the database
4 # Mark Huang <mlhuang@cs.princeton.edu>
5 # Copyright (C) 2006 The Trustees of Princeton University
7 # $Id: PCUs.py,v 1.2 2006/10/11 19:54:53 mlhuang Exp $
10 from PLC.Faults import *
11 from PLC.Parameter import Parameter
12 from PLC.Debug import profile
13 from PLC.Table import Row, Table
14 from PLC.NodeNetworks import valid_ip, NodeNetwork, NodeNetworks
15 from PLC.Nodes import Node, Nodes
19 Representation of a row in the pcus table. To use,
20 instantiate with a dict of values.
24 primary_key = 'pcu_id'
26 'pcu_id': Parameter(int, "PCU identifier"),
27 'site_id': Parameter(int, "Identifier of site where PCU is located"),
28 'hostname': Parameter(str, "PCU hostname", max = 254),
29 'ip': Parameter(str, "PCU IP address", max = 254),
30 'protocol': Parameter(str, "PCU protocol, e.g. ssh, https, telnet", max = 16),
31 'username': Parameter(str, "PCU username", max = 254),
32 'password': Parameter(str, "PCU username", max = 254),
33 'notes': Parameter(str, "Miscellaneous notes", max = 254),
34 'model': Parameter(str, "PCU model string", max = 32),
35 'node_ids': Parameter([int], "List of nodes that this PCU controls", ro = True),
36 'ports': Parameter([int], "List of the port numbers that each node is connected to", ro = True),
39 def __init__(self, api, fields = {}):
40 Row.__init__(self, fields)
43 def validate_ip(self, ip):
45 raise PLCInvalidArgument, "Invalid IP address " + ip
48 def add_node(self, node, port, commit = True):
50 Add node to existing PCU.
53 assert 'pcu_id' in self
54 assert isinstance(node, Node)
55 assert isinstance(port, (int, long))
56 assert 'node_id' in node
58 pcu_id = self['pcu_id']
59 node_id = node['node_id']
61 if node_id not in self['node_ids'] and port not in self['ports']:
62 self.api.db.do("INSERT INTO pcu_node (pcu_id, node_id, port)" \
63 " VALUES(%(pcu_id)d, %(node_id)d, %(port)d)",
69 self['node_ids'].append(node_id)
70 self['ports'].append(port)
72 def remove_node(self, node, commit = True):
74 Remove node from existing PCU.
77 assert 'pcu_id' in self
78 assert isinstance(node, Node)
79 assert 'node_id' in node
81 pcu_id = self['pcu_id']
82 node_id = node['node_id']
84 if node_id in self['node_ids']:
85 i = self['node_ids'].index(node_id)
86 port = self['ports'][i]
88 self.api.db.do("DELETE FROM pcu_node" \
89 " WHERE pcu_id = %(pcu_id)d" \
90 " AND node_id = %(node_id)d",
96 self['node_ids'].remove(node_id)
97 self['ports'].remove(port)
99 def delete(self, commit = True):
104 assert 'pcu_id' in self
106 # Clean up various join tables
107 for table in ['pcu_node', 'pcus']:
108 self.api.db.do("DELETE FROM " + table +
109 " WHERE pcu_id = %(pcu_id)d",
117 Representation of row(s) from the pcus table in the
121 def __init__(self, api, pcu_ids = None):
124 # N.B.: Node IDs returned may be deleted.
125 sql = "SELECT %s FROM view_pcus" % \
126 ", ".join(PCU.fields)
129 sql += " WHERE pcu_id IN (%s)" % ", ".join(map(str, pcu_ids))
131 rows = self.api.db.selectall(sql)
134 self[row['pcu_id']] = pcu = PCU(api, row)
135 for aggregate in ['node_ids', 'ports']:
136 if not pcu.has_key(aggregate) or pcu[aggregate] is None:
139 pcu[aggregate] = map(int, pcu[aggregate].split(','))