from PLC.Faults import *
from PLC.Parameter import Parameter
from PLC.Filter import Filter
-from PLC.Table import Row, Table
+from PLC.Storage.AlchemyObject import AlchemyObj
from PLC.TagTypes import TagType, TagTypes
from PLC.Interfaces import Interface
-class InterfaceTag(Row):
+class InterfaceTag(AlchemyObj):
"""
Representation of a row in the interface_tag.
To use, instantiate with a dict of values.
"""
- table_name = 'interface_tag'
- primary_key = 'interface_tag_id'
+ table_name = 'interface_tags'
fields = {
- 'interface_tag_id': Parameter(int, "Interface setting identifier"),
+ 'interface_tag_id': Parameter(int, "Interface setting identifier", primary_key=True),
'interface_id': Interface.fields['interface_id'],
'ip': Interface.fields['ip'],
'tag_type_id': TagType.fields['tag_type_id'],
}
-class InterfaceTags(Table):
+ def sync(self, commit = True, validate=True):
+ AlchemyObj.sync(self, commit, validate)
+ if 'interface_tag_id' not in self:
+ # Before a new slice is added, delete expired slices
+ #expired = Slices(self.api, expires = -int(time.time()))
+ #for slice in expired:
+ # slice.delete(commit)
+ AlchemyObj.insert(self, dict(self))
+ else:
+ AlchemyObj.update(self, {'interface_tag_id': self['interface_tag_id']}, dict(self))
+
+ def delete(self, commit=True):
+ assert 'interface_tag_id' in self
+ AlchemyObj.delete(self, dict(self))
+
+
+class InterfaceTags(list):
"""
Representation of row(s) from the interface_tag table in the
database.
"""
def __init__(self, api, interface_tag_filter = None, columns = None):
- Table.__init__(self, api, InterfaceTag, columns)
-
- sql = "SELECT %s FROM view_interface_tags WHERE True" % \
- ", ".join(self.columns)
-
- if interface_tag_filter is not None:
- if isinstance(interface_tag_filter, (list, tuple, set, int, long)):
- interface_tag_filter = Filter(InterfaceTag.fields, {'interface_tag_id': interface_tag_filter})
- elif isinstance(interface_tag_filter, dict):
- interface_tag_filter = Filter(InterfaceTag.fields, interface_tag_filter)
- else:
- raise PLCInvalidArgument, "Wrong interface setting filter %r"%interface_tag_filter
- sql += " AND (%s) %s" % interface_tag_filter.sql(api)
-
+ if not interface_tag_filter:
+ interface_tags = InterfaceTag().select()
+ if isinstance(interface_tag_filter, (list, tuple, set, int, long)):
+ interface_tags = InterfaceTag().select(filter={'interface_tag_id': interface_tag_filter})
+ elif isinstance(interface_tag_filter, dict):
+ interface_tags = InterfaceTag().select(filter=interface_tag_filter})
+ else:
+ raise PLCInvalidArgument, "Wrong interface setting filter %r"%interface_tag_filter
- self.selectall(sql)
+ for interface_tag in interface_tags:
+ self.append(interface_tag)
from PLC.Faults import *
from PLC.Parameter import Parameter
-from PLC.Filter import Filter
from PLC.Debug import profile
-from PLC.Table import Row, Table
+from PLC.Storage.AlchemyObject import AlchemyObj
from PLC.NetworkTypes import NetworkType, NetworkTypes
from PLC.NetworkMethods import NetworkMethod, NetworkMethods
import PLC.Nodes
return in_same_network_ipv4(address1, address2, netmask) or \
in_same_network_ipv6(address1, address2, netmask)
-class Interface(Row):
+class Interface(AlchemyObj):
"""
Representation of a row in the interfaces table. To use, optionally
instantiate with a dict of values. Update as you would a
dict. Commit to the database with sync().
"""
- table_name = 'interfaces'
- primary_key = 'interface_id'
+ tablename = 'interfaces'
join_tables = ['interface_tag']
fields = {
- 'interface_id': Parameter(int, "Node interface identifier"),
+ 'interface_id': Parameter(int, "Node interface identifier", primary_key=True),
'method': Parameter(str, "Addressing method (e.g., 'static' or 'dhcp')"),
'type': Parameter(str, "Address type (e.g., 'ipv4')"),
'ip': Parameter(str, "IP address", nullok = True),
'hostname': Parameter(str, "(Optional) Hostname", nullok = True),
'node_id': Parameter(int, "Node associated with this interface"),
'is_primary': Parameter(bool, "Is the primary interface for this node"),
- 'interface_tag_ids' : Parameter([int], "List of interface settings"),
+ 'interface_tag_ids' : Parameter([int], "List of interface settings", joined=True),
'last_updated': Parameter(int, "Date and time when node entry was created", ro = True),
}
- view_tags_name = "view_interface_tags"
tags = {}
def validate_method(self, method):
"""
# Basic validation
- Row.validate(self)
+ AlchemyObj.validate(self)
assert 'method' in self
method = self['method']
Update col_name field with current time
"""
- assert 'interface_id' in self
- assert self.table_name
-
- self.api.db.do("UPDATE %s SET %s = CURRENT_TIMESTAMP " % (self.table_name, col_name) + \
- " where interface_id = %d" % (self['interface_id']) )
- self.sync(commit)
+ pass
def update_last_updated(self, commit = True):
self.update_timestamp('last_updated', commit)
+ def sync(self, commit=True, validate=True):
+ AlchemyObj.sync(self, commit, validate)
+ if 'interface_id' not in self:
+ AlchemyObj.insert(self, dict(self))
+ else:
+ AlchemyObj.update(self, {'interface_id': self['interface_id']}, dict(self))
+
def delete(self,commit=True):
### need to cleanup ilinks
- self.api.db.do("DELETE FROM ilink WHERE src_interface_id=%d OR dst_interface_id=%d" % \
- (self['interface_id'],self['interface_id']))
-
- Row.delete(self)
+ AlchemyObj.delete(self, dict(self)
-class Interfaces(Table):
+
+class Interfaces(list):
"""
Representation of row(s) from the interfaces table in the
database.
"""
def __init__(self, api, interface_filter = None, columns = None):
- Table.__init__(self, api, Interface, columns)
-
# the view that we're selecting upon: start with view_nodes
- view = "view_interfaces"
- # as many left joins as requested tags
- for tagname in self.tag_columns:
- view= "%s left join %s using (%s)"%(view,Interface.tagvalue_view_name(tagname),
- Interface.primary_key)
-
- sql = "SELECT %s FROM %s WHERE True" % \
- (", ".join(self.columns.keys()+self.tag_columns.keys()),view)
-
- if interface_filter is not None:
- if isinstance(interface_filter, (list, tuple, set)):
- # Separate the list into integers and strings
- ints = filter(lambda x: isinstance(x, (int, long)), interface_filter)
- strs = filter(lambda x: isinstance(x, StringTypes), interface_filter)
- interface_filter = Filter(Interface.fields, {'interface_id': ints, 'ip': strs})
- sql += " AND (%s) %s" % interface_filter.sql(api, "OR")
- elif isinstance(interface_filter, dict):
- allowed_fields=dict(Interface.fields.items()+Interface.tags.items())
- interface_filter = Filter(allowed_fields, interface_filter)
- sql += " AND (%s) %s" % interface_filter.sql(api)
- elif isinstance(interface_filter, int):
- interface_filter = Filter(Interface.fields, {'interface_id': [interface_filter]})
- sql += " AND (%s) %s" % interface_filter.sql(api)
- elif isinstance (interface_filter, StringTypes):
- interface_filter = Filter(Interface.fields, {'ip':[interface_filter]})
- sql += " AND (%s) %s" % interface_filter.sql(api, "AND")
- else:
- raise PLCInvalidArgument, "Wrong interface filter %r"%interface_filter
-
- self.selectall(sql)
+ if not interface_filter:
+ interfaces = Interface().select()
+ elif isinstance(interface_filter, (list, tuple, set)):
+ # Separate the list into integers and strings
+ ints = filter(lambda x: isinstance(x, (int, long)), interface_filter)
+ strs = filter(lambda x: isinstance(x, StringTypes), interface_filter)
+ interfaces = Interface().select(filter={'interface_id': ints, 'ip': strs})
+ elif isinstance(interface_filter, dict):
+ interfaces = Interface().select(filter=interface_filter})
+ elif isinstance(interface_filter, int):
+ interfaces = Interface().select(filter={'interface_id': interface_filter})
+ elif isinstance (interface_filter, StringTypes):
+ interfaces = Interface().select(filter={'ip': interface_filter})
+ else:
+ raise PLCInvalidArgument, "Wrong interface filter %r"%interface_filter
+
+ for interface in interfaces:
+ self.append(interface)
from PLC.Parameter import Parameter
from PLC.Table import Row, Table
from PLC.Filter import Filter
+from PLC.Storage.AlchemyObject import AlchemyObj
-class Message(Row):
+class Message(AlchemyObj):
"""
Representation of a row in the messages table.
"""
- table_name = 'messages'
- primary_key = 'message_id'
+ tablename = 'messages'
fields = {
- 'message_id': Parameter(str, "Message identifier"),
+ 'message_id': Parameter(str, "Message identifier", primary_key=True),
'subject': Parameter(str, "Message summary", nullok = True),
'template': Parameter(str, "Message template", nullok = True),
'enabled': Parameter(bool, "Message is enabled"),
}
-class Messages(Table):
+ def sync(self, commit=True, validate=True):
+ AlchemyObj.sync(self, commit, validate)
+ if 'message_id' not in self:
+ # Before a new slice is added, delete expired slices
+ #expired = Slices(self.api, expires = -int(time.time()))
+ #for slice in expired:
+ # slice.delete(commit)
+ AlchemyObj.insert(self, dict(self))
+ else:
+ AlchemyObj.update(self, {'message_id': self['message_id']}, dict(self))
+
+ def delete(self, commit = True):
+ AlchemyObj.delete(self, dict(self))
+
+class Messages(list):
"""
Representation of row(s) from the messages table in the database.
"""
def __init__(self, api, message_filter = None, columns = None, enabled = None):
- Table.__init__(self, api, Message, columns)
-
- sql = "SELECT %s from messages WHERE True" % \
- ", ".join(self.columns)
-
- if enabled is not None:
- sql += " AND enabled IS %s" % enabled
-
- if message_filter is not None:
- if isinstance(message_filter, (list, tuple, set, int, long)):
- message_filter = Filter(Message.fields, {'message_id': message_filter})
- sql += " AND (%s) %s" % message_filter.sql(api, "OR")
- elif isinstance(message_filter, dict):
- message_filter = Filter(Message.fields, message_filter)
- sql += " AND (%s) %s" % message_filter.sql(api, "AND")
- else:
- raise PLCInvalidArgument, "Wrong message filter %r"%message_filter
-
- self.selectall(sql)
+ if not message_filter:
+ messages = Message().select()
+ if isinstance(message_filter, (list, tuple, set, int, long)):
+ messages = Message().select(filter={'message_id': message_filter})
+ elif isinstance(message_filter, dict):
+ messages = Message().select(filter=message_filter)
+ else:
+ raise PLCInvalidArgument, "Wrong message filter %r"%message_filter
+
+ for message in messages:
+ self.append(message)
#
# Functions for interacting with the network_methods table in the database
#
-# Mark Huang <mlhuang@cs.princeton.edu>
-# Copyright (C) 2006 The Trustees of Princeton University
#
-
+from types import StringTypes
from PLC.Faults import *
from PLC.Parameter import Parameter
-from PLC.Table import Row, Table
+from PLC.Storage.AlchemyObject import AlchemyObj
-class NetworkMethod(Row):
+class NetworkMethod(AlchemyObj):
"""
Representation of a row in the network_methods table. To use,
instantiate with a dict of values.
"""
- table_name = 'network_methods'
- primary_key = 'method'
+ tablename = 'network_methods'
join_tables = ['interfaces']
fields = {
- 'method': Parameter(str, "Network method", max = 20),
+ 'method': Parameter(str, "Network method", max = 20, primary_key=True),
}
def validate_method(self, name):
raise PLCInvalidArgument, "Network method must be specified"
# Make sure network method does not alredy exist
- conflicts = NetworkMethods(self.api, [name])
+ conflicts = NetworkMethods(self.api, name)
if conflicts:
raise PLCInvalidArgument, "Network method name already in use"
return name
-class NetworkMethods(Table):
+ def sync(self, commit = True, validate=True):
+ AlchemyObj.sync(self, commit, validate)
+ AlchemyObj.insert(self, dict(self))
+
+ def delete(self, commit=True):
+ assert method in self
+ AlchemyObj.delete(self, dict(self))
+
+
+class NetworkMethods(list):
"""
Representation of the network_methods table in the database.
"""
def __init__(self, api, methods = None):
- Table.__init__(self, api, NetworkMethod)
-
- sql = "SELECT %s FROM network_methods" % \
- ", ".join(NetworkMethod.fields)
- if methods:
- sql += " WHERE method IN (%s)" % ", ".join( [ api.db.quote (m) for m in methods ] )
+ if not methods:
+ network_methods = NetworkMethod().select()
+ elif isinstance(methods, StringTypes):
+ network_methods = NetworkMethod().select(filter={'method': methods})
+ else:
+ raise PLCInvalidArgument, "Wrong network method filter %r"%methods
- self.selectall(sql)
+ self.extend(network_methods)
+
#
# Functions for interacting with the network_types table in the database
#
-# Mark Huang <mlhuang@cs.princeton.edu>
-# Copyright (C) 2006 The Trustees of Princeton University
#
-
+from types import StringTypes
from PLC.Faults import *
from PLC.Parameter import Parameter
-from PLC.Table import Row, Table
+from PLC.Storage.AlchemyObject import AlchemyObj
-class NetworkType(Row):
+class NetworkType(AlchemyObj):
"""
Representation of a row in the network_types table. To use,
instantiate with a dict of values.
"""
- table_name = 'network_types'
- primary_key = 'type'
- join_tables = ['interfaces']
+ tablename = 'network_types'
fields = {
- 'type': Parameter(str, "Network type", max = 20),
+ 'type': Parameter(str, "Network type", max = 20, primary_key=True),
}
def validate_type(self, name):
raise PLCInvalidArgument, "Network type must be specified"
# Make sure network type does not alredy exist
- conflicts = NetworkTypes(self.api, [name])
+ conflicts = NetworkTypes(self.api, name)
if conflicts:
raise PLCInvalidArgument, "Network type name already in use"
return name
-class NetworkTypes(Table):
+class NetworkTypes(list):
"""
Representation of the network_types table in the database.
"""
def __init__(self, api, types = None):
- Table.__init__(self, api, NetworkType)
-
- sql = "SELECT %s FROM network_types" % \
- ", ".join(NetworkType.fields)
-
- if types:
- sql += " WHERE type IN (%s)" % ", ".join( [ api.db.quote (t) for t in types ] )
-
- self.selectall(sql)
+ if not types:
+ network_types = NetworkType().select()
+ elif isinstance(types, StringTypes):
+ network_types = NetworkType().select({'type': types})
+ else:
+ raise PLCInvalidArgument, "Wrong network type filter %r"%types
+
+ self.extend(network_types)
#
# Functions for interacting with the nodegroups table in the database
#
-# Mark Huang <mlhuang@cs.princeton.edu>
-# Copyright (C) 2006 The Trustees of Princeton University
#
from types import StringTypes
from PLC.Faults import *
from PLC.Parameter import Parameter, Mixed
-from PLC.Filter import Filter
from PLC.Debug import profile
-from PLC.Table import Row, Table
+from PLC.Storage.AlchemyObject import AlchemyObj
from PLC.Nodes import Node, Nodes
class NodeGroup(Row):
dict. Commit to the database with sync().
"""
- table_name = 'nodegroups'
- primary_key = 'nodegroup_id'
+ tablename = 'nodegroups'
join_tables = ['conf_file_nodegroup']
- primary_field = 'nodegroup_id'
fields = {
- 'nodegroup_id': Parameter(int, "Node group identifier"),
+ 'nodegroup_id': Parameter(int, "Node group identifier", primary_key),
'groupname': Parameter(str, "Node group name", max = 50),
'tag_type_id': Parameter (int, "Node tag type id"),
'value' : Parameter(str, "value that the nodegroup definition is based upon"),
'tagname' : Parameter(str, "Tag name that the nodegroup definition is based upon"),
- 'conf_file_ids': Parameter([int], "List of configuration files specific to this node group"),
- 'node_ids' : Parameter([int], "List of node_ids that belong to this nodegroup"),
+ 'conf_file_ids': Parameter([int], "List of configuration files specific to this node group", joined=True),
+ 'node_ids' : Parameter([int], "List of node_ids that belong to this nodegroup", joined=True),
}
related_fields = {
}
raise PLCInvalidArgument, "Invalid node group name"
# Make sure node group does not alredy exist
- conflicts = NodeGroups(self.api, [name])
+ conflicts = NodeGroups(self.api, name)
for nodegroup in conflicts:
if 'nodegroup_id' not in self or self['nodegroup_id'] != nodegroup['nodegroup_id']:
raise PLCInvalidArgument, "Node group name already in use"
return name
- def associate_conf_files(self, auth, field, value):
- """
- Add conf_files found in value list (AddConfFileToNodeGroup)
- Delets conf_files not found in value list (DeleteConfFileFromNodeGroup)
- """
+ def sync(self, commit=True, validate=True):
+ AlchemyObj.sync(self, commit, validate)
+ if 'nodegroup_id' not in self:
+ AlchemyObj.insert(self, dict(self))
+ else:
+ AlchemyObj.update(self, {'nodegroup_id': self['nodegroup_id']}, dict(self))
- assert 'conf_file_ids' in self
- assert 'nodegroup_id' in self
- assert isinstance(value, list)
-
- conf_file_ids = self.separate_types(value)[0]
-
- if self['conf_file_ids'] != conf_file_ids:
- from PLC.Methods.AddConfFileToNodeGroup import AddConfFileToNodeGroup
- from PLC.Methods.DeleteConfFileFromNodeGroup import DeleteConfFileFromNodeGroup
- new_conf_files = set(conf_file_ids).difference(self['conf_file_ids'])
- stale_conf_files = set(self['conf_file_ids']).difference(conf_file_ids)
-
- for new_conf_file in new_conf_files:
- AddConfFileToNodeGroup.__call__(AddConfFileToNodeGroup(self.api),
- auth, new_conf_file, self['nodegroup_id'])
- for stale_conf_file in stale_conf_files:
- DeleteConfFileFromNodeGroup.__call__(DeleteConfFileFromNodeGroup(self.api),
- auth, stale_conf_file, self['nodegroup_id'])
-
-
-class NodeGroups(Table):
+class NodeGroups(list):
"""
Representation of row(s) from the nodegroups table in the
database.
"""
def __init__(self, api, nodegroup_filter = None, columns = None):
- Table.__init__(self, api, NodeGroup, columns)
-
- sql = "SELECT %s FROM view_nodegroups WHERE True" % \
- ", ".join(self.columns)
-
- if nodegroup_filter is not None:
- if isinstance(nodegroup_filter, (list, tuple, set)):
- # Separate the list into integers and strings
- ints = filter(lambda x: isinstance(x, (int, long)), nodegroup_filter)
- strs = filter(lambda x: isinstance(x, StringTypes), nodegroup_filter)
- nodegroup_filter = Filter(NodeGroup.fields, {'nodegroup_id': ints, 'groupname': strs})
- sql += " AND (%s) %s" % nodegroup_filter.sql(api, "OR")
- elif isinstance(nodegroup_filter, dict):
- nodegroup_filter = Filter(NodeGroup.fields, nodegroup_filter)
- sql += " AND (%s) %s" % nodegroup_filter.sql(api, "AND")
- elif isinstance(nodegroup_filter, (int, long)):
- nodegroup_filter = Filter(NodeGroup.fields, {'nodegroup_id': nodegroup_filter})
- sql += " AND (%s) %s" % nodegroup_filter.sql(api, "AND")
- elif isinstance(nodegroup_filter, StringTypes):
- nodegroup_filter = Filter(NodeGroup.fields, {'groupname': nodegroup_filter})
- sql += " AND (%s) %s" % nodegroup_filter.sql(api, "AND")
- else:
- raise PLCInvalidArgument, "Wrong node group filter %r"%nodegroup_filter
- self.selectall(sql)
+ if not nodegroup_filter is not None:
+ nodegroups = NodeGroup().select()
+ if isinstance(nodegroup_filter, (list, tuple, set)):
+ # Separate the list into integers and strings
+ ints = filter(lambda x: isinstance(x, (int, long)), nodegroup_filter)
+ strs = filter(lambda x: isinstance(x, StringTypes), nodegroup_filter)
+ nodegroups = NodeGroup().select(filter={'nodegroup_id': ints, 'groupname': strs})
+ elif isinstance(nodegroup_filter, dict):
+ nodegroups = NodeGroup().select(filter=nodegroup_filter)
+ elif isinstance(nodegroup_filter, (int, long)):
+ nodegroups = NodeGroup().select(filter={'nodegroup_id': nodegroup_filter})
+ elif isinstance(nodegroup_filter, StringTypes):
+ nodegroups = NodeGroup().select(filter={'groupname': nodegroup_filter})
+ else:
+ raise PLCInvalidArgument, "Wrong node group filter %r"%nodegroup_filter
+
+ for nodegroup in nodegroups:
+ self.append(nodegroup)