# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2005 The Trustees of Princeton University
#
-# $Id: Makefile,v 1.10 2006/12/15 16:20:20 mlhuang Exp $
+# $Id: Makefile,v 1.12 2007/07/02 19:28:52 tmack Exp $
#
# Metafiles
--install-scripts=$(DESTDIR)/$(datadir)/plc_api \
--install-data=$(DESTDIR)/$(datadir)/plc_api
install -D -m 755 php/xmlrpc/xmlrpc.so $(DESTDIR)/$(shell php-config --extension-dir)/xmlrpc.so
+ install -D -m 755 refresh-peer.py $(DESTDIR)/$(bindir)/refresh-peer.py
$(subdirs): $(init) $(modules)
# Mark Huang <mlhuang@cs.princeton.edu>
#
# Copyright (C) 2004-2006 The Trustees of Princeton University
-# $Id$
+# $Id: ModPython.py,v 1.5 2007/02/12 18:42:49 mlhuang Exp $
#
import sys
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id$
+# $Id: Auth.py,v 1.18 2007/03/08 22:22:21 tmack Exp $
#
import crypt
# Tony Mack <tmack@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id$
+# $Id: EventObjects.py,v 1.3 2007/05/16 18:07:02 tmack Exp $
#
from PLC.Faults import *
table_name = 'event_object'
primary_key = 'event_id'
fields = {
- 'event_object.event_id': Parameter(int, "Event identifier"),
+ 'event_id': Parameter(int, "Event identifier"),
'person_id': Parameter(int, "Identifier of person responsible for event, if any"),
'node_id': Parameter(int, "Identifier of node responsible for event, if any"),
'fault_code': Parameter(int, "Event fault code"),
def __init__(self, api, event_filter = None, columns = None):
Table.__init__(self, api, EventObject, columns)
+
+ all_fields = EventObject.fields.keys()
+ if not columns:
+ columns = all_fields
+ else:
+ columns = filter(lambda column: column in all_fields, columns)
+
+ # Since we are querying a table (not a view) ensure that timestamps
+ # are converted to ints in the db before being returned
+ timestamps = ['time']
+ for col in columns:
+ if col in timestamps:
+ index = columns.index(col)
+ columns[index] = "CAST(date_part('epoch', events.time) AS bigint) AS time"
+ elif col in [EventObject.primary_key]:
+ index = columns.index(col)
+ columns[index] = EventObject.table_name+"."+EventObject.primary_key
+
sql = "SELECT %s FROM event_object, events WHERE True" % \
- ", ".join(self.columns)
- if event_filter is not None:
+ ", ".join(columns)
+
+ if event_filter is not None:
if isinstance(event_filter, (list, tuple, set)):
event_filter = Filter(EventObject.fields, {'event_id': event_filter})
elif isinstance(event_filter, dict):
event_filter = Filter(EventObject.fields, event_filter)
sql += " AND (%s) " % event_filter.sql(api)
sql += " AND events.event_id = event_object.event_id "
- sql += " ORDER BY %s" % EventObject.primary_key
- self.selectall(sql)
+ sql += " ORDER BY %s" % EventObject.table_name+"."+EventObject.primary_key
+
+ self.selectall(sql)
# Tony Mack <tmack@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id$
+# $Id: Events.py,v 1.13 2007/04/11 20:29:10 tmack Exp $
#
from PLC.Faults import *
from sets import Set
set = Set
+import time
+
from PLC.Faults import *
from PLC.Parameter import Parameter, Mixed, python_type
Special forms:
* a field starting with the ~ character means negation.
example : { '~peer_id' : None }
+ * a field starting with < [ ] or > means lower than or greater than
+ < > uses strict comparison
+ [ ] is for using <= or >= instead
+ example : { '>time' : 1178531418 }
+ example : { ']event_id' : 2305 }
+ * a field starting with [ or ] means older than or more recent than
+ the associated value should be a given unix timestamp
* a (string) value containing either a * or a % character is
treated as a (sql) pattern; * are replaced with % that is the
SQL wildcard character.
# Null filter means no filter
Parameter.__init__(self, self.fields, doc = doc, nullok = True)
+ # this code is not used anymore
+ # at some point the select in the DB for event objects was done on
+ # the events table directly, that is stored as a timestamp, thus comparisons
+ # needed to be done based on SQL timestamps as well
+ def unix2timestamp (self,unix):
+ s = time.gmtime(unix)
+ return "TIMESTAMP'%04d-%02d-%02d %02d:%02d:%02d'" % (s.tm_year,s.tm_mon,s.tm_mday,
+ s.tm_hour,s.tm_min,s.tm_sec)
+
def sql(self, api, join_with = "AND"):
"""
Returns a SQL conditional that represents this filter.
assert join_with in ("AND", "OR")
for field, value in self.iteritems():
- # provide for negation with a field starting with ~
- negation=False
- if field[0] == '~':
- negation = True
- field = field[1:]
+ # handle negation, numeric comparisons
+ # simple, 1-depth only mechanism
+
+ modifiers={'~' : False,
+ '<' : False, '>' : False,
+ '[' : False, ']' : False,
+ }
+
+ for char in modifiers.keys():
+ if field[0] == char:
+ modifiers[char]=True;
+ field = field[1:]
+ break
if field not in self.fields:
+# print 'current fields',self.fields
raise PLCInvalidArgument, "Invalid filter field '%s'" % field
if isinstance(value, (list, tuple, set)):
value = str(api.db.quote(value.replace("*", "%")))
else:
operator = "="
- value = str(api.db.quote(value))
+ if modifiers['<']:
+ operator='<'
+ if modifiers['>']:
+ operator='>'
+ if modifiers['[']:
+ operator='<='
+ if modifiers[']']:
+ operator='>='
+ else:
+ value = str(api.db.quote(value))
clause = "%s %s %s" % (field, operator, value)
- if negation:
- clause = " ( NOT %s ) "%clause
-
+
+ if modifiers['~']:
+ clause = " ( NOT %s ) " % (clause)
+
conditionals.append(clause)
+# print 'sql=',(" %s " % join_with).join(conditionals)
return (" %s " % join_with).join(conditionals)
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id$
+# $Id: Method.py,v 1.27 2007/05/16 18:56:03 tmack Exp $
#
import xmlrpclib
return result
except PLCFault, fault:
- # Prepend method name to expected faults
- fault.faultString = self.name + ": " + fault.faultString
+
+ caller = ""
+ if isinstance(self.caller, Person):
+ caller = 'person_id %s' % self.caller['person_id']
+ elif isinstance(self.caller, Node):
+ caller = 'node_id %s' % self.caller['node_id']
+
+ # Prepend caller and method name to expected faults
+ fault.faultString = caller + ": " + self.name + ": " + fault.faultString
runtime = time.time() - start
self.log(fault.faultCode, runtime, *args)
raise fault
auth_methods = ['session', 'password', 'capability', 'gpg', 'hmac','anonymous']
auth_method = args[0]['AuthMethod']
if auth_method in auth_methods:
- event['auth_method'] = auth_method
+ event['auth_type'] = auth_method
for password in 'AuthString', 'session':
if args[0].has_key(password):
auth = args[0].copy()
from PLC.Parameter import Parameter, Mixed
from PLC.Nodes import Node, Nodes
from PLC.PCUs import PCU, PCUs
+from PLC.Sites import Site, Sites
from PLC.Auth import Auth
class AddNodeToPCU(Method):
len(site['slice_ids']),
site['max_slices'])
+ if not site['enabled']:
+ raise PLCInvalidArgument, "Site %s is disabled can cannot create slices" % (site['name'])
+
slice = Slice(self.api, slice_fields)
slice['creator_person_id'] = self.caller['person_id']
slice['site_id'] = site['site_id']
from PLC.Parameter import Parameter, Mixed
from PLC.Nodes import Node, Nodes
from PLC.PCUs import PCU, PCUs
+from PLC.Sites import Site, Sites
from PLC.Auth import Auth
class DeleteNodeFromPCU(Method):
raise PLCInvalidArgument, "No such slice"
slice = slices[0]
- if slice['peer_id'] is not None:
- raise PLCInvalidArgument, "Not a local slice"
-
assert slice_attribute['slice_attribute_id'] in slice['slice_attribute_ids']
if 'admin' not in self.caller['roles']:
# Remove admin only fields
if not isinstance(self.caller, Person) or \
'admin' not in self.caller['roles']:
+ slice_ids = set()
+ if self.caller:
+ slice_ids.update(self.caller['slice_ids'])
for node in nodes:
+ # if node has whitelist, make sure the user has a slice on the whitelist
+ if 'slice_ids_whitelist' in node and \
+ node['slice_ids_whitelist'] and \
+ not slice_ids.intersection(node['slice_ids_whitelist']):
+ nodes.remove(node)
+ continue
for field in ['boot_nonce', 'key', 'session', 'root_person_ids']:
if field in node:
del node[field]
# Per-node sliver attributes take precedence over global
# slice attributes, so set them first.
+ # Then comes nodegroup slice attributes
+ # Followed by global slice attributes
sliver_attributes = []
if node is not None:
attributes.append({'name': sliver_attribute['name'],
'value': sliver_attribute['value']})
- # set nodegroup slice attributes
- for slice_attribute in filter(lambda a: a['nodegroup_id'] in node['nodegroup_ids'], slice_attributes):
- # Do not set any nodegroup slice attributes for
- # which there is at least one sliver attribute
- # already set.
- if slice_attribute['name'] not in slice_attributes:
- attributes.append({'name': slice_attribute['name'],
+ # set nodegroup slice attributes
+ for slice_attribute in filter(lambda a: a['nodegroup_id'] in node['nodegroup_ids'], slice_attributes):
+ # Do not set any nodegroup slice attributes for
+ # which there is at least one sliver attribute
+ # already set.
+ if slice_attribute['name'] not in slice_attributes:
+ attributes.append({'name': slice_attribute['name'],
'value': slice_attribute['value']})
for slice_attribute in filter(lambda a: a['node_id'] is None, slice_attributes):
# Get system slices
system_slice_attributes = SliceAttributes(self.api, {'name': 'system', 'value': '1'}).dict('slice_id')
system_slice_ids = system_slice_attributes.keys()
+
+ # Get nm-controller slices
+ controller_and_delegated_slices = Slices(self.api, {'instantiation': ['nm-controller', 'delegated']}, ['slice_id']).dict('slice_id')
+ controller_and_delegated_slice_ids = controller_and_delegated_slices.keys()
+ slice_ids = system_slice_ids + controller_and_delegated_slice_ids + node['slice_ids']
- slivers = get_slivers(self.api, system_slice_ids + node['slice_ids'], node)
+ slivers = get_slivers(self.api, slice_ids, node)
node.update_last_contact()
#
# Thierry Parmentelat - INRIA
#
-# $Id$
+# $Id: RefreshPeer.py,v 1.24 2007/06/14 16:26:23 tmack Exp $
import time
# Keyed on foreign person_id
old_peer_persons = Persons(self.api, {'peer_id': peer_id}, columns).dict('peer_person_id')
+
+ # artificially attach the persons returned by GetPeerData to the new peer
+ # this is because validate_email needs peer_id to be correct when checking for duplicates
+ for person in peer_tables['Persons']:
+ person['peer_id']=peer_id
persons_at_peer = dict([(peer_person['person_id'], peer_person) \
for peer_person in peer_tables['Persons']])
-methods = 'AddAddressType AddAddressTypeToAddress AddBootState AddConfFile AddConfFileToNodeGroup AddConfFileToNode AddInitScript AddKeyType AddMessage AddNetworkMethod AddNetworkType AddNodeGroup AddNodeNetwork AddNode AddNodeToNodeGroup AddNodeToPCU AddPCU AddPeer AddPersonKey AddPerson AddPersonToSite AddPersonToSlice AddRole AddRoleToPerson AddSiteAddress AddSite AddSliceAttribute AddSliceAttributeType AddSliceInstantiation AddSlice AddSliceToNodes AdmAddAddressType AdmAddNodeGroup AdmAddNodeNetwork AdmAddNode AdmAddNodeToNodeGroup AdmAddPersonKey AdmAddPerson AdmAddPersonToSite AdmAddSitePowerControlUnit AdmAddSite AdmAssociateNodeToPowerControlUnitPort AdmAuthCheck AdmDeleteAddressType AdmDeleteAllPersonKeys AdmDeleteNodeGroup AdmDeleteNodeNetwork AdmDeleteNode AdmDeletePersonKeys AdmDeletePerson AdmDeleteSitePowerControlUnit AdmDeleteSite AdmDisassociatePowerControlUnitPort AdmGenerateNodeConfFile AdmGetAllAddressTypes AdmGetAllKeyTypes AdmGetAllNodeNetworks AdmGetAllRoles AdmGetNodeGroupNodes AdmGetNodeGroups AdmGetNodes AdmGetPersonKeys AdmGetPersonRoles AdmGetPersonSites AdmGetPersons AdmGetPowerControlUnitNodes AdmGetPowerControlUnits AdmGetSiteNodes AdmGetSitePersons AdmGetSitePIs AdmGetSitePowerControlUnits AdmGetSites AdmGetSiteTechContacts AdmGrantRoleToPerson AdmIsPersonInRole AdmQueryConfFile AdmQueryNode AdmQueryPerson AdmQueryPowerControlUnit AdmQuerySite AdmRebootNode AdmRemoveNodeFromNodeGroup AdmRemovePersonFromSite AdmRevokeRoleFromPerson AdmSetPersonEnabled AdmSetPersonPrimarySite AdmUpdateNodeGroup AdmUpdateNodeNetwork AdmUpdateNode AdmUpdatePerson AdmUpdateSitePowerControlUnit AdmUpdateSite AnonAdmGetNodeGroups AuthCheck BlacklistKey BootCheckAuthentication BootGetNodeDetails BootNotifyOwners BootUpdateNode DeleteAddress DeleteAddressTypeFromAddress DeleteAddressType DeleteBootState DeleteConfFileFromNodeGroup DeleteConfFileFromNode DeleteConfFile DeleteInitScript DeleteKey DeleteKeyType DeleteMessage DeleteNetworkMethod DeleteNetworkType DeleteNodeFromNodeGroup DeleteNodeFromPCU DeleteNodeGroup DeleteNodeNetwork DeleteNode DeletePCU DeletePeer DeletePersonFromSite DeletePersonFromSlice DeletePerson DeleteRoleFromPerson DeleteRole DeleteSession DeleteSite DeleteSliceAttribute DeleteSliceAttributeType DeleteSliceFromNodes DeleteSliceInstantiation DeleteSlice GetAddresses GetAddressTypes GetBootStates GetConfFiles GetEventObjects GetEvents GetInitScripts GetKeys GetKeyTypes GetMessages GetNetworkMethods GetNetworkTypes GetNodeGroups GetNodeNetworks GetNodes GetPCUs GetPeerData GetPeerName GetPeers GetPersons GetRoles GetSession GetSites GetSliceAttributes GetSliceAttributeTypes GetSliceInstantiations GetSlicesMD5 GetSlices GetSliceTicket GetSlivers NotifyPersons RebootNode RefreshPeer ResetPassword SetPersonPrimarySite SliceCreate SliceDelete SliceExtendedInfo SliceGetTicket SliceInfo SliceListNames SliceListUserSlices SliceNodesAdd SliceNodesDel SliceNodesList SliceRenew SliceTicketGet SliceUpdate SliceUserAdd SliceUserDel SliceUsersList UpdateAddress UpdateAddressType UpdateConfFile UpdateInitScript UpdateKey UpdateMessage UpdateNodeGroup UpdateNodeNetwork UpdateNode UpdatePCU UpdatePeer UpdatePerson UpdateSite UpdateSliceAttribute UpdateSliceAttributeType UpdateSlice VerifyPerson system.listMethods system.methodHelp system.methodSignature system.multicall'.split()
+methods = 'AddAddressType AddAddressTypeToAddress AddBootState AddConfFile AddConfFileToNodeGroup AddConfFileToNode AddInitScript AddKeyType AddMessage AddNetworkMethod AddNetworkType AddNodeGroup AddNodeNetwork AddNode AddNodeToNodeGroup AddNodeToPCU AddPCU AddPeer AddPersonKey AddPerson AddPersonToSite AddPersonToSlice AddRole AddRoleToPerson AddSession AddSiteAddress AddSite AddSliceAttribute AddSliceAttributeType AddSliceInstantiation AddSlice AddSliceToNodes AddSliceToNodesWhitelist AdmAddAddressType AdmAddNodeGroup AdmAddNodeNetwork AdmAddNode AdmAddNodeToNodeGroup AdmAddPersonKey AdmAddPerson AdmAddPersonToSite AdmAddSitePowerControlUnit AdmAddSite AdmAssociateNodeToPowerControlUnitPort AdmAuthCheck AdmDeleteAddressType AdmDeleteAllPersonKeys AdmDeleteNodeGroup AdmDeleteNodeNetwork AdmDeleteNode AdmDeletePersonKeys AdmDeletePerson AdmDeleteSitePowerControlUnit AdmDeleteSite AdmDisassociatePowerControlUnitPort AdmGenerateNodeConfFile AdmGetAllAddressTypes AdmGetAllKeyTypes AdmGetAllNodeNetworks AdmGetAllRoles AdmGetNodeGroupNodes AdmGetNodeGroups AdmGetNodes AdmGetPersonKeys AdmGetPersonRoles AdmGetPersonSites AdmGetPersons AdmGetPowerControlUnitNodes AdmGetPowerControlUnits AdmGetSiteNodes AdmGetSitePersons AdmGetSitePIs AdmGetSitePowerControlUnits AdmGetSites AdmGetSiteTechContacts AdmGrantRoleToPerson AdmIsPersonInRole AdmQueryConfFile AdmQueryNode AdmQueryPerson AdmQueryPowerControlUnit AdmQuerySite AdmRebootNode AdmRemoveNodeFromNodeGroup AdmRemovePersonFromSite AdmRevokeRoleFromPerson AdmSetPersonEnabled AdmSetPersonPrimarySite AdmUpdateNodeGroup AdmUpdateNodeNetwork AdmUpdateNode AdmUpdatePerson AdmUpdateSitePowerControlUnit AdmUpdateSite AnonAdmGetNodeGroups AuthCheck BlacklistKey BootCheckAuthentication BootGetNodeDetails BootNotifyOwners BootUpdateNode DeleteAddress DeleteAddressTypeFromAddress DeleteAddressType DeleteBootState DeleteConfFileFromNodeGroup DeleteConfFileFromNode DeleteConfFile DeleteInitScript DeleteKey DeleteKeyType DeleteMessage DeleteNetworkMethod DeleteNetworkType DeleteNodeFromNodeGroup DeleteNodeFromPCU DeleteNodeGroup DeleteNodeNetwork DeleteNode DeletePCU DeletePeer DeletePersonFromSite DeletePersonFromSlice DeletePerson DeleteRoleFromPerson DeleteRole DeleteSession DeleteSite DeleteSliceAttribute DeleteSliceAttributeType DeleteSliceFromNodes DeleteSliceFromNodesWhitelist DeleteSliceInstantiation DeleteSlice GenerateNodeConfFile GetAddresses GetAddressTypes GetBootStates GetConfFiles GetEventObjects GetEvents GetInitScripts GetKeys GetKeyTypes GetMessages GetNetworkMethods GetNetworkTypes GetNodeGroups GetNodeNetworks GetNodes GetPCUs GetPeerData GetPeerName GetPeers GetPersons GetRoles GetSession GetSessions GetSites GetSliceAttributes GetSliceAttributeTypes GetSliceInstantiations GetSlicesMD5 GetSlices GetSliceTicket GetSlivers NotifyPersons RebootNode RefreshPeer ResetPassword SetPersonPrimarySite SliceCreate SliceDelete SliceExtendedInfo SliceGetTicket SliceInfo SliceListNames SliceListUserSlices SliceNodesAdd SliceNodesDel SliceNodesList SliceRenew SliceTicketGet SliceUpdate SliceUserAdd SliceUserDel SliceUsersList UpdateAddress UpdateAddressType UpdateConfFile UpdateInitScript UpdateKey UpdateMessage UpdateNodeGroup UpdateNodeNetwork UpdateNode UpdatePCU UpdatePeer UpdatePerson UpdateSite UpdateSliceAttribute UpdateSliceAttributeType UpdateSlice VerifyPerson system.listMethods system.methodHelp system.methodSignature system.multicall'.split()
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id: NodeNetworks.py,v 1.15 2006/11/09 19:43:55 mlhuang Exp $
+# $Id: NodeNetworks.py,v 1.17 2007/05/11 20:22:55 tmack Exp $
#
from types import StringTypes
validate_dns1 = validate_ip
validate_dns2 = validate_ip
+ def validate_bwlimit(self, bwlimit):
+ if not bwlimit:
+ return bwlimit
+
+ if bwlimit < 500000:
+ raise PLCInvalidArgument, 'Minimum bw is 500 kbs'
+
+ return bwlimit
+
def validate_hostname(self, hostname):
# Optional
if not hostname:
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id$
+# $Id: Nodes.py,v 1.34 2007/07/12 17:55:02 tmack Exp $
#
from types import StringTypes
from PLC.Table import Row, Table
from PLC.NodeNetworks import NodeNetwork, NodeNetworks
from PLC.BootStates import BootStates
+#from PLC.Slices import Slice, Slices
def valid_hostname(hostname):
# 1. Each part begins and ends with a letter or number.
table_name = 'nodes'
primary_key = 'node_id'
- join_tables = ['nodegroup_node', 'conf_file_node', 'nodenetworks', 'pcu_node', 'slice_node', 'slice_attribute', 'node_session', 'peer_node']
+ join_tables = ['nodegroup_node', 'conf_file_node', 'nodenetworks', 'pcu_node', 'slice_node', 'slice_attribute', 'node_session', 'peer_node', 'node_slice_whitelist']
fields = {
'node_id': Parameter(int, "Node identifier"),
'hostname': Parameter(str, "Fully qualified hostname", max = 255),
'conf_file_ids': Parameter([int], "List of configuration files specific to this node"),
# 'root_person_ids': Parameter([int], "(Admin only) List of people who have root access to this node"),
'slice_ids': Parameter([int], "List of slices on this node"),
+ 'slice_ids_whitelist': Parameter([int], "List of slices allowed on this node"),
'pcu_ids': Parameter([int], "List of PCUs that control this node"),
'ports': Parameter([int], "List of PCU ports that this node is connected to"),
'peer_id': Parameter(int, "Peer to which this node belongs", nullok = True),
validate_date_created = Row.validate_timestamp
validate_last_updated = Row.validate_timestamp
+ validate_last_contact = Row.validate_timestamp
def update_last_contact(self, commit = True):
"""
self.api.db.do("UPDATE %s SET last_contact = CURRENT_TIMESTAMP " % (self.table_name) + \
" where node_id = %d" % ( self['node_id']) )
self.sync(commit)
-
+
def delete(self, commit = True):
"""
Delete existing node.
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id$
+# $Id: Persons.py,v 1.37 2007/06/14 16:26:01 tmack Exp $
#
from types import StringTypes
if len(domain) < 2:
raise invalid_email
- conflicts = Persons(self.api, [email])
- for person in conflicts:
+ # check only against users on the same peer
+ if 'peer_id' in self:
+ namespace_peer_id = self['peer_id']
+ else:
+ namespace_peer_id = None
+
+ conflicts = Persons(self.api, {'email':email,'peer_id':namespace_peer_id})
+
+ for person in conflicts:
if 'person_id' not in self or self['person_id'] != person['person_id']:
raise PLCInvalidArgument, "E-mail address already in use"
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id$
+# $Id: PostgreSQL.py,v 1.15 2007/02/12 18:41:27 mlhuang Exp $
#
import psycopg2
+from types import StringTypes
import random
import base64
import time
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.Persons import Person, Persons
from PLC.Nodes import Node, Nodes
Representation of row(s) from the session table in the database.
"""
- def __init__(self, api, session_ids = None, expires = int(time.time())):
+ def __init__(self, api, session_filter = None, expires = int(time.time())):
Table.__init__(self, api, Session)
sql = "SELECT %s FROM view_sessions WHERE True" % \
", ".join(Session.fields)
- if session_ids:
- sql += " AND session_id IN (%s)" % ", ".join(map(api.db.quote, session_ids))
+ if session_filter is not None:
+ if isinstance(session_filter, (list, tuple, set)):
+ # Separate the list into integers and strings
+ ints = filter(lambda x: isinstance(x, (int, long)), session_filter)
+ strs = filter(lambda x: isinstance(x, StringTypes), session_filter)
+ session_filter = Filter(Session.fields, {'person_id': ints, 'session_id': strs})
+ sql += " AND (%s)" % session_filter.sql(api, "OR")
+ elif isinstance(session_filter, dict):
+ session_filter = Filter(Session.fields, session_filter)
+ sql += " AND (%s)" % session_filter.sql(api, "AND")
if expires is not None:
if expires >= 0:
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2005 The Trustees of Princeton University
#
-# $Id$
+# $Id: Shell.py,v 1.5 2007/02/08 21:49:24 mlhuang Exp $
#
import os
from PLC.Debug import profile
from PLC.Table import Row, Table
from PLC.SliceInstantiations import SliceInstantiation, SliceInstantiations
-from PLC.Nodes import Node, Nodes
+from PLC.Nodes import Node
from PLC.Persons import Person, Persons
class Slice(Row):
table_name = 'slices'
primary_key = 'slice_id'
- join_tables = ['slice_node', 'slice_person', 'slice_attribute', 'peer_slice']
+ join_tables = ['slice_node', 'slice_person', 'slice_attribute', 'peer_slice', 'node_slice_whitelist']
fields = {
'slice_id': Parameter(int, "Slice identifier"),
'site_id': Parameter(int, "Identifier of the site to which this slice belongs"),
add_node = Row.add_object(Node, 'slice_node')
remove_node = Row.remove_object(Node, 'slice_node')
+ add_to_node_whitelist = Row.add_object(Node, 'node_slice_whitelist')
+ delete_from_node_whitelist = Row.remove_object(Node, 'node_slice_whitelist')
+
def sync(self, commit = True):
"""
Add or update a slice.
%{_bindir}/plcsh
%{php_extension_dir}/xmlrpc.so
%{_sysconfdir}/php.d/xmlrpc.ini
+%{_bindir}/refresh-peer.py
%changelog
* Fri Oct 27 2006 Mark Huang <mlhuang@CS.Princeton.EDU> -
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2006 The Trustees of Princeton University
#
-# $Id$
+# $Id: DocBook.py,v 1.4 2007/02/19 18:02:39 mlhuang Exp $
#
import xml.dom.minidom
--
-- Copyright (C) 2006 The Trustees of Princeton University
--
--- $Id$
+-- $Id: planetlab4.sql,v 1.79 2007/07/12 17:48:19 tmack Exp $
--
SET client_encoding = 'UNICODE';
FROM nodes
GROUP BY site_id;
+-- slice whitelist on nodes
+CREATE TABLE node_slice_whitelist (
+ node_id integer REFERENCES nodes NOT NULL, -- Node id of whitelist
+ slice_id integer REFERENCES slices NOT NULL, -- Slice id thats allowd on this node
+ PRIMARY KEY (node_id, slice_id)
+) WITH OIDS;
+CREATE INDEX node_slice_whitelist_node_id_idx ON node_slice_whitelist (node_id);
+CREATE INDEX node_slice_whitelist_slice_id_idx ON node_slice_whitelist (slice_id);
+
+-- Slices on each node
+CREATE VIEW node_slices_whitelist AS
+SELECT node_id,
+array_accum(slice_id) AS slice_ids_whitelist
+FROM node_slice_whitelist
+GROUP BY node_id;
+
--------------------------------------------------------------------------------
-- Node groups
--------------------------------------------------------------------------------
INSERT INTO slice_instantiations (instantiation) VALUES ('not-instantiated'); -- Placeholder slice
INSERT INTO slice_instantiations (instantiation) VALUES ('plc-instantiated'); -- Instantiated by Node Manager
INSERT INTO slice_instantiations (instantiation) VALUES ('delegated'); -- Manually instantiated
+INSERT INTO slice_instantiations (instantiation) VALUES ('nm-controller'); -- NM Controller
-- Slices
CREATE TABLE slices (
COALESCE((SELECT nodenetwork_ids FROM node_nodenetworks WHERE node_nodenetworks.node_id = nodes.node_id), '{}') AS nodenetwork_ids,
COALESCE((SELECT nodegroup_ids FROM node_nodegroups WHERE node_nodegroups.node_id = nodes.node_id), '{}') AS nodegroup_ids,
COALESCE((SELECT slice_ids FROM node_slices WHERE node_slices.node_id = nodes.node_id), '{}') AS slice_ids,
+COALESCE((SELECT slice_ids_whitelist FROM node_slices_whitelist WHERE node_slices_whitelist.node_id = nodes.node_id), '{}') AS slice_ids_whitelist,
COALESCE((SELECT pcu_ids FROM node_pcus WHERE node_pcus.node_id = nodes.node_id), '{}') AS pcu_ids,
COALESCE((SELECT ports FROM node_pcus WHERE node_pcus.node_id = nodes.node_id), '{}') AS ports,
COALESCE((SELECT conf_file_ids FROM node_conf_files WHERE node_conf_files.node_id = nodes.node_id), '{}') AS conf_file_ids,
# Mark Huang <mlhuang@cs.princeton.edu>
# Copyright (C) 2005 The Trustees of Princeton University
#
-# $Id$
+# $Id: plcsh,v 1.6 2007/02/08 21:49:41 mlhuang Exp $
#
import os
#!/usr/bin/env plcsh
-# $Id: refresh-peer.py 154 2007-03-28 14:15:55Z thierry $
+# $Id: refresh-peer.py,v 1.1 2007/07/02 19:27:43 tmack Exp $
import sys,os,time