# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id$
-# $URL$
-#
from types import StringTypes
import re
from PLC.NodeTypes import NodeTypes
from PLC.BootStates import BootStates
from PLC.Interfaces import Interface, Interfaces
+from PLC.IpAddresses import SimpleAddress
def valid_hostname(hostname):
# 1. Each part begins and ends with a letter or number.
primary_key = 'node_id'
join_tables = [ 'slice_node', 'peer_node', 'slice_tag',
'node_session', 'node_slice_whitelist',
- 'node_tag', 'conf_file_node', 'pcu_node', 'leases', ]
+ 'node_tag', 'conf_file_node', 'pcu_node', 'leases', 'routes']
fields = {
'node_id': Parameter(int, "Node identifier"),
'node_type': Parameter(str,"Node type",max=20),
'last_download': Parameter(int, "Date and time when node boot image was created", ro = True),
'last_pcu_reboot': Parameter(int, "Date and time when PCU reboot was attempted", ro = True),
'last_pcu_confirmation': Parameter(int, "Date and time when PCU reboot was confirmed", ro = True),
+ 'last_time_spent_online': Parameter(int, "Length of time the node was last online before shutdown/failure", ro = True),
+ 'last_time_spent_offline': Parameter(int, "Length of time the node was last offline after failure and before reboot", ro = True),
'verified': Parameter(bool, "Whether the node configuration is verified correct", ro=False),
+ 'dns': Parameter(str, "Comma-separated list of dns servers", max=255, nullok=True),
+ 'ntp': Parameter(str, "Comma-separated list of ntp servers", max=255, nullok=True),
'key': Parameter(str, "(Admin only) Node key", max = 256),
'session': Parameter(str, "(Admin only) Node session value", max = 256, ro = True),
'interface_ids': Parameter([int], "List of network interfaces that this node has"),
'peer_node_id': Parameter(int, "Foreign node identifier at peer", nullok = True),
'node_tag_ids' : Parameter ([int], "List of tags attached to this node"),
'nodegroup_ids': Parameter([int], "List of node groups that this node is in"),
+ 'route_ids': Parameter([int], "List of routes attached to this node"),
}
related_fields = {
'interfaces': [Mixed(Parameter(int, "Interface identifier"),
tags = { }
def validate_hostname(self, hostname):
+ hostname = hostname.lower()
if not valid_hostname(hostname):
raise PLCInvalidArgument, "Invalid hostname"
validate_last_pcu_reboot = Row.validate_timestamp
validate_last_pcu_confirmation = Row.validate_timestamp
+ def validate_dns(self, dns):
+ addrs = dns.split(",")
+ addrs = [x.strip() for x in addrs]
+ for addr in addrs:
+ SimpleAddress(addr)
+
+ return dns
+
+ validate_ntp = validate_dns
+
+ def update_readonly_int(self, col_name, commit = True):
+
+ assert 'node_id' in self
+ assert self.table_name
+
+ self.api.db.do("UPDATE %s SET %s = %s" % (self.table_name, col_name, self[col_name]) + \
+ " where node_id = %d" % (self['node_id']) )
+ self.sync(commit)
+
def update_timestamp(self, col_name, commit = True):
"""
Update col_name field with current time
self['deleted'] = True
self.sync(commit)
-
class Nodes(Table):
"""
Representation of row(s) from the nodes table in the
node_filter = Filter(allowed_fields, node_filter)
sql += " AND (%s) %s" % node_filter.sql(api, "AND")
elif isinstance (node_filter, StringTypes):
- node_filter = Filter(Node.fields, {'hostname':[node_filter]})
+ node_filter = Filter(Node.fields, {'hostname':node_filter})
sql += " AND (%s) %s" % node_filter.sql(api, "AND")
- elif isinstance (node_filter, int):
- node_filter = Filter(Node.fields, {'node_id':[node_filter]})
+ elif isinstance (node_filter, (int, long)):
+ node_filter = Filter(Node.fields, {'node_id':node_filter})
sql += " AND (%s) %s" % node_filter.sql(api, "AND")
else:
raise PLCInvalidArgument, "Wrong node filter %r"%node_filter