From d910a6190fec258ddbf0e26d01539839ac3fdc76 Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Thu, 22 May 2008 15:40:21 +0000 Subject: [PATCH] first draft for node tags & new node groups: * assuming the database name & version is reset to planetlab5 (5,) - migrations cleaned * 'nodenetwork' renamed into 'interface' * ongoing work - this is known to be still broken, as some objects and methods still need changes --- Makefile | 12 +- PLC/Auth.py | 18 +- PLC/InterfaceSettingTypes.py | 83 +++++ PLC/InterfaceSettings.py | 57 ++++ PLC/{NodeNetworks.py => Interfaces.py} | 56 ++-- PLC/Methods/.cvsignore | 1 - .../{AddNodeNetwork.py => AddInterface.py} | 38 +-- PLC/Methods/AddInterfaceSetting.py | 89 ++++++ PLC/Methods/AddInterfaceSettingType.py | 45 +++ PLC/Methods/AddNodeNetworkSetting.py | 89 ------ PLC/Methods/AddNodeNetworkSettingType.py | 45 --- PLC/Methods/AddNodeToNodeGroup.py | 55 ---- PLC/Methods/AdmAddAddressType.py | 21 -- PLC/Methods/AdmAddNode.py | 33 -- PLC/Methods/AdmAddNodeGroup.py | 22 -- PLC/Methods/AdmAddNodeNetwork.py | 31 -- PLC/Methods/AdmAddNodeToNodeGroup.py | 8 - PLC/Methods/AdmAddPerson.py | 30 -- PLC/Methods/AdmAddPersonKey.py | 28 -- PLC/Methods/AdmAddPersonToSite.py | 8 - PLC/Methods/AdmAddSite.py | 32 -- PLC/Methods/AdmAddSitePowerControlUnit.py | 8 - .../AdmAssociateNodeToPowerControlUnitPort.py | 29 -- PLC/Methods/AdmAuthCheck.py | 8 - PLC/Methods/AdmDeleteAddressType.py | 8 - PLC/Methods/AdmDeleteAllPersonKeys.py | 55 ---- PLC/Methods/AdmDeleteNode.py | 9 - PLC/Methods/AdmDeleteNodeGroup.py | 8 - PLC/Methods/AdmDeleteNodeNetwork.py | 24 -- PLC/Methods/AdmDeletePerson.py | 8 - PLC/Methods/AdmDeletePersonKeys.py | 56 ---- PLC/Methods/AdmDeleteSite.py | 8 - PLC/Methods/AdmDeleteSitePowerControlUnit.py | 8 - .../AdmDisassociatePowerControlUnitPort.py | 37 --- PLC/Methods/AdmGenerateNodeConfFile.py | 110 ------- PLC/Methods/AdmGetAllAddressTypes.py | 8 - PLC/Methods/AdmGetAllKeyTypes.py | 8 - PLC/Methods/AdmGetAllNodeNetworks.py | 37 --- PLC/Methods/AdmGetAllRoles.py | 32 -- PLC/Methods/AdmGetNodeGroupNodes.py | 36 --- PLC/Methods/AdmGetNodeGroups.py | 8 - PLC/Methods/AdmGetNodes.py | 11 - PLC/Methods/AdmGetPersonKeys.py | 40 --- PLC/Methods/AdmGetPersonRoles.py | 55 ---- PLC/Methods/AdmGetPersonSites.py | 47 --- PLC/Methods/AdmGetPersons.py | 11 - PLC/Methods/AdmGetPowerControlUnitNodes.py | 41 --- PLC/Methods/AdmGetPowerControlUnits.py | 8 - PLC/Methods/AdmGetSiteNodes.py | 44 --- PLC/Methods/AdmGetSitePIs.py | 44 --- PLC/Methods/AdmGetSitePersons.py | 44 --- PLC/Methods/AdmGetSitePowerControlUnits.py | 35 -- PLC/Methods/AdmGetSiteTechContacts.py | 45 --- PLC/Methods/AdmGetSites.py | 11 - PLC/Methods/AdmGrantRoleToPerson.py | 11 - PLC/Methods/AdmIsPersonInRole.py | 67 ---- PLC/Methods/AdmQueryConfFile.py | 35 -- PLC/Methods/AdmQueryNode.py | 67 ---- PLC/Methods/AdmQueryPerson.py | 29 -- PLC/Methods/AdmQueryPowerControlUnit.py | 59 ---- PLC/Methods/AdmQuerySite.py | 87 ----- PLC/Methods/AdmRebootNode.py | 8 - PLC/Methods/AdmRemoveNodeFromNodeGroup.py | 8 - PLC/Methods/AdmRemovePersonFromSite.py | 8 - PLC/Methods/AdmRevokeRoleFromPerson.py | 11 - PLC/Methods/AdmSetPersonEnabled.py | 23 -- PLC/Methods/AdmSetPersonPrimarySite.py | 8 - PLC/Methods/AdmUpdateNode.py | 8 - PLC/Methods/AdmUpdateNodeGroup.py | 27 -- PLC/Methods/AdmUpdateNodeNetwork.py | 8 - PLC/Methods/AdmUpdatePerson.py | 8 - PLC/Methods/AdmUpdateSite.py | 8 - PLC/Methods/AdmUpdateSitePowerControlUnit.py | 8 - PLC/Methods/AnonAdmGetNodeGroups.py | 11 - PLC/Methods/BootGetNodeDetails.py | 8 +- PLC/Methods/BootUpdateNode.py | 24 +- ...eleteNodeNetwork.py => DeleteInterface.py} | 22 +- PLC/Methods/DeleteInterfaceSetting.py | 73 +++++ PLC/Methods/DeleteInterfaceSettingType.py | 39 +++ PLC/Methods/DeleteNodeFromNodeGroup.py | 53 --- PLC/Methods/DeleteNodeNetworkSetting.py | 73 ----- PLC/Methods/DeleteNodeNetworkSettingType.py | 39 --- PLC/Methods/GenerateNodeConfFile.py | 20 +- PLC/Methods/GetBootMedium.py | 28 +- PLC/Methods/GetInterfaceSettingTypes.py | 33 ++ PLC/Methods/GetInterfaceSettings.py | 45 +++ .../{GetNodeNetworks.py => GetInterfaces.py} | 18 +- PLC/Methods/GetNodeNetworkSettingTypes.py | 33 -- PLC/Methods/GetNodeNetworkSettings.py | 45 --- PLC/Methods/GetSlivers.py | 10 +- PLC/Methods/RebootNode.py | 10 +- ...pdateNodeNetwork.py => UpdateInterface.py} | 36 +-- PLC/Methods/UpdateInterfaceSetting.py | 72 +++++ PLC/Methods/UpdateInterfaceSettingType.py | 48 +++ PLC/Methods/UpdateNodeNetworkSetting.py | 72 ----- PLC/Methods/UpdateNodeNetworkSettingType.py | 48 --- PLC/Methods/__init__.py | 142 +++------ PLC/Methods/system/.cvsignore | 1 - PLC/Methods/system/__init__.py | 0 PLC/NetworkMethods.py | 2 +- PLC/NetworkTypes.py | 2 +- PLC/NodeGroups.py | 89 +----- PLC/NodeNetworkSettingTypes.py | 83 ----- PLC/NodeNetworkSettings.py | 57 ---- PLC/Nodes.py | 41 +-- PLC/PCUs.py | 2 +- PLC/Test.py | 74 ++--- PLC/__init__.py | 22 +- doc/PLCAPI.xml.in | 2 +- migrations/001-down-subversion.sql | 3 - migrations/001-up-subversion.sql | 5 - migrations/002-up-slices.sql | 6 - migrations/003-down-network-settings.sql | 24 -- migrations/003-test.py | 60 ---- migrations/003-up-network-settings.sql | 86 ----- migrations/004-up-fix-site-nodes.sql | 16 - migrations/005-down-import-apr-2007.sql | 112 ------- migrations/005-up-import-apr-2007.sql | 154 --------- .../006-down-slice-attribute-nodegroup.sql | 25 -- .../006-up-slice-attribute-nodegroup.sql | 29 -- migrations/007-down-event-objects-view.sql | 11 - migrations/007-up-event-objects-view.sql | 26 -- migrations/008-down-import-aug-2007.sql | 42 --- migrations/008-up-import-aug-2007.sql | 64 ---- migrations/009-down-pcu-types.sql | 13 - migrations/009-up-pcu-types.sql | 41 --- migrations/migrate-v4-to-v5.sh | 227 +++++++++++++ planetlab4.sql => planetlab5.sql | 301 ++++++++++-------- setup.py | 2 +- tools/dzombie.py | 2 +- tools/upgrade-db.py | 2 +- 131 files changed, 1244 insertions(+), 3614 deletions(-) create mode 100644 PLC/InterfaceSettingTypes.py create mode 100644 PLC/InterfaceSettings.py rename PLC/{NodeNetworks.py => Interfaces.py} (81%) delete mode 100644 PLC/Methods/.cvsignore rename PLC/Methods/{AddNodeNetwork.py => AddInterface.py} (58%) create mode 100644 PLC/Methods/AddInterfaceSetting.py create mode 100644 PLC/Methods/AddInterfaceSettingType.py delete mode 100644 PLC/Methods/AddNodeNetworkSetting.py delete mode 100644 PLC/Methods/AddNodeNetworkSettingType.py delete mode 100644 PLC/Methods/AddNodeToNodeGroup.py delete mode 100644 PLC/Methods/AdmAddAddressType.py delete mode 100644 PLC/Methods/AdmAddNode.py delete mode 100644 PLC/Methods/AdmAddNodeGroup.py delete mode 100644 PLC/Methods/AdmAddNodeNetwork.py delete mode 100644 PLC/Methods/AdmAddNodeToNodeGroup.py delete mode 100644 PLC/Methods/AdmAddPerson.py delete mode 100644 PLC/Methods/AdmAddPersonKey.py delete mode 100644 PLC/Methods/AdmAddPersonToSite.py delete mode 100644 PLC/Methods/AdmAddSite.py delete mode 100644 PLC/Methods/AdmAddSitePowerControlUnit.py delete mode 100644 PLC/Methods/AdmAssociateNodeToPowerControlUnitPort.py delete mode 100644 PLC/Methods/AdmAuthCheck.py delete mode 100644 PLC/Methods/AdmDeleteAddressType.py delete mode 100644 PLC/Methods/AdmDeleteAllPersonKeys.py delete mode 100644 PLC/Methods/AdmDeleteNode.py delete mode 100644 PLC/Methods/AdmDeleteNodeGroup.py delete mode 100644 PLC/Methods/AdmDeleteNodeNetwork.py delete mode 100644 PLC/Methods/AdmDeletePerson.py delete mode 100644 PLC/Methods/AdmDeletePersonKeys.py delete mode 100644 PLC/Methods/AdmDeleteSite.py delete mode 100644 PLC/Methods/AdmDeleteSitePowerControlUnit.py delete mode 100644 PLC/Methods/AdmDisassociatePowerControlUnitPort.py delete mode 100644 PLC/Methods/AdmGenerateNodeConfFile.py delete mode 100644 PLC/Methods/AdmGetAllAddressTypes.py delete mode 100644 PLC/Methods/AdmGetAllKeyTypes.py delete mode 100644 PLC/Methods/AdmGetAllNodeNetworks.py delete mode 100644 PLC/Methods/AdmGetAllRoles.py delete mode 100644 PLC/Methods/AdmGetNodeGroupNodes.py delete mode 100644 PLC/Methods/AdmGetNodeGroups.py delete mode 100644 PLC/Methods/AdmGetNodes.py delete mode 100644 PLC/Methods/AdmGetPersonKeys.py delete mode 100644 PLC/Methods/AdmGetPersonRoles.py delete mode 100644 PLC/Methods/AdmGetPersonSites.py delete mode 100644 PLC/Methods/AdmGetPersons.py delete mode 100644 PLC/Methods/AdmGetPowerControlUnitNodes.py delete mode 100644 PLC/Methods/AdmGetPowerControlUnits.py delete mode 100644 PLC/Methods/AdmGetSiteNodes.py delete mode 100644 PLC/Methods/AdmGetSitePIs.py delete mode 100644 PLC/Methods/AdmGetSitePersons.py delete mode 100644 PLC/Methods/AdmGetSitePowerControlUnits.py delete mode 100644 PLC/Methods/AdmGetSiteTechContacts.py delete mode 100644 PLC/Methods/AdmGetSites.py delete mode 100644 PLC/Methods/AdmGrantRoleToPerson.py delete mode 100644 PLC/Methods/AdmIsPersonInRole.py delete mode 100644 PLC/Methods/AdmQueryConfFile.py delete mode 100644 PLC/Methods/AdmQueryNode.py delete mode 100644 PLC/Methods/AdmQueryPerson.py delete mode 100644 PLC/Methods/AdmQueryPowerControlUnit.py delete mode 100644 PLC/Methods/AdmQuerySite.py delete mode 100644 PLC/Methods/AdmRebootNode.py delete mode 100644 PLC/Methods/AdmRemoveNodeFromNodeGroup.py delete mode 100644 PLC/Methods/AdmRemovePersonFromSite.py delete mode 100644 PLC/Methods/AdmRevokeRoleFromPerson.py delete mode 100644 PLC/Methods/AdmSetPersonEnabled.py delete mode 100644 PLC/Methods/AdmSetPersonPrimarySite.py delete mode 100644 PLC/Methods/AdmUpdateNode.py delete mode 100644 PLC/Methods/AdmUpdateNodeGroup.py delete mode 100644 PLC/Methods/AdmUpdateNodeNetwork.py delete mode 100644 PLC/Methods/AdmUpdatePerson.py delete mode 100644 PLC/Methods/AdmUpdateSite.py delete mode 100644 PLC/Methods/AdmUpdateSitePowerControlUnit.py delete mode 100644 PLC/Methods/AnonAdmGetNodeGroups.py rename PLC/Methods/{DeleteNodeNetwork.py => DeleteInterface.py} (69%) create mode 100644 PLC/Methods/DeleteInterfaceSetting.py create mode 100644 PLC/Methods/DeleteInterfaceSettingType.py delete mode 100644 PLC/Methods/DeleteNodeFromNodeGroup.py delete mode 100644 PLC/Methods/DeleteNodeNetworkSetting.py delete mode 100644 PLC/Methods/DeleteNodeNetworkSettingType.py create mode 100644 PLC/Methods/GetInterfaceSettingTypes.py create mode 100644 PLC/Methods/GetInterfaceSettings.py rename PLC/Methods/{GetNodeNetworks.py => GetInterfaces.py} (57%) delete mode 100644 PLC/Methods/GetNodeNetworkSettingTypes.py delete mode 100644 PLC/Methods/GetNodeNetworkSettings.py rename PLC/Methods/{UpdateNodeNetwork.py => UpdateInterface.py} (62%) create mode 100644 PLC/Methods/UpdateInterfaceSetting.py create mode 100644 PLC/Methods/UpdateInterfaceSettingType.py delete mode 100644 PLC/Methods/UpdateNodeNetworkSetting.py delete mode 100644 PLC/Methods/UpdateNodeNetworkSettingType.py delete mode 100644 PLC/Methods/system/.cvsignore delete mode 100644 PLC/Methods/system/__init__.py delete mode 100644 PLC/NodeNetworkSettingTypes.py delete mode 100644 PLC/NodeNetworkSettings.py delete mode 100644 migrations/001-down-subversion.sql delete mode 100644 migrations/001-up-subversion.sql delete mode 100644 migrations/002-up-slices.sql delete mode 100644 migrations/003-down-network-settings.sql delete mode 100755 migrations/003-test.py delete mode 100644 migrations/003-up-network-settings.sql delete mode 100644 migrations/004-up-fix-site-nodes.sql delete mode 100644 migrations/005-down-import-apr-2007.sql delete mode 100644 migrations/005-up-import-apr-2007.sql delete mode 100644 migrations/006-down-slice-attribute-nodegroup.sql delete mode 100644 migrations/006-up-slice-attribute-nodegroup.sql delete mode 100644 migrations/007-down-event-objects-view.sql delete mode 100644 migrations/007-up-event-objects-view.sql delete mode 100644 migrations/008-down-import-aug-2007.sql delete mode 100644 migrations/008-up-import-aug-2007.sql delete mode 100644 migrations/009-down-pcu-types.sql delete mode 100644 migrations/009-up-pcu-types.sql create mode 100755 migrations/migrate-v4-to-v5.sh rename planetlab4.sql => planetlab5.sql (86%) diff --git a/Makefile b/Makefile index 2fc4409..4d12508 100644 --- a/Makefile +++ b/Makefile @@ -82,7 +82,9 @@ tags: ########## make sync PLCHOST=hostname ifdef PLCHOST -PLCSSH:=root@$(PLCHOST) +ifdef VSERVER +PLCSSH:=root@$(PLCHOST):/vservers/$(VSERVER) +endif endif LOCAL_RSYNC_EXCLUDES := --exclude '*.pyc' @@ -92,11 +94,11 @@ RSYNC := rsync -a -v $(RSYNC_COND_DRY_RUN) $(RSYNC_EXCLUDES) sync: ifeq (,$(PLCSSH)) - echo "sync: You must define target host as PLCHOST on the command line" - echo " e.g. make sync PLCHOST=private.one-lab.org" ; exit 1 + echo "sync: You must define PLCHOST and VSERVER on the command line" + echo " e.g. make sync PLCHOST=private.one-lab.org VSERVER=myplc01" ; exit 1 else - +$(RSYNC) PLC planetlab4.sql migrations $(PLCSSH):/plc/root/usr/share/plc_api/ - ssh $(PLCSSH) chroot /plc/root apachectl graceful + +$(RSYNC) PLC planetlab5.sql migrations $(PLCSSH)/usr/share/plc_api/ + ssh root@$(PLCHOST) vserver $(VSERVER) exec apachectl graceful endif #################### diff --git a/PLC/Auth.py b/PLC/Auth.py index f62b511..e4a5a11 100644 --- a/PLC/Auth.py +++ b/PLC/Auth.py @@ -16,7 +16,7 @@ from PLC.Faults import * from PLC.Parameter import Parameter, Mixed from PLC.Persons import Persons from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks +from PLC.Interfaces import Interface, Interfaces from PLC.Sessions import Session, Sessions from PLC.Peers import Peer, Peers from PLC.Boot import notify_owners @@ -224,22 +224,22 @@ class BootAuth(Auth): # on record for the node. key = node['boot_nonce'] - nodenetwork = None - if node['nodenetwork_ids']: - nodenetworks = NodeNetworks(method.api, node['nodenetwork_ids']) - for nodenetwork in nodenetworks: - if nodenetwork['is_primary']: + interface = None + if node['interface_ids']: + interfaces = Interfaces(method.api, node['interface_ids']) + for interface in interfaces: + if interface['is_primary']: break - if not nodenetwork or not nodenetwork['is_primary']: + if not interface or not interface['is_primary']: raise PLCAuthenticationFailure, "No primary network interface on record" if method.source is None: raise PLCAuthenticationFailure, "Cannot determine IP address of requestor" - if nodenetwork['ip'] != method.source[0]: + if interface['ip'] != method.source[0]: raise PLCAuthenticationFailure, "Requestor IP %s does not match node IP %s" % \ - (method.source[0], nodenetwork['ip']) + (method.source[0], interface['ip']) else: raise PLCAuthenticationFailure, "No node key or boot nonce" diff --git a/PLC/InterfaceSettingTypes.py b/PLC/InterfaceSettingTypes.py new file mode 100644 index 0000000..25c59d3 --- /dev/null +++ b/PLC/InterfaceSettingTypes.py @@ -0,0 +1,83 @@ +# +# Thierry Parmentelat - INRIA +# +# $Revision$ +# +from types import StringTypes + +from PLC.Faults import * +from PLC.Parameter import Parameter +from PLC.Filter import Filter +from PLC.Table import Row, Table +from PLC.Roles import Role, Roles + +class InterfaceSettingType (Row): + + """ + Representation of a row in the interface_setting_types table. + """ + + table_name = 'interface_setting_types' + primary_key = 'interface_setting_type_id' + join_tables = ['interface_setting'] + fields = { + 'interface_setting_type_id': Parameter(int, "Interface setting type identifier"), + 'name': Parameter(str, "Interface setting type name", max = 100), + 'description': Parameter(str, "Interface setting type description", max = 254), + 'category' : Parameter (str, "Interface setting category", max=64), + 'min_role_id': Parameter(int, "Minimum (least powerful) role that can set or change this attribute"), + } + + # for Cache + class_key = 'name' + foreign_fields = ['category','description','min_role_id'] + foreign_xrefs = [] + + def validate_name(self, name): + if not len(name): + raise PLCInvalidArgument, "interface setting type name must be set" + + conflicts = InterfaceSettingTypes(self.api, [name]) + for setting_type in conflicts: + if 'interface_setting_type_id' not in self or \ + self['interface_setting_type_id'] != setting_type['interface_setting_type_id']: + raise PLCInvalidArgument, "interface setting type name already in use" + + return name + + def validate_min_role_id(self, role_id): + roles = [row['role_id'] for row in Roles(self.api)] + if role_id not in roles: + raise PLCInvalidArgument, "Invalid role" + + return role_id + +class InterfaceSettingTypes(Table): + """ + Representation of row(s) from the interface_setting_types table + in the database. + """ + + def __init__(self, api, interface_setting_type_filter = None, columns = None): + Table.__init__(self, api, InterfaceSettingType, columns) + + sql = "SELECT %s FROM interface_setting_types WHERE True" % \ + ", ".join(self.columns) + + if interface_setting_type_filter is not None: + if isinstance(interface_setting_type_filter, (list, tuple, set)): + # Separate the list into integers and strings + ints = filter(lambda x: isinstance(x, (int, long)), interface_setting_type_filter) + strs = filter(lambda x: isinstance(x, StringTypes), interface_setting_type_filter) + interface_setting_type_filter = Filter(InterfaceSettingType.fields, {'interface_setting_type_id': ints, 'name': strs}) + sql += " AND (%s) %s" % interface_setting_type_filter.sql(api, "OR") + elif isinstance(interface_setting_type_filter, dict): + interface_setting_type_filter = Filter(InterfaceSettingType.fields, interface_setting_type_filter) + sql += " AND (%s) %s" % interface_setting_type_filter.sql(api, "AND") + elif isinstance (interface_setting_type_filter, StringTypes): + interface_setting_type_filter = Filter(InterfaceSettingType.fields, {'name':[interface_setting_type_filter]}) + sql += " AND (%s) %s" % interface_setting_type_filter.sql(api, "AND") + else: + raise PLCInvalidArgument, "Wrong interface setting type filter %r"%interface_setting_type_filter + + self.selectall(sql) diff --git a/PLC/InterfaceSettings.py b/PLC/InterfaceSettings.py new file mode 100644 index 0000000..63442f1 --- /dev/null +++ b/PLC/InterfaceSettings.py @@ -0,0 +1,57 @@ +# +# Thierry Parmentelat - INRIA +# +# $Revision$ +# +from PLC.Faults import * +from PLC.Parameter import Parameter +from PLC.Filter import Filter +from PLC.Table import Row, Table +from PLC.InterfaceSettingTypes import InterfaceSettingType, InterfaceSettingTypes + +class InterfaceSetting(Row): + """ + Representation of a row in the interface_setting. + To use, instantiate with a dict of values. + """ + + table_name = 'interface_setting' + primary_key = 'interface_setting_id' + fields = { + 'interface_setting_id': Parameter(int, "Interface setting identifier"), + 'interface_id': Parameter(int, "Interface identifier"), + 'interface_setting_type_id': InterfaceSettingType.fields['interface_setting_type_id'], + 'name': InterfaceSettingType.fields['name'], + 'description': InterfaceSettingType.fields['description'], + 'category': InterfaceSettingType.fields['category'], + 'min_role_id': InterfaceSettingType.fields['min_role_id'], + 'value': Parameter(str, "Interface setting value"), + ### relations + + } + +class InterfaceSettings(Table): + """ + Representation of row(s) from the interface_setting table in the + database. + """ + + def __init__(self, api, interface_setting_filter = None, columns = None): + Table.__init__(self, api, InterfaceSetting, columns) + + sql = "SELECT %s FROM view_interface_settings WHERE True" % \ + ", ".join(self.columns) + + if interface_setting_filter is not None: + if isinstance(interface_setting_filter, (list, tuple, set)): + interface_setting_filter = Filter(InterfaceSetting.fields, {'interface_setting_id': interface_setting_filter}) + elif isinstance(interface_setting_filter, dict): + interface_setting_filter = Filter(InterfaceSetting.fields, interface_setting_filter) + elif isinstance(interface_setting_filter, int): + interface_setting_filter = Filter(InterfaceSetting.fields, {'interface_setting_id': [interface_setting_filter]}) + else: + raise PLCInvalidArgument, "Wrong interface setting filter %r"%interface_setting_filter + sql += " AND (%s) %s" % interface_setting_filter.sql(api) + + + self.selectall(sql) diff --git a/PLC/NodeNetworks.py b/PLC/Interfaces.py similarity index 81% rename from PLC/NodeNetworks.py rename to PLC/Interfaces.py index f63ca23..18016a6 100644 --- a/PLC/NodeNetworks.py +++ b/PLC/Interfaces.py @@ -1,5 +1,5 @@ # -# Functions for interacting with the nodenetworks table in the database +# Functions for interacting with the interfaces table in the database # # Mark Huang # Copyright (C) 2006 The Trustees of Princeton University @@ -39,18 +39,18 @@ def in_same_network(address1, address2, netmask): return (address1 & netmask) == (address2 & netmask) -class NodeNetwork(Row): +class Interface(Row): """ - Representation of a row in the nodenetworks table. To use, optionally + 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 = 'nodenetworks' - primary_key = 'nodenetwork_id' - join_tables = ['nodenetwork_setting'] + table_name = 'interfaces' + primary_key = 'interface_id' + join_tables = ['interface_setting'] fields = { - 'nodenetwork_id': Parameter(int, "Node interface identifier"), + 'interface_id': Parameter(int, "Node interface identifier"), '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), @@ -65,7 +65,7 @@ class NodeNetwork(Row): '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"), - 'nodenetwork_setting_ids' : Parameter([int], "List of nodenetwork settings"), + 'setting_ids' : Parameter([int], "List of interface settings"), } def validate_method(self, method): @@ -148,12 +148,12 @@ class NodeNetwork(Row): raise PLCInvalidArgument, "No such node %d"%node_id node = nodes[0] - if node['nodenetwork_ids']: - conflicts = NodeNetworks(self.api, node['nodenetwork_ids']) - for nodenetwork in conflicts: - if ('nodenetwork_id' not in self or \ - self['nodenetwork_id'] != nodenetwork['nodenetwork_id']) and \ - nodenetwork['is_primary']: + if node['interface_ids']: + conflicts = Interfaces(self.api, node['interface_ids']) + for interface in conflicts: + if ('interface_id' not in self or \ + self['interface_id'] != interface['interface_id']) and \ + interface['is_primary']: raise PLCInvalidArgument, "Can only set one primary interface per node" return is_primary @@ -205,27 +205,27 @@ class NodeNetwork(Row): if 'ip' not in self or not self['ip']: raise PLCInvalidArgument, "For ipmi method, ip is required" -class NodeNetworks(Table): +class Interfaces(Table): """ - Representation of row(s) from the nodenetworks table in the + Representation of row(s) from the interfaces table in the database. """ - def __init__(self, api, nodenetwork_filter = None, columns = None): - Table.__init__(self, api, NodeNetwork, columns) + def __init__(self, api, interface_filter = None, columns = None): + Table.__init__(self, api, Interface, columns) - sql = "SELECT %s FROM view_nodenetworks WHERE True" % \ + sql = "SELECT %s FROM view_interfaces WHERE True" % \ ", ".join(self.columns) - if nodenetwork_filter is not None: - if isinstance(nodenetwork_filter, (list, tuple, set)): - nodenetwork_filter = Filter(NodeNetwork.fields, {'nodenetwork_id': nodenetwork_filter}) - elif isinstance(nodenetwork_filter, dict): - nodenetwork_filter = Filter(NodeNetwork.fields, nodenetwork_filter) - elif isinstance(nodenetwork_filter, int): - nodenetwork_filter = Filter(NodeNetwork.fields, {'nodenetwork_id': [nodenetwork_filter]}) + if interface_filter is not None: + if isinstance(interface_filter, (list, tuple, set)): + interface_filter = Filter(Interface.fields, {'interface_id': interface_filter}) + elif isinstance(interface_filter, dict): + interface_filter = Filter(Interface.fields, interface_filter) + elif isinstance(interface_filter, int): + interface_filter = Filter(Interface.fields, {'interface_id': [interface_filter]}) else: - raise PLCInvalidArgument, "Wrong node network filter %r"%nodenetwork_filter - sql += " AND (%s) %s" % nodenetwork_filter.sql(api) + raise PLCInvalidArgument, "Wrong node network filter %r"%interface_filter + sql += " AND (%s) %s" % interface_filter.sql(api) self.selectall(sql) diff --git a/PLC/Methods/.cvsignore b/PLC/Methods/.cvsignore deleted file mode 100644 index 0d20b64..0000000 --- a/PLC/Methods/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/PLC/Methods/AddNodeNetwork.py b/PLC/Methods/AddInterface.py similarity index 58% rename from PLC/Methods/AddNodeNetwork.py rename to PLC/Methods/AddInterface.py index 6e24bce..6bfb4e5 100644 --- a/PLC/Methods/AddNodeNetwork.py +++ b/PLC/Methods/AddInterface.py @@ -2,46 +2,46 @@ from PLC.Faults import * from PLC.Method import Method from PLC.Parameter import Parameter, Mixed from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks +from PLC.Interfaces import Interface, Interfaces from PLC.Auth import Auth -can_update = lambda (field, value): field not in ['nodenetwork_id', 'node_id'] +can_update = lambda (field, value): field not in ['interface_id', 'node_id'] -class AddNodeNetwork(Method): +class AddInterface(Method): """ Adds a new network for a node. Any values specified in - nodenetwork_fields are used, otherwise defaults are + interface_fields are used, otherwise defaults are used. Acceptable values for method may be retrieved via GetNetworkMethods. Acceptable values for type may be retrieved via GetNetworkTypes. If type is static, ip, gateway, network, broadcast, netmask, and - dns1 must all be specified in nodenetwork_fields. If type is dhcp, + dns1 must all be specified in interface_fields. If type is dhcp, these parameters, even if specified, are ignored. PIs and techs may only add networks to their own nodes. Admins may add networks to any node. - Returns the new nodenetwork_id (> 0) if successful, faults otherwise. + Returns the new interface_id (> 0) if successful, faults otherwise. """ roles = ['admin', 'pi', 'tech'] - nodenetwork_fields = dict(filter(can_update, NodeNetwork.fields.items())) + interface_fields = dict(filter(can_update, Interface.fields.items())) accepts = [ Auth(), Mixed(Node.fields['node_id'], Node.fields['hostname']), - nodenetwork_fields + interface_fields ] - returns = Parameter(int, 'New nodenetwork_id (> 0) if successful') + returns = Parameter(int, 'New interface_id (> 0) if successful') - def call(self, auth, node_id_or_hostname, nodenetwork_fields): - nodenetwork_fields = dict(filter(can_update, nodenetwork_fields.items())) + def call(self, auth, node_id_or_hostname, interface_fields): + interface_fields = dict(filter(can_update, interface_fields.items())) # Check if node exists nodes = Nodes(self.api, [node_id_or_hostname]) @@ -59,15 +59,15 @@ class AddNodeNetwork(Method): raise PLCPermissionDenied, "Not allowed to add node network for specified node" # Add node network - nodenetwork = NodeNetwork(self.api, nodenetwork_fields) - nodenetwork['node_id'] = node['node_id'] + interface = Interface(self.api, interface_fields) + interface['node_id'] = node['node_id'] # if this is the first node network, make it primary - if not node['nodenetwork_ids']: - nodenetwork['is_primary'] = True - nodenetwork.sync() + if not node['interface_ids']: + interface['is_primary'] = True + interface.sync() # Logging variables - self.object_ids = [node['node_id'], nodenetwork['nodenetwork_id']] - self.messgage = "Node network %d added" % nodenetwork['nodenetwork_id'] + self.object_ids = [node['node_id'], interface['interface_id']] + self.messgage = "Node network %d added" % interface['interface_id'] - return nodenetwork['nodenetwork_id'] + return interface['interface_id'] diff --git a/PLC/Methods/AddInterfaceSetting.py b/PLC/Methods/AddInterfaceSetting.py new file mode 100644 index 0000000..bc2c621 --- /dev/null +++ b/PLC/Methods/AddInterfaceSetting.py @@ -0,0 +1,89 @@ +# +# Thierry Parmentelat - INRIA +# +# $Revision$ +# +from PLC.Faults import * +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.Auth import Auth + +from PLC.InterfaceSettingTypes import InterfaceSettingType, InterfaceSettingTypes +from PLC.InterfaceSettings import InterfaceSetting, InterfaceSettings +from PLC.Interfaces import Interface, Interfaces + +from PLC.Nodes import Nodes +from PLC.Sites import Sites + +class AddInterfaceSetting(Method): + """ + Sets the specified setting for the specified interface + to the specified value. + + In general only tech(s), PI(s) and of course admin(s) are allowed to + do the change, but this is defined in the interface setting type object. + + Returns the new interface_setting_id (> 0) if successful, faults + otherwise. + """ + + roles = ['admin', 'pi', 'tech', 'user'] + + accepts = [ + Auth(), + # no other way to refer to a interface + InterfaceSetting.fields['interface_id'], + Mixed(InterfaceSettingType.fields['interface_setting_type_id'], + InterfaceSettingType.fields['name']), + InterfaceSetting.fields['value'], + ] + + returns = Parameter(int, 'New interface_setting_id (> 0) if successful') + + object_type = 'Interface' + + + def call(self, auth, interface_id, interface_setting_type_id_or_name, value): + interfaces = Interfaces(self.api, [interface_id]) + if not interfaces: + raise PLCInvalidArgument, "No such interface %r"%interface_id + interface = interfaces[0] + + interface_setting_types = InterfaceSettingTypes(self.api, [interface_setting_type_id_or_name]) + if not interface_setting_types: + raise PLCInvalidArgument, "No such interface setting type %r"%interface_setting_type_id_or_name + interface_setting_type = interface_setting_types[0] + + # checks for existence - does not allow several different settings + conflicts = InterfaceSettings(self.api, + {'interface_id':interface['interface_id'], + 'interface_setting_type_id':interface_setting_type['interface_setting_type_id']}) + + if len(conflicts) : + raise PLCInvalidArgument, "Interface %d already has setting %d"%(interface['interface_id'], + interface_setting_type['interface_setting_type_id']) + + # check permission : it not admin, is the user affiliated with the right site + if 'admin' not in self.caller['roles']: + # locate node + node = Nodes (self.api,[interface['node_id']])[0] + # locate site + site = Sites (self.api, [node['site_id']])[0] + # check caller is affiliated with this site + if self.caller['person_id'] not in site['person_ids']: + raise PLCPermissionDenied, "Not a member of the hosting site %s"%site['abbreviated_site'] + + required_min_role = interface_setting_type ['min_role_id'] + if required_min_role is not None and \ + min(self.caller['role_ids']) > required_min_role: + raise PLCPermissionDenied, "Not allowed to modify the specified interface setting, requires role %d",required_min_role + + interface_setting = InterfaceSetting(self.api) + interface_setting['interface_id'] = interface['interface_id'] + interface_setting['interface_setting_type_id'] = interface_setting_type['interface_setting_type_id'] + interface_setting['value'] = value + + interface_setting.sync() + self.object_ids = [interface_setting['interface_setting_id']] + + return interface_setting['interface_setting_id'] diff --git a/PLC/Methods/AddInterfaceSettingType.py b/PLC/Methods/AddInterfaceSettingType.py new file mode 100644 index 0000000..29141c2 --- /dev/null +++ b/PLC/Methods/AddInterfaceSettingType.py @@ -0,0 +1,45 @@ +# +# Thierry Parmentelat - INRIA +# +# $Revision$ +# + + +from PLC.Faults import * +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.InterfaceSettingTypes import InterfaceSettingType, InterfaceSettingTypes +from PLC.Auth import Auth + +can_update = lambda (field, value): field in \ + ['name', 'description', 'category', 'min_role_id'] + +class AddInterfaceSettingType(Method): + """ + Adds a new type of interface setting. + Any fields specified are used, otherwise defaults are used. + + Returns the new interface_setting_id (> 0) if successful, + faults otherwise. + """ + + roles = ['admin'] + + interface_setting_type_fields = dict(filter(can_update, InterfaceSettingType.fields.items())) + + accepts = [ + Auth(), + interface_setting_type_fields + ] + + returns = Parameter(int, 'New interface_setting_id (> 0) if successful') + + + def call(self, auth, interface_setting_type_fields): + interface_setting_type_fields = dict(filter(can_update, interface_setting_type_fields.items())) + interface_setting_type = InterfaceSettingType(self.api, interface_setting_type_fields) + interface_setting_type.sync() + + self.object_ids = [interface_setting_type['interface_setting_type_id']] + + return interface_setting_type['interface_setting_type_id'] diff --git a/PLC/Methods/AddNodeNetworkSetting.py b/PLC/Methods/AddNodeNetworkSetting.py deleted file mode 100644 index b31aed2..0000000 --- a/PLC/Methods/AddNodeNetworkSetting.py +++ /dev/null @@ -1,89 +0,0 @@ -# -# Thierry Parmentelat - INRIA -# -# $Revision$ -# -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Auth import Auth - -from PLC.NodeNetworkSettingTypes import NodeNetworkSettingType, NodeNetworkSettingTypes -from PLC.NodeNetworkSettings import NodeNetworkSetting, NodeNetworkSettings -from PLC.NodeNetworks import NodeNetwork, NodeNetworks - -from PLC.Nodes import Nodes -from PLC.Sites import Sites - -class AddNodeNetworkSetting(Method): - """ - Sets the specified setting for the specified nodenetwork - to the specified value. - - In general only tech(s), PI(s) and of course admin(s) are allowed to - do the change, but this is defined in the nodenetwork setting type object. - - Returns the new nodenetwork_setting_id (> 0) if successful, faults - otherwise. - """ - - roles = ['admin', 'pi', 'tech', 'user'] - - accepts = [ - Auth(), - # no other way to refer to a nodenetwork - NodeNetworkSetting.fields['nodenetwork_id'], - Mixed(NodeNetworkSettingType.fields['nodenetwork_setting_type_id'], - NodeNetworkSettingType.fields['name']), - NodeNetworkSetting.fields['value'], - ] - - returns = Parameter(int, 'New nodenetwork_setting_id (> 0) if successful') - - object_type = 'NodeNetwork' - - - def call(self, auth, nodenetwork_id, nodenetwork_setting_type_id_or_name, value): - nodenetworks = NodeNetworks(self.api, [nodenetwork_id]) - if not nodenetworks: - raise PLCInvalidArgument, "No such nodenetwork %r"%nodenetwork_id - nodenetwork = nodenetworks[0] - - nodenetwork_setting_types = NodeNetworkSettingTypes(self.api, [nodenetwork_setting_type_id_or_name]) - if not nodenetwork_setting_types: - raise PLCInvalidArgument, "No such nodenetwork setting type %r"%nodenetwork_setting_type_id_or_name - nodenetwork_setting_type = nodenetwork_setting_types[0] - - # checks for existence - does not allow several different settings - conflicts = NodeNetworkSettings(self.api, - {'nodenetwork_id':nodenetwork['nodenetwork_id'], - 'nodenetwork_setting_type_id':nodenetwork_setting_type['nodenetwork_setting_type_id']}) - - if len(conflicts) : - raise PLCInvalidArgument, "Nodenetwork %d already has setting %d"%(nodenetwork['nodenetwork_id'], - nodenetwork_setting_type['nodenetwork_setting_type_id']) - - # check permission : it not admin, is the user affiliated with the right site - if 'admin' not in self.caller['roles']: - # locate node - node = Nodes (self.api,[nodenetwork['node_id']])[0] - # locate site - site = Sites (self.api, [node['site_id']])[0] - # check caller is affiliated with this site - if self.caller['person_id'] not in site['person_ids']: - raise PLCPermissionDenied, "Not a member of the hosting site %s"%site['abbreviated_site'] - - required_min_role = nodenetwork_setting_type ['min_role_id'] - if required_min_role is not None and \ - min(self.caller['role_ids']) > required_min_role: - raise PLCPermissionDenied, "Not allowed to modify the specified nodenetwork setting, requires role %d",required_min_role - - nodenetwork_setting = NodeNetworkSetting(self.api) - nodenetwork_setting['nodenetwork_id'] = nodenetwork['nodenetwork_id'] - nodenetwork_setting['nodenetwork_setting_type_id'] = nodenetwork_setting_type['nodenetwork_setting_type_id'] - nodenetwork_setting['value'] = value - - nodenetwork_setting.sync() - self.object_ids = [nodenetwork_setting['nodenetwork_setting_id']] - - return nodenetwork_setting['nodenetwork_setting_id'] diff --git a/PLC/Methods/AddNodeNetworkSettingType.py b/PLC/Methods/AddNodeNetworkSettingType.py deleted file mode 100644 index 35a3ca0..0000000 --- a/PLC/Methods/AddNodeNetworkSettingType.py +++ /dev/null @@ -1,45 +0,0 @@ -# -# Thierry Parmentelat - INRIA -# -# $Revision$ -# - - -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.NodeNetworkSettingTypes import NodeNetworkSettingType, NodeNetworkSettingTypes -from PLC.Auth import Auth - -can_update = lambda (field, value): field in \ - ['name', 'description', 'category', 'min_role_id'] - -class AddNodeNetworkSettingType(Method): - """ - Adds a new type of nodenetwork setting. - Any fields specified are used, otherwise defaults are used. - - Returns the new nodenetwork_setting_id (> 0) if successful, - faults otherwise. - """ - - roles = ['admin'] - - nodenetwork_setting_type_fields = dict(filter(can_update, NodeNetworkSettingType.fields.items())) - - accepts = [ - Auth(), - nodenetwork_setting_type_fields - ] - - returns = Parameter(int, 'New nodenetwork_setting_id (> 0) if successful') - - - def call(self, auth, nodenetwork_setting_type_fields): - nodenetwork_setting_type_fields = dict(filter(can_update, nodenetwork_setting_type_fields.items())) - nodenetwork_setting_type = NodeNetworkSettingType(self.api, nodenetwork_setting_type_fields) - nodenetwork_setting_type.sync() - - self.object_ids = [nodenetwork_setting_type['nodenetwork_setting_type_id']] - - return nodenetwork_setting_type['nodenetwork_setting_type_id'] diff --git a/PLC/Methods/AddNodeToNodeGroup.py b/PLC/Methods/AddNodeToNodeGroup.py deleted file mode 100644 index a552b11..0000000 --- a/PLC/Methods/AddNodeToNodeGroup.py +++ /dev/null @@ -1,55 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.NodeGroups import NodeGroup, NodeGroups -from PLC.Nodes import Node, Nodes -from PLC.Auth import Auth - -class AddNodeToNodeGroup(Method): - """ - Add a node to the specified node group. If the node is - already a member of the nodegroup, no errors are returned. - - Returns 1 if successful, faults otherwise. - """ - - roles = ['admin'] - - accepts = [ - Auth(), - Mixed(Node.fields['node_id'], - Node.fields['hostname']), - Mixed(NodeGroup.fields['nodegroup_id'], - NodeGroup.fields['name']), - ] - - returns = Parameter(int, '1 if successful') - - - def call(self, auth, node_id_or_hostname, nodegroup_id_or_name): - # Get node info - nodes = Nodes(self.api, [node_id_or_hostname]) - if not nodes: - raise PLCInvalidArgument, "No such node" - node = nodes[0] - - if node['peer_id'] is not None: - raise PLCInvalidArgument, "Not a local node" - - # Get nodegroup info - nodegroups = NodeGroups(self.api, [nodegroup_id_or_name]) - if not nodegroups: - raise PLCInvalidArgument, "No such nodegroup" - - nodegroup = nodegroups[0] - - # add node to nodegroup - if node['node_id'] not in nodegroup['node_ids']: - nodegroup.add_node(node) - - # Logging variables - self.event_objects = {'NodeGroup': [nodegroup['nodegroup_id']], - 'Node': [node['node_id']]} - self.message = 'Node %d added to node group %d' % \ - (node['node_id'], nodegroup['nodegroup_id']) - return 1 diff --git a/PLC/Methods/AdmAddAddressType.py b/PLC/Methods/AdmAddAddressType.py deleted file mode 100644 index e0cd09d..0000000 --- a/PLC/Methods/AdmAddAddressType.py +++ /dev/null @@ -1,21 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.AddressTypes import AddressType, AddressTypes -from PLC.Auth import Auth -from PLC.Methods.AddAddressType import AddAddressType - -class AdmAddAddressType(AddAddressType): - """ - Deprecated. See AddAddressType. - """ - - status = "deprecated" - - accepts = [ - Auth(), - AddressType.fields['name'] - ] - - def call(self, auth, name): - return AddAddressType.call(self, auth, {'name': name}) diff --git a/PLC/Methods/AdmAddNode.py b/PLC/Methods/AdmAddNode.py deleted file mode 100644 index dda5c99..0000000 --- a/PLC/Methods/AdmAddNode.py +++ /dev/null @@ -1,33 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Nodes import Node, Nodes -from PLC.Sites import Site, Sites -from PLC.Auth import Auth -from PLC.Methods.AddNode import AddNode - -can_update = lambda (field, value): field in \ - ['model', 'version'] - -class AdmAddNode(AddNode): - """ - Deprecated. See AddNode. - """ - - status = "deprecated" - - node_fields = dict(filter(can_update, Node.fields.items())) - - accepts = [ - Auth(), - Site.fields['site_id'], - Node.fields['hostname'], - Node.fields['boot_state'], - node_fields - ] - - def call(self, auth, site_id, hostname, boot_state, node_fields = {}): - node_fields['site_id'] = site_id - node_fields['hostname'] = hostname - node_fields['boot_state'] = boot_state - return AddNode.call(self, auth, node_fields) diff --git a/PLC/Methods/AdmAddNodeGroup.py b/PLC/Methods/AdmAddNodeGroup.py deleted file mode 100644 index 6bbb59e..0000000 --- a/PLC/Methods/AdmAddNodeGroup.py +++ /dev/null @@ -1,22 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.NodeGroups import NodeGroup, NodeGroups -from PLC.Auth import Auth -from PLC.Methods.AddNodeGroup import AddNodeGroup - -class AdmAddNodeGroup(AddNodeGroup): - """ - Deprecated. See AddNodeGroup. - """ - - status = "deprecated" - - accepts = [ - Auth(), - NodeGroup.fields['name'], - NodeGroup.fields['description'] - ] - - def call(self, auth, name, description): - return AddNodeGroup.call(self, auth, {'name': name, 'description': description}) diff --git a/PLC/Methods/AdmAddNodeNetwork.py b/PLC/Methods/AdmAddNodeNetwork.py deleted file mode 100644 index c309a77..0000000 --- a/PLC/Methods/AdmAddNodeNetwork.py +++ /dev/null @@ -1,31 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.NodeNetworks import NodeNetwork, NodeNetworks -from PLC.Auth import Auth -from PLC.Methods.AddNodeNetwork import AddNodeNetwork - -can_update = lambda (field, value): field not in ['nodenetwork_id', 'node_id', 'method', 'type'] - -class AdmAddNodeNetwork(AddNodeNetwork): - """ - Deprecated. See AddNodeNetwork. - """ - - status = "deprecated" - - nodenetwork_fields = dict(filter(can_update, NodeNetwork.fields.items())) - - accepts = [ - Auth(), - NodeNetwork.fields['node_id'], - NodeNetwork.fields['method'], - NodeNetwork.fields['type'], - nodenetwork_fields - ] - - def call(self, auth, node_id, method, type, nodenetwork_fields = {}): - nodenetwork_fields['node_id'] = node_id - nodenetwork_fields['method'] = method - nodenetwork_fields['type'] = type - return AddNodeNetwork.call(self, auth, nodenetwork_fields) diff --git a/PLC/Methods/AdmAddNodeToNodeGroup.py b/PLC/Methods/AdmAddNodeToNodeGroup.py deleted file mode 100644 index dc7eab4..0000000 --- a/PLC/Methods/AdmAddNodeToNodeGroup.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.AddNodeToNodeGroup import AddNodeToNodeGroup - -class AdmAddNodeToNodeGroup(AddNodeToNodeGroup): - """ - Deprecated. See AddNodeToNodeGroup. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmAddPerson.py b/PLC/Methods/AdmAddPerson.py deleted file mode 100644 index 2b90f61..0000000 --- a/PLC/Methods/AdmAddPerson.py +++ /dev/null @@ -1,30 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Persons import Person, Persons -from PLC.Auth import Auth -from PLC.Methods.AddPerson import AddPerson - -can_update = lambda (field, value): field in \ - ['title', 'email', 'password', 'phone', 'url', 'bio'] - -class AdmAddPerson(AddPerson): - """ - Deprecated. See AddPerson. - """ - - status = "deprecated" - - person_fields = dict(filter(can_update, Person.fields.items())) - - accepts = [ - Auth(), - Person.fields['first_name'], - Person.fields['last_name'], - person_fields - ] - - def call(self, auth, first_name, last_name, person_fields = {}): - person_fields['first_name'] = first_name - person_fields['last_name'] = last_name - return AddPerson.call(self, auth, person_fields) diff --git a/PLC/Methods/AdmAddPersonKey.py b/PLC/Methods/AdmAddPersonKey.py deleted file mode 100644 index 05d0a69..0000000 --- a/PLC/Methods/AdmAddPersonKey.py +++ /dev/null @@ -1,28 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Keys import Key, Keys -from PLC.Persons import Person, Persons -from PLC.Auth import Auth -from PLC.Methods.AddPersonKey import AddPersonKey - -class AdmAddPersonKey(AddPersonKey): - """ - Deprecated. See AddPersonKey. Keys can no longer be marked as - primary, i.e. the is_primary argument does nothing. - """ - - status = "deprecated" - - accepts = [ - Auth(), - Mixed(Person.fields['person_id'], - Person.fields['email']), - Key.fields['key_type'], - Key.fields['key'], - Parameter(int, "Make this key the primary key") - ] - - def call(self, auth, person_id_or_email, key_type, key_value, is_primary): - key_fields = {'key_type': key_type, 'key_value': key_value} - return AddPersonKey.call(self, auth, person_id_or_email, key_fields) diff --git a/PLC/Methods/AdmAddPersonToSite.py b/PLC/Methods/AdmAddPersonToSite.py deleted file mode 100644 index 948b06f..0000000 --- a/PLC/Methods/AdmAddPersonToSite.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.AddPersonToSite import AddPersonToSite - -class AdmAddPersonToSite(AddPersonToSite): - """ - Deprecated. See AddPersonToSite. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmAddSite.py b/PLC/Methods/AdmAddSite.py deleted file mode 100644 index 929c0a7..0000000 --- a/PLC/Methods/AdmAddSite.py +++ /dev/null @@ -1,32 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Sites import Site, Sites -from PLC.Auth import Auth -from PLC.Methods.AddSite import AddSite - -can_update = lambda (field, value): field in \ - ['is_public', 'latitude', 'longitude', 'url'] - -class AdmAddSite(AddSite): - """ - Deprecated. See AddSite. - """ - - status = "deprecated" - - site_fields = dict(filter(can_update, Site.fields.items())) - - accepts = [ - Auth(), - Site.fields['name'], - Site.fields['abbreviated_name'], - Site.fields['login_base'], - site_fields - ] - - def call(self, auth, name, abbreviated_name, login_base, site_fields = {}): - site_fields['name'] = name - site_fields['abbreviated_name'] = abbreviated_name - site_fields['login_base'] = login_base - return AddSite.call(self, auth, site_fields) diff --git a/PLC/Methods/AdmAddSitePowerControlUnit.py b/PLC/Methods/AdmAddSitePowerControlUnit.py deleted file mode 100644 index e9e452e..0000000 --- a/PLC/Methods/AdmAddSitePowerControlUnit.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.AddPCU import AddPCU - -class AdmAddSitePowerControlUnit(AddPCU): - """ - Deprecated. See AddPCU. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmAssociateNodeToPowerControlUnitPort.py b/PLC/Methods/AdmAssociateNodeToPowerControlUnitPort.py deleted file mode 100644 index 9e955be..0000000 --- a/PLC/Methods/AdmAssociateNodeToPowerControlUnitPort.py +++ /dev/null @@ -1,29 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Nodes import Node, Nodes -from PLC.PCUs import PCU, PCUs -from PLC.Auth import Auth -from PLC.Methods.AddNodeToPCU import AddNodeToPCU - -class AdmAssociateNodeToPowerControlUnitPort(AddNodeToPCU): - """ - Deprecated. See AddNodeToPCU. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'tech'] - - accepts = [ - Auth(), - PCU.fields['pcu_id'], - Parameter(int, 'PCU port number'), - Mixed(Node.fields['node_id'], - Node.fields['hostname']), - ] - - returns = Parameter(int, '1 if successful') - - def call(self, auth, pcu_id, port, node_id_or_hostname): - return AddNodeToPCU(self, auth, node_id_or_hostname, pcu_id, port) diff --git a/PLC/Methods/AdmAuthCheck.py b/PLC/Methods/AdmAuthCheck.py deleted file mode 100644 index 63defa5..0000000 --- a/PLC/Methods/AdmAuthCheck.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.AuthCheck import AuthCheck - -class AdmAuthCheck(AuthCheck): - """ - Deprecated. See AuthCheck. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmDeleteAddressType.py b/PLC/Methods/AdmDeleteAddressType.py deleted file mode 100644 index 12f0625..0000000 --- a/PLC/Methods/AdmDeleteAddressType.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.DeleteAddressType import DeleteAddressType - -class AdmDeleteAddressType(DeleteAddressType): - """ - Deprecated. See DeleteAddressType. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmDeleteAllPersonKeys.py b/PLC/Methods/AdmDeleteAllPersonKeys.py deleted file mode 100644 index 9f038f9..0000000 --- a/PLC/Methods/AdmDeleteAllPersonKeys.py +++ /dev/null @@ -1,55 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Persons import Person, Persons -from PLC.Keys import Key, Keys -from PLC.Auth import Auth - -class AdmDeleteAllPersonKeys(Method): - """ - Deprecated. Functionality can be implemented with GetPersons and - DeleteKey. - - Deletes all of the keys associated with an account. Non-admins may - only delete their own keys. - - Non-admins may only delete their own keys. - - Returns 1 if successful, faults otherwise. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'tech', 'user'] - - accepts = [ - Auth(), - Mixed(Person.fields['person_id'], - Person.fields['email']) - ] - - returns = Parameter(int, '1 if successful') - - def call(self, auth, person_id_or_email): - # Get account information - persons = Persons(self.api, [person_id_or_email]) - if not persons: - raise PLCInvalidArgument, "No such account" - - person = persons[0] - - if 'admin' not in self.caller['roles']: - if self.caller['person_id'] != person['person_id']: - raise PLCPermissionDenied, "Not allowed to update specified account" - - key_ids = person['key_ids'] - if not key_ids: - return 1 - - # Get associated key details - keys = Keys(self.api, key_ids) - - for key in keys: - key.delete() - - return 1 diff --git a/PLC/Methods/AdmDeleteNode.py b/PLC/Methods/AdmDeleteNode.py deleted file mode 100644 index 2ec9ff1..0000000 --- a/PLC/Methods/AdmDeleteNode.py +++ /dev/null @@ -1,9 +0,0 @@ -from PLC.Methods.DeleteNode import DeleteNode - -class AdmDeleteNode(DeleteNode): - """ - Deprecated. See DeleteNode. - """ - - status = "deprecated" - diff --git a/PLC/Methods/AdmDeleteNodeGroup.py b/PLC/Methods/AdmDeleteNodeGroup.py deleted file mode 100644 index b5b2cb6..0000000 --- a/PLC/Methods/AdmDeleteNodeGroup.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.DeleteNodeGroup import DeleteNodeGroup - -class AdmDeleteNodeGroup(DeleteNodeGroup): - """ - Deprecated. See DeleteNodeGroup. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmDeleteNodeNetwork.py b/PLC/Methods/AdmDeleteNodeNetwork.py deleted file mode 100644 index d566504..0000000 --- a/PLC/Methods/AdmDeleteNodeNetwork.py +++ /dev/null @@ -1,24 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Auth import Auth -from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks -from PLC.Methods.DeleteNodeNetwork import DeleteNodeNetwork - -class AdmDeleteNodeNetwork(DeleteNodeNetwork): - """ - Deprecated. See DeleteNodeNetwork. - """ - - status = "deprecated" - - accepts = [ - Auth(), - Mixed(Node.fields['node_id'], - Node.fields['hostname']), - NodeNetwork.fields['nodenetwork_id'] - ] - - def call(self, auth, node_id_or_hostname, nodenetwork_id): - return DeleteNodeNetwork.call(self, auth, nodenetwork_id) diff --git a/PLC/Methods/AdmDeletePerson.py b/PLC/Methods/AdmDeletePerson.py deleted file mode 100644 index ff29e8b..0000000 --- a/PLC/Methods/AdmDeletePerson.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.DeletePerson import DeletePerson - -class AdmDeletePerson(DeletePerson): - """ - Deprecated. See DeletePerson. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmDeletePersonKeys.py b/PLC/Methods/AdmDeletePersonKeys.py deleted file mode 100644 index fd24eef..0000000 --- a/PLC/Methods/AdmDeletePersonKeys.py +++ /dev/null @@ -1,56 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Persons import Person, Persons -from PLC.Keys import Key, Keys -from PLC.Auth import Auth - -class AdmDeletePersonKeys(Method): - """ - Deprecated. Functionality can be implemented with GetPersons and - DeleteKey. - - Deletes the specified keys. Non-admins may only delete their own - keys. - - Returns 1 if successful, faults otherwise. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'tech', 'user'] - - accepts = [ - Auth(), - Mixed(Person.fields['person_id'], - Person.fields['email']), - [Key.fields['key_id']] - ] - - returns = Parameter(int, '1 if successful') - - def call(self, auth, person_id_or_email, key_ids): - # Get account information - persons = Persons(self.api, [person_id_or_email]) - if not persons: - raise PLCInvalidArgument, "No such account" - person = persons[0] - - if person['peer_id'] is not None: - raise PLCInvalidArgument, "Not a local account" - - if 'admin' not in self.caller['roles']: - if self.caller['person_id'] != person['person_id']: - raise PLCPermissionDenied, "Not allowed to update specified account" - - key_ids = set(key_ids).intersection(person['key_ids']) - if not key_ids: - return 1 - - # Get associated key details - keys = Keys(self.api, key_ids) - - for key in keys: - key.delete() - - return 1 diff --git a/PLC/Methods/AdmDeleteSite.py b/PLC/Methods/AdmDeleteSite.py deleted file mode 100644 index 7501ad5..0000000 --- a/PLC/Methods/AdmDeleteSite.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.DeleteSite import DeleteSite - -class AdmDeleteSite(DeleteSite): - """ - Deprecated. See DeleteSite. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmDeleteSitePowerControlUnit.py b/PLC/Methods/AdmDeleteSitePowerControlUnit.py deleted file mode 100644 index 2865224..0000000 --- a/PLC/Methods/AdmDeleteSitePowerControlUnit.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.DeletePCU import DeletePCU - -class AdmDeleteSitePowerControlUnit(DeletePCU): - """ - Deprecated. See DeletePCU. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmDisassociatePowerControlUnitPort.py b/PLC/Methods/AdmDisassociatePowerControlUnitPort.py deleted file mode 100644 index 5f7c448..0000000 --- a/PLC/Methods/AdmDisassociatePowerControlUnitPort.py +++ /dev/null @@ -1,37 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Nodes import Node, Nodes -from PLC.PCUs import PCU, PCUs -from PLC.Auth import Auth -from PLC.Methods.DeleteNodeFromPCU import DeleteNodeFromPCU - -class AdmDisassociatePowerControlUnitPort(DeleteNodeFromPCU): - """ - Deprecated. See DeleteNodeFromPCU. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'tech'] - - accepts = [ - Auth(), - PCU.fields['pcu_id'], - Parameter(int, 'PCU port number'), - ] - - returns = Parameter(int, '1 if successful') - - def call(self, auth, pcu_id, port): - pcus = PCUs(self.api, [pcu_id]) - if not pcus: - raise PLCInvalidArgument, "No such PCU" - - pcu = pcus[0] - - ports = dict(zip(pcu['ports'], pcu['node_ids'])) - if port not in ports: - raise PLCInvalidArgument, "No node on that port or no such port" - - return DeleteNodeFromPCU(self, auth, ports[port], pcu_id) diff --git a/PLC/Methods/AdmGenerateNodeConfFile.py b/PLC/Methods/AdmGenerateNodeConfFile.py deleted file mode 100644 index 85789bd..0000000 --- a/PLC/Methods/AdmGenerateNodeConfFile.py +++ /dev/null @@ -1,110 +0,0 @@ -import random -import base64 - -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks -from PLC.Auth import Auth - -class AdmGenerateNodeConfFile(Method): - """ - Deprecated. Functionality can be implemented with GetNodes, - GetNodeNetworks, and UpdateNode. - - Creates a new node configuration file if all network settings are - present. This function will generate a new node key for the - specified node, effectively invalidating any old configuration - files. - - Non-admins can only generate files for nodes at their sites. - - Returns the contents of the file if successful, faults otherwise. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'tech'] - - accepts = [ - Auth(), - Mixed(Node.fields['node_id'], - Node.fields['hostname']) - ] - - returns = Parameter(str, "Node configuration file") - - def call(self, auth, node_id_or_hostname): - # Get node information - nodes = Nodes(self.api, [node_id_or_hostname]) - if not nodes: - raise PLCInvalidArgument, "No such node" - node = nodes[0] - - if node['peer_id'] is not None: - raise PLCInvalidArgument, "Not a local node" - - # If we are not an admin, make sure that the caller is a - # member of the site at which the node is located. - if 'admin' not in self.caller['roles']: - if node['site_id'] not in self.caller['site_ids']: - raise PLCPermissionDenied, "Not allowed to generate a configuration file for that node" - - # Get node networks for this node - primary = None - nodenetworks = NodeNetworks(self.api, node['nodenetwork_ids']) - for nodenetwork in nodenetworks: - if nodenetwork['is_primary']: - primary = nodenetwork - break - if primary is None: - raise PLCInvalidArgument, "No primary network configured" - - # Split hostname into host and domain parts - parts = node['hostname'].split(".", 1) - if len(parts) < 2: - raise PLCInvalidArgument, "Node hostname is invalid" - host = parts[0] - domain = parts[1] - - # Generate 32 random bytes - bytes = random.sample(xrange(0, 256), 32) - # Base64 encode their string representation - node['key'] = base64.b64encode("".join(map(chr, bytes))) - # XXX Boot Manager cannot handle = in the key - node['key'] = node['key'].replace("=", "") - # Save it - node.sync() - - # Generate node configuration file suitable for BootCD - file = "" - - file += 'NODE_ID="%d"\n' % node['node_id'] - file += 'NODE_KEY="%s"\n' % node['key'] - - if primary['mac']: - file += 'NET_DEVICE="%s"\n' % primary['mac'].lower() - - file += 'IP_METHOD="%s"\n' % primary['method'] - - if primary['method'] == 'static': - file += 'IP_ADDRESS="%s"\n' % primary['ip'] - file += 'IP_GATEWAY="%s"\n' % primary['gateway'] - file += 'IP_NETMASK="%s"\n' % primary['netmask'] - file += 'IP_NETADDR="%s"\n' % primary['network'] - file += 'IP_BROADCASTADDR="%s"\n' % primary['broadcast'] - file += 'IP_DNS1="%s"\n' % primary['dns1'] - file += 'IP_DNS2="%s"\n' % (primary['dns2'] or "") - - file += 'HOST_NAME="%s"\n' % host - file += 'DOMAIN_NAME="%s"\n' % domain - - for nodenetwork in nodenetworks: - if nodenetwork['method'] == 'ipmi': - file += 'IPMI_ADDRESS="%s"\n' % nodenetwork['ip'] - if nodenetwork['mac']: - file += 'IPMI_MAC="%s"\n' % nodenetwork['mac'].lower() - break - - return file diff --git a/PLC/Methods/AdmGetAllAddressTypes.py b/PLC/Methods/AdmGetAllAddressTypes.py deleted file mode 100644 index ca4748b..0000000 --- a/PLC/Methods/AdmGetAllAddressTypes.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.GetAddressTypes import GetAddressTypes - -class AdmGetAllAddressTypes(GetAddressTypes): - """ - Deprecated. See GetAddressTypes. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmGetAllKeyTypes.py b/PLC/Methods/AdmGetAllKeyTypes.py deleted file mode 100644 index 4383f84..0000000 --- a/PLC/Methods/AdmGetAllKeyTypes.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.GetKeyTypes import GetKeyTypes - -class AdmGetAllKeyTypes(GetKeyTypes): - """ - Deprecated. See GetKeyTypes. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmGetAllNodeNetworks.py b/PLC/Methods/AdmGetAllNodeNetworks.py deleted file mode 100644 index c00bdec..0000000 --- a/PLC/Methods/AdmGetAllNodeNetworks.py +++ /dev/null @@ -1,37 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks -from PLC.Auth import Auth -from PLC.Methods.GetNodeNetworks import GetNodeNetworks - -class AdmGetAllNodeNetworks(GetNodeNetworks): - """ - Deprecated. Functionality can be implemented with GetNodes and - GetNodeNetworks. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - Auth(), - Mixed(Node.fields['node_id'], - Node.fields['hostname']) - ] - - returns = [NodeNetwork.fields] - - def call(self, auth, node_id_or_hostname): - # Get node information - nodes = Nodes(self.api, [node_id_or_hostname]) - if not nodes: - raise PLCInvalidArgument, "No such node" - node = nodes[0] - - if not node['nodenetwork_ids']: - return [] - - return GetNodeNetworks.call(self, auth, node['nodenetwork_ids']) diff --git a/PLC/Methods/AdmGetAllRoles.py b/PLC/Methods/AdmGetAllRoles.py deleted file mode 100644 index 2b88714..0000000 --- a/PLC/Methods/AdmGetAllRoles.py +++ /dev/null @@ -1,32 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter -from PLC.Auth import Auth -from PLC.Methods.GetRoles import GetRoles - -class AdmGetAllRoles(GetRoles): - """ - Deprecated. See GetRoles. - - Return all possible roles as a struct: - - {'10': 'admin', '20': 'pi', '30': 'user', '40': 'tech'} - - Note that because of XML-RPC marshalling limitations, the keys to - this struct are string representations of the integer role - identifiers. - """ - - status = "deprecated" - - returns = dict - - def call(self, auth): - roles_list = GetRoles.call(self, auth) - - roles_dict = {} - for role in roles_list: - # Stringify the keys! - roles_dict[str(role['role_id'])] = role['name'] - - return roles_dict diff --git a/PLC/Methods/AdmGetNodeGroupNodes.py b/PLC/Methods/AdmGetNodeGroupNodes.py deleted file mode 100644 index 51c392a..0000000 --- a/PLC/Methods/AdmGetNodeGroupNodes.py +++ /dev/null @@ -1,36 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Auth import Auth -from PLC.NodeGroups import NodeGroup, NodeGroups - -class AdmGetNodeGroupNodes(Method): - """ - Deprecated. See GetNodeGroups. - - Returns a list of node_ids for the node group specified. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - Auth(), - Mixed(NodeGroup.fields['nodegroup_id'], - NodeGroup.fields['name']) - ] - - returns = NodeGroup.fields['node_ids'] - - def call(self, auth, nodegroup_id_or_name): - # Get nodes in this nodegroup - nodegroups = NodeGroups(self.api, [nodegroup_id_or_name]) - if not nodegroups: - raise PLCInvalidArgument, "No such node group" - - # Get the info for the node group specified - nodegroup = nodegroups[0] - - # Return the list of node_ids - return nodegroup['node_ids'] diff --git a/PLC/Methods/AdmGetNodeGroups.py b/PLC/Methods/AdmGetNodeGroups.py deleted file mode 100644 index fa1ad59..0000000 --- a/PLC/Methods/AdmGetNodeGroups.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.GetNodeGroups import GetNodeGroups - -class AdmGetNodeGroups(GetNodeGroups): - """ - Deprecated. See GetNodeGroups. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmGetNodes.py b/PLC/Methods/AdmGetNodes.py deleted file mode 100644 index 74d8489..0000000 --- a/PLC/Methods/AdmGetNodes.py +++ /dev/null @@ -1,11 +0,0 @@ -from PLC.Methods.GetNodes import GetNodes - -class AdmGetNodes(GetNodes): - """ - Deprecated. See GetNodes. All fields are now always returned. - """ - - status = "deprecated" - - def call(self, auth, node_id_or_hostname_list = None, return_fields = None): - return GetNodes.call(self, auth, node_id_or_hostname_list) diff --git a/PLC/Methods/AdmGetPersonKeys.py b/PLC/Methods/AdmGetPersonKeys.py deleted file mode 100644 index 946230a..0000000 --- a/PLC/Methods/AdmGetPersonKeys.py +++ /dev/null @@ -1,40 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Persons import Person, Persons -from PLC.Keys import Key, Keys -from PLC.Auth import Auth -from PLC.Methods.GetKeys import GetKeys - -class AdmGetPersonKeys(GetKeys): - """ - Deprecated. Functionality can be implemented with GetPersons and - GetKeys. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - Auth(), - Mixed(Person.fields['person_id'], - Person.fields['email']), - [Key.fields['key_id']] - ] - - returns = [Key.fields] - - def call(self, auth, person_id_or_email): - # Get account information - persons = Persons(self.api, [person_id_or_email]) - if not persons: - raise PLCInvalidArgument, "No such account" - - person = persons[0] - - if 'admin' not in self.caller['roles']: - if self.caller['person_id'] != person['person_id']: - raise PLCPermissionDenied, "Not allowed to view keys for specified account" - - return GetKeys.call(self, auth, person['key_ids']) diff --git a/PLC/Methods/AdmGetPersonRoles.py b/PLC/Methods/AdmGetPersonRoles.py deleted file mode 100644 index 024b93c..0000000 --- a/PLC/Methods/AdmGetPersonRoles.py +++ /dev/null @@ -1,55 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Persons import Person, Persons -from PLC.Auth import Auth - -class AdmGetPersonRoles(Method): - """ - Deprecated. See GetPersons. - - Return the roles that the specified person has as a struct: - - {'10': 'admin', '30': 'user', '20': 'pi', '40': 'tech'} - - Admins can get the roles for any user. PIs can only get the roles - for members of their sites. All others may only get their own - roles. - - Note that because of XML-RPC marshalling limitations, the keys to - this struct are string representations of the integer role - identifiers. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - Auth(), - Mixed(Person.fields['person_id'], - Person.fields['email']) - ] - - returns = dict - - def call(self, auth, person_id_or_email): - # Get account information - persons = Persons(self.api, [person_id_or_email]) - if not persons: - raise PLCInvalidArgument, "No such account" - - person = persons[0] - - # Authenticated function - assert self.caller is not None - - # Check if we can view this account - if not self.caller.can_view(person): - raise PLCPermissionDenied, "Not allowed to view specified account" - - # Stringify the keys! - role_ids = map(str, person['role_ids']) - roles = person['roles'] - - return dict(zip(role_ids, roles)) diff --git a/PLC/Methods/AdmGetPersonSites.py b/PLC/Methods/AdmGetPersonSites.py deleted file mode 100644 index 79324f8..0000000 --- a/PLC/Methods/AdmGetPersonSites.py +++ /dev/null @@ -1,47 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Persons import Person, Persons -from PLC.Sites import Site, Sites -from PLC.Auth import Auth - -class AdmGetPersonSites(Method): - """ - Deprecated. See GetPersons. - - Returns the sites that the specified person is associated with as - an array of site identifiers. - - Admins may retrieve details about anyone. Users and techs may only - retrieve details about themselves. PIs may retrieve details about - themselves and others at their sites. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - Auth(), - Mixed(Person.fields['person_id'], - Person.fields['email']) - ] - - returns = Person.fields['site_ids'] - - def call(self, auth, person_id_or_email): - # Get account information - persons = Persons(self.api, [person_id_or_email]) - if not persons: - raise PLCInvalidArgument, "No such account" - - person = persons[0] - - # Authenticated function - assert self.caller is not None - - # Check if we can view this account - if not self.caller.can_view(person): - raise PLCPermissionDenied, "Not allowed to view specified account" - - return person['site_ids'] diff --git a/PLC/Methods/AdmGetPersons.py b/PLC/Methods/AdmGetPersons.py deleted file mode 100644 index 35e94a0..0000000 --- a/PLC/Methods/AdmGetPersons.py +++ /dev/null @@ -1,11 +0,0 @@ -from PLC.Methods.GetPersons import GetPersons - -class AdmGetPersons(GetPersons): - """ - Deprecated. See GetPersons. - """ - - status = "deprecated" - - def call(self, auth, person_id_or_email_list = None, return_fields = None): - return GetPersons.call(self, auth, person_id_or_email_list) diff --git a/PLC/Methods/AdmGetPowerControlUnitNodes.py b/PLC/Methods/AdmGetPowerControlUnitNodes.py deleted file mode 100644 index af298ee..0000000 --- a/PLC/Methods/AdmGetPowerControlUnitNodes.py +++ /dev/null @@ -1,41 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.PCUs import PCU, PCUs -from PLC.Auth import Auth - -class AdmGetPowerControlUnitNodes(Method): - """ - Deprecated. See GetPCUs. - - Returns a list of the nodes, and the ports they are assigned to, - on the specified PCU. - - Admin may query all PCUs. Non-admins may only query the PCUs at - their sites. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'tech'] - - accepts = [ - Auth(), - PCU.fields['pcu_id'] - ] - - returns = [{'node_id': Parameter(int, "Node identifier"), - 'port_number': Parameter(int, "Port number")}] - - def call(self, auth, pcu_id): - pcus = PCUs(self.api, [pcu_id]) - if not pcus: - raise PLCInvalidArgument, "No such PCU" - pcu = pcus[0] - - if 'admin' not in self.caller['roles']: - if pcu['site_id'] not in self.caller['site_ids']: - raise PLCPermissionDenied, "Not allowed to view that PCU" - - return [{'node_id': node_id, 'port_number': port} \ - for (node_id, port) in zip(pcu['node_ids'], pcu['ports'])] diff --git a/PLC/Methods/AdmGetPowerControlUnits.py b/PLC/Methods/AdmGetPowerControlUnits.py deleted file mode 100644 index 8f7e0c7..0000000 --- a/PLC/Methods/AdmGetPowerControlUnits.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.GetPCUs import GetPCUs - -class AdmGetPowerControlUnits(GetPCUs): - """ - Deprecated. See GetPCUs. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmGetSiteNodes.py b/PLC/Methods/AdmGetSiteNodes.py deleted file mode 100644 index b366c80..0000000 --- a/PLC/Methods/AdmGetSiteNodes.py +++ /dev/null @@ -1,44 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Sites import Site, Sites -from PLC.Auth import Auth - -class AdmGetSiteNodes(Method): - """ - Deprecated. See GetSites. - - Return a struct containing an array of node_ids for each of the - sites specified. Note that the keys of the struct are strings, not - integers, because of XML-RPC marshalling limitations. - - Admins may retrieve details about all nodes on a site by not specifying - site_id_or_name or by specifying an empty list. Users and - techs may only retrieve details about themselves. PIs may retrieve - details about themselves and others at their sites. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - Auth(), - [Mixed(Site.fields['site_id'], - Site.fields['name'])], - ] - - returns = dict - - def call(self, auth, site_id_or_name_list = None): - # Get site information - sites = Sites(self.api, site_id_or_name_list) - if not sites: - raise PLCInvalidArgument, "No such site" - - # Convert to {str(site_id): [node_id]} - site_nodes = {} - for site in sites: - site_nodes[str(site['site_id'])] = site['node_ids'] - - return site_nodes diff --git a/PLC/Methods/AdmGetSitePIs.py b/PLC/Methods/AdmGetSitePIs.py deleted file mode 100644 index d35ee88..0000000 --- a/PLC/Methods/AdmGetSitePIs.py +++ /dev/null @@ -1,44 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Sites import Site, Sites -from PLC.Persons import Person, Persons -from PLC.Auth import Auth - -class AdmGetSitePIs(Method): - """ - Deprecated. Functionality can be implemented with GetSites and - GetPersons. - - Return a list of person_ids of the PIs for the site specified. - """ - - status = "deprecated" - - roles = ['admin'] - - accepts = [ - Auth(), - Mixed(Site.fields['site_id'], - Site.fields['login_base']) - ] - - returns = Site.fields['person_ids'] - - def call(self, auth, site_id_or_login_base): - # Authenticated function - assert self.caller is not None - - # Get site information - sites = Sites(self.api, [site_id_or_login_base]) - if not sites: - raise PLCInvalidArgument, "No such site" - - site = sites[0] - - persons = Persons(self.api, site['person_ids']) - - has_pi_role = lambda person: 'pi' in person['roles'] - pis = filter(has_pi_role, persons) - - return [pi['person_id'] for pi in pis] diff --git a/PLC/Methods/AdmGetSitePersons.py b/PLC/Methods/AdmGetSitePersons.py deleted file mode 100644 index 8122528..0000000 --- a/PLC/Methods/AdmGetSitePersons.py +++ /dev/null @@ -1,44 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Sites import Site, Sites -from PLC.Auth import Auth - -class AdmGetSitePersons(Method): - """ - Deprecated. See GetSites. - - Return a list of person_ids for the site specified. - - PIs may only retrieve the person_ids of accounts at their - site. Admins may retrieve the person_ids of accounts at any site. - """ - - status = "deprecated" - - roles = ['admin', 'pi'] - - accepts = [ - Auth(), - Mixed(Site.fields['site_id'], - Site.fields['login_base']) - ] - - returns = Site.fields['person_ids'] - - def call(self, auth, site_id_or_login_base): - # Authenticated function - assert self.caller is not None - - # Get site information - sites = Sites(self.api, [site_id_or_login_base]) - if not sites: - raise PLCInvalidArgument, "No such site" - - site = sites[0] - - if 'admin' not in self.caller['roles']: - if site['site_id'] not in self.caller['site_ids']: - raise PLCPermissionDenied, "Not allowed to view accounts at that site" - - return site['person_ids'] diff --git a/PLC/Methods/AdmGetSitePowerControlUnits.py b/PLC/Methods/AdmGetSitePowerControlUnits.py deleted file mode 100644 index b95f298..0000000 --- a/PLC/Methods/AdmGetSitePowerControlUnits.py +++ /dev/null @@ -1,35 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.PCUs import PCU, PCUs -from PLC.Sites import Site, Sites -from PLC.Auth import Auth - -class AdmGetSitePowerControlUnits(Method): - """ - Deprecated. Functionality can be implemented with GetSites and GetPCUs. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'tech'] - - accepts = [ - Auth(), - Mixed(Site.fields['site_id'], - Site.fields['login_base']) - ] - - returns = [PCU.fields] - - def call(self, auth, site_id_or_login_base): - sites = Sites(self.api, [site_id_or_login_base]) - if not sites: - raise PLCInvalidArgument, "No such site" - site = sites[0] - - if 'admin' not in self.caller['roles']: - if site['site_id'] not in self.caller['site_ids']: - raise PLCPermissionDenied, "Not allowed to view the PCUs at that site" - - return PCUs(self.api, site['pcu_ids']) diff --git a/PLC/Methods/AdmGetSiteTechContacts.py b/PLC/Methods/AdmGetSiteTechContacts.py deleted file mode 100644 index f531db5..0000000 --- a/PLC/Methods/AdmGetSiteTechContacts.py +++ /dev/null @@ -1,45 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Sites import Site, Sites -from PLC.Persons import Person, Persons -from PLC.Auth import Auth - -class AdmGetSiteTechContacts(Method): - """ - Deprecated. Functionality can be implemented with GetSites and - GetPersons. - - Return a list of person_ids of the technical contacts for the site - specified. - """ - - status = "deprecated" - - roles = ['admin'] - - accepts = [ - Auth(), - Mixed(Site.fields['site_id'], - Site.fields['login_base']) - ] - - returns = Site.fields['person_ids'] - - def call(self, auth, site_id_or_login_base): - # Authenticated function - assert self.caller is not None - - # Get site information - sites = Sites(self.api, [site_id_or_login_base]) - if not sites: - raise PLCInvalidArgument, "No such site" - - site = sites[0] - - persons = Persons(self.api, site['person_ids']) - - has_tech_role = lambda person: 'tech' in person['roles'] - techs = filter(has_tech_role, persons) - - return [tech['person_id'] for tech in techs] diff --git a/PLC/Methods/AdmGetSites.py b/PLC/Methods/AdmGetSites.py deleted file mode 100644 index cf5b0cd..0000000 --- a/PLC/Methods/AdmGetSites.py +++ /dev/null @@ -1,11 +0,0 @@ -from PLC.Methods.GetSites import GetSites - -class AdmGetSites(GetSites): - """ - Deprecated. See GetSites. - """ - - status = "deprecated" - - def call(self, auth, site_id_or_login_base_list = None, return_fields = None): - return GetSites.call(self, auth, site_id_or_login_base_list) diff --git a/PLC/Methods/AdmGrantRoleToPerson.py b/PLC/Methods/AdmGrantRoleToPerson.py deleted file mode 100644 index 36e2e25..0000000 --- a/PLC/Methods/AdmGrantRoleToPerson.py +++ /dev/null @@ -1,11 +0,0 @@ -from PLC.Methods.AddRoleToPerson import AddRoleToPerson - -class AdmGrantRoleToPerson(AddRoleToPerson): - """ - Deprecated. See AddRoleToPerson. - """ - - status = "deprecated" - - def call(self, auth, person_id_or_email, role_id_or_name): - return AddRoleToPerson.call(self, auth, role_id_or_name, person_id_or_email) diff --git a/PLC/Methods/AdmIsPersonInRole.py b/PLC/Methods/AdmIsPersonInRole.py deleted file mode 100644 index b32ab03..0000000 --- a/PLC/Methods/AdmIsPersonInRole.py +++ /dev/null @@ -1,67 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Persons import Person, Persons -from PLC.Auth import Auth -from PLC.Roles import Role, Roles - -class AdmIsPersonInRole(Method): - """ - Deprecated. Functionality can be implemented with GetPersons. - - Returns 1 if the specified account has the specified role, 0 - otherwise. This function differs from AdmGetPersonRoles() in that - any authorized user can call it. It is currently restricted to - verifying PI roles. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - Auth(), - Mixed(Person.fields['person_id'], - Person.fields['email']), - Mixed(Parameter(int, "Role identifier"), - Parameter(str, "Role name")) - ] - - returns = Parameter(int, "1 if account has role, 0 otherwise") - - def call(self, auth, person_id_or_email, role_id_or_name): - # This is a totally fucked up function. I have no idea why it - # exists or who calls it, but here is how it is supposed to - # work. - - # Only allow PI roles to be checked - roles = {} - for role in Roles(self.api): - roles[role['role_id']] = role['name'] - roles[role['name']] = role['role_id'] - - if role_id_or_name not in roles: - raise PLCInvalidArgument, "Invalid role identifier or name" - - if isinstance(role_id_or_name, int): - role_id = role_id_or_name - else: - role_id = roles[role_id_or_name] - - if roles[role_id] != "pi": - raise PLCInvalidArgument, "Only the PI role may be checked" - - # Get account information - persons = Persons(self.api, [person_id_or_email]) - - # Rather than raise an error, and indicate whether or not - # the person is real, return 0. - if not persons: - return 0 - - person = persons[0] - - if role_id in person['role_ids']: - return 1 - - return 0 diff --git a/PLC/Methods/AdmQueryConfFile.py b/PLC/Methods/AdmQueryConfFile.py deleted file mode 100644 index 6cf5d99..0000000 --- a/PLC/Methods/AdmQueryConfFile.py +++ /dev/null @@ -1,35 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Nodes import Node, Nodes -from PLC.ConfFiles import ConfFile, ConfFiles -from PLC.Auth import Auth - -class AdmQueryConfFile(Method): - """ - Deprecated. See GetConfFiles. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - Auth(), - {'node_id': Node.fields['node_id']} - ] - - returns = [ConfFile.fields['conf_file_id']] - - def call(self, auth, search_vals): - if 'node_id' in search_vals: - conf_files = ConfFiles(self.api) - - conf_files = filter(lambda conf_file: \ - search_vals['node_id'] in conf_file['node_ids'], - conf_files) - - if conf_files: - return [conf_file['conf_file_id'] for conf_file in conf_files] - - return [] diff --git a/PLC/Methods/AdmQueryNode.py b/PLC/Methods/AdmQueryNode.py deleted file mode 100644 index f41d04f..0000000 --- a/PLC/Methods/AdmQueryNode.py +++ /dev/null @@ -1,67 +0,0 @@ -import socket - -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks, valid_ip -from PLC.Auth import Auth - -class AdmQueryNode(Method): - """ - Deprecated. Functionality can be implemented with GetNodes and - GetNodeNetworks. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - Auth(), - {'node_hostname': Node.fields['hostname'], - 'nodenetwork_ip': NodeNetwork.fields['ip'], - 'nodenetwork_mac': NodeNetwork.fields['mac'], - 'nodenetwork_method': NodeNetwork.fields['method']} - ] - - returns = [Node.fields['node_id']] - - def call(self, auth, search_vals): - # Get possible nodenetworks - if 'node_hostname' in search_vals: - nodes = Nodes(self.api, [search_vals['node_hostname']]) - if not nodes: - return [] - - # No network interface filters specified - if 'nodenetwork_ip' not in search_vals and \ - 'nodenetwork_mac' not in search_vals and \ - 'nodenetwork_method' not in search_vals: - return [nodes[0]['node_id']] - - if nodes[0]['nodenetwork_ids']: - nodenetworks = NodeNetworks(self.api, nodes[0]['nodenetwork_ids']) - else: - nodenetworks = [] - else: - nodenetworks = NodeNetworks(self.api) - - if 'nodenetwork_ip' in search_vals: - if not valid_ip(search_vals['nodenetwork_ip']): - raise PLCInvalidArgument, "Invalid IP address" - nodenetworks = filter(lambda nodenetwork: \ - socket.inet_aton(nodenetwork['ip']) == socket.inet_aton(search_vals['nodenetwork_ip']), - nodenetworks) - - if 'nodenetwork_mac' in search_vals: - nodenetworks = filter(lambda nodenetwork: \ - nodenetwork['mac'].lower() == search_vals['nodenetwork_mac'].lower(), - nodenetworks) - - if 'nodenetwork_method' in search_vals: - nodenetworks = filter(lambda nodenetwork: \ - nodenetwork['method'].lower() == search_vals['nodenetwork_method'].lower(), - nodenetworks) - - return [nodenetwork['node_id'] for nodenetwork in nodenetworks] diff --git a/PLC/Methods/AdmQueryPerson.py b/PLC/Methods/AdmQueryPerson.py deleted file mode 100644 index b41d0a5..0000000 --- a/PLC/Methods/AdmQueryPerson.py +++ /dev/null @@ -1,29 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Persons import Person, Persons -from PLC.Auth import Auth - -class AdmQueryPerson(Method): - """ - Deprecated. See GetPersons. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - Auth(), - {'email': Person.fields['email']} - ] - - returns = [Person.fields['person_id']] - - def call(self, auth, search_vals): - if 'email' in search_vals: - persons = Persons(self.api, [search_vals['email']]) - if persons: - return [persons[0]['person_id']] - - return [] diff --git a/PLC/Methods/AdmQueryPowerControlUnit.py b/PLC/Methods/AdmQueryPowerControlUnit.py deleted file mode 100644 index 8fc2f42..0000000 --- a/PLC/Methods/AdmQueryPowerControlUnit.py +++ /dev/null @@ -1,59 +0,0 @@ -import socket - -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.PCUs import PCU, PCUs -from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks, valid_ip -from PLC.Auth import Auth - -class AdmQueryPowerControlUnit(Method): - """ - Deprecated. Functionality can be implemented with GetPCUs or - GetNodes. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - Auth(), - {'pcu_hostname': PCU.fields['hostname'], - 'pcu_ip': PCU.fields['ip'], - 'node_hostname': Node.fields['hostname'], - 'node_id': Node.fields['node_id']} - ] - - returns = [PCU.fields['pcu_id']] - - def call(self, auth, search_vals): - # Get all PCUs. This is a stupid function. The API should not - # be used for DB mining. - pcus = PCUs(self.api) - - if 'pcu_hostname' in search_vals: - pcus = filter(lambda pcu: \ - pcu['hostname'].lower() == search_vals['pcu_hostname'].lower(), - pcus) - - if 'pcu_ip' in search_vals: - if not valid_ip(search_vals['pcu_ip']): - raise PLCInvalidArgument, "Invalid IP address" - pcus = filter(lambda pcu: \ - socket.inet_aton(pcu['ip']) == socket.inet_aton(search_vals['pcu_ip']), - pcus) - - if 'node_id' in search_vals: - pcus = filter(lambda pcu: \ - search_vals['node_id'] in pcu['node_ids'], - pcus) - - if 'node_hostname' in search_vals: - pcus = filter(lambda pcu: \ - search_vals['node_hostname'] in \ - [node['hostname'] for node in Nodes(self.api, pcu['node_ids'])], - pcus) - - return [pcu['pcu_id'] for pcu in pcus] diff --git a/PLC/Methods/AdmQuerySite.py b/PLC/Methods/AdmQuerySite.py deleted file mode 100644 index cad6b8c..0000000 --- a/PLC/Methods/AdmQuerySite.py +++ /dev/null @@ -1,87 +0,0 @@ -import socket - -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Sites import Site, Sites -from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks, valid_ip -from PLC.Auth import Auth - -class AdmQuerySite(Method): - """ - Deprecated. Functionality can be implemented with GetSites and - GetNodes. - """ - - status = "deprecated" - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - Auth(), - {'site_name': Site.fields['name'], - 'site_abbreviatedname': Site.fields['abbreviated_name'], - 'site_loginbase': Site.fields['login_base'], - 'node_hostname': Node.fields['hostname'], - 'node_id': Node.fields['node_id'], - 'nodenetwork_ip': NodeNetwork.fields['ip'], - 'nodenetwork_mac': NodeNetwork.fields['mac']} - ] - - returns = [Site.fields['site_id']] - - def call(self, auth, search_vals): - if 'site_loginbase' in search_vals: - sites = Sites(self.api, [search_vals['site_loginbase']]) - else: - sites = Sites(self.api) - - if 'site_name' in search_vals: - sites = filter(lambda site: \ - site['name'] == search_vals['site_name'], - sites) - - if 'site_abbreviatedname' in search_vals: - sites = filter(lambda site: \ - site['abbreviatedname'] == search_vals['site_abbreviatedname'], - sites) - - if 'node_id' in search_vals: - sites = filter(lambda site: \ - search_vals['node_id'] in site['node_ids'], - sites) - - if 'node_hostname' in search_vals or \ - 'nodenetwork_ip' in search_vals or \ - 'nodenetwork_mac' in search_vals: - for site in sites: - site['hostnames'] = [] - site['ips'] = [] - site['macs'] = [] - if site['node_ids']: - nodes = Nodes(self.api, site['node_ids']) - for node in nodes: - site['hostnames'].append(node['hostname']) - if 'nodenetwork_ip' in search_vals or \ - 'nodenetwork_mac' in search_vals: - nodenetworks = NodeNetworks(self.api, node['nodenetwork_ids']) - site['ips'] += [nodenetwork['ip'] for nodenetwork in nodenetworks] - site['macs'] += [nodenetwork['mac'] for nodenetwork in nodenetworks] - - if 'node_hostname' in search_vals: - sites = filter(lambda site: \ - search_vals['node_hostname'] in site['hostnames'], - sites) - - if 'nodenetwork_ip' in search_vals: - sites = filter(lambda site: \ - search_vals['nodenetwork_ip'] in site['ips'], - sites) - - if 'nodenetwork_mac' in search_vals: - sites = filter(lambda site: \ - search_vals['nodenetwork_mac'] in site['macs'], - sites) - - return [site['site_id'] for site in sites] diff --git a/PLC/Methods/AdmRebootNode.py b/PLC/Methods/AdmRebootNode.py deleted file mode 100644 index c8368e3..0000000 --- a/PLC/Methods/AdmRebootNode.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.RebootNode import RebootNode - -class AdmRebootNode(RebootNode): - """ - Deprecated. See RebootNode. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmRemoveNodeFromNodeGroup.py b/PLC/Methods/AdmRemoveNodeFromNodeGroup.py deleted file mode 100644 index f905a16..0000000 --- a/PLC/Methods/AdmRemoveNodeFromNodeGroup.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.DeleteNodeFromNodeGroup import DeleteNodeFromNodeGroup - -class AdmRemoveNodeFromNodeGroup(DeleteNodeFromNodeGroup): - """ - Deprecated. See DeleteNodeFromNodeGroup. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmRemovePersonFromSite.py b/PLC/Methods/AdmRemovePersonFromSite.py deleted file mode 100644 index 54d3f1d..0000000 --- a/PLC/Methods/AdmRemovePersonFromSite.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.DeletePersonFromSite import DeletePersonFromSite - -class AdmRemovePersonFromSite(DeletePersonFromSite): - """ - Deprecated. See DeletePersonFromSite. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmRevokeRoleFromPerson.py b/PLC/Methods/AdmRevokeRoleFromPerson.py deleted file mode 100644 index 2631a3a..0000000 --- a/PLC/Methods/AdmRevokeRoleFromPerson.py +++ /dev/null @@ -1,11 +0,0 @@ -from PLC.Methods.DeleteRoleFromPerson import DeleteRoleFromPerson - -class AdmRevokeRoleFromPerson(DeleteRoleFromPerson): - """ - Deprecated. See DeleteRoleFromPerson. - """ - - status = "deprecated" - - def call(self, auth, person_id_or_email, role_id_or_name): - return DeleteRoleFromPerson.call(self, auth, role_id_or_name, person_id_or_email) diff --git a/PLC/Methods/AdmSetPersonEnabled.py b/PLC/Methods/AdmSetPersonEnabled.py deleted file mode 100644 index 2009f00..0000000 --- a/PLC/Methods/AdmSetPersonEnabled.py +++ /dev/null @@ -1,23 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Persons import Person, Persons -from PLC.Auth import Auth -from PLC.Methods.UpdatePerson import UpdatePerson - -class AdmSetPersonEnabled(UpdatePerson): - """ - Deprecated. See UpdatePerson. - """ - - status = "deprecated" - - accepts = [ - Auth(), - Mixed(Person.fields['person_id'], - Person.fields['email']), - Person.fields['enabled'] - ] - - def call(self, auth, person_id_or_email, enabled): - return UpdatePerson.call(self, auth, person_id_or_email, {'enabled': enabled}) diff --git a/PLC/Methods/AdmSetPersonPrimarySite.py b/PLC/Methods/AdmSetPersonPrimarySite.py deleted file mode 100644 index c631a95..0000000 --- a/PLC/Methods/AdmSetPersonPrimarySite.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.SetPersonPrimarySite import SetPersonPrimarySite - -class AdmSetPersonPrimarySite(SetPersonPrimarySite): - """ - Deprecated. See SetPersonPrimarySite. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmUpdateNode.py b/PLC/Methods/AdmUpdateNode.py deleted file mode 100644 index ba4b3f1..0000000 --- a/PLC/Methods/AdmUpdateNode.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.UpdateNode import UpdateNode - -class AdmUpdateNode(UpdateNode): - """ - Deprecated. See UpdateNode. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmUpdateNodeGroup.py b/PLC/Methods/AdmUpdateNodeGroup.py deleted file mode 100644 index b53198a..0000000 --- a/PLC/Methods/AdmUpdateNodeGroup.py +++ /dev/null @@ -1,27 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.NodeGroups import NodeGroup, NodeGroups -from PLC.Auth import Auth -from PLC.Methods.UpdateNodeGroup import UpdateNodeGroup - -class AdmUpdateNodeGroup(UpdateNodeGroup): - """ - Deprecated. See UpdateNodeGroup. - """ - - status = "deprecated" - - accepts = [ - Auth(), - Mixed(NodeGroup.fields['nodegroup_id'], - NodeGroup.fields['name']), - NodeGroup.fields['name'], - NodeGroup.fields['description'] - ] - - returns = Parameter(int, '1 if successful') - - def call(self, auth, nodegroup_id_or_name, name, description): - return UpdateNodeGroup.call(self, auth, nodegroup_id_or_name, - {'name': name, 'description': description}) diff --git a/PLC/Methods/AdmUpdateNodeNetwork.py b/PLC/Methods/AdmUpdateNodeNetwork.py deleted file mode 100644 index a85d62a..0000000 --- a/PLC/Methods/AdmUpdateNodeNetwork.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.UpdateNodeNetwork import UpdateNodeNetwork - -class AdmUpdateNodeNetwork(UpdateNodeNetwork): - """ - Deprecated. See UpdateNodeNetwork. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmUpdatePerson.py b/PLC/Methods/AdmUpdatePerson.py deleted file mode 100644 index 066fe6d..0000000 --- a/PLC/Methods/AdmUpdatePerson.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.UpdatePerson import UpdatePerson - -class AdmUpdatePerson(UpdatePerson): - """ - Deprecated. See UpdatePerson. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmUpdateSite.py b/PLC/Methods/AdmUpdateSite.py deleted file mode 100644 index 0b6c26a..0000000 --- a/PLC/Methods/AdmUpdateSite.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.UpdateSite import UpdateSite - -class AdmUpdateSite(UpdateSite): - """ - Deprecated. See UpdateSite. - """ - - status = "deprecated" diff --git a/PLC/Methods/AdmUpdateSitePowerControlUnit.py b/PLC/Methods/AdmUpdateSitePowerControlUnit.py deleted file mode 100644 index ed564fb..0000000 --- a/PLC/Methods/AdmUpdateSitePowerControlUnit.py +++ /dev/null @@ -1,8 +0,0 @@ -from PLC.Methods.UpdatePCU import UpdatePCU - -class AdmUpdateSitePowerControlUnit(UpdatePCU): - """ - Deprecated. See UpdatePCU. - """ - - status = "deprecated" diff --git a/PLC/Methods/AnonAdmGetNodeGroups.py b/PLC/Methods/AnonAdmGetNodeGroups.py deleted file mode 100644 index b223e1e..0000000 --- a/PLC/Methods/AnonAdmGetNodeGroups.py +++ /dev/null @@ -1,11 +0,0 @@ -from PLC.Methods.GetNodeGroups import GetNodeGroups - -class AnonAdmGetNodeGroups(GetNodeGroups): - """ - Deprecated. See GetNodeGroups. All fields are now always returned - """ - - status = "deprecated" - - def call(self, auth, nodegroup_id_or_name_list = None, return_fields = None): - return GetNodeGroups.call(self, auth, nodegroup_id_or_name_list) diff --git a/PLC/Methods/BootGetNodeDetails.py b/PLC/Methods/BootGetNodeDetails.py index 2f5056d..8f228bc 100644 --- a/PLC/Methods/BootGetNodeDetails.py +++ b/PLC/Methods/BootGetNodeDetails.py @@ -2,7 +2,7 @@ from PLC.Method import Method from PLC.Parameter import Parameter, Mixed from PLC.Auth import BootAuth from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks +from PLC.Interfaces import Interface, Interfaces from PLC.Sessions import Session, Sessions class BootGetNodeDetails(Method): @@ -19,7 +19,7 @@ class BootGetNodeDetails(Method): 'hostname': Node.fields['hostname'], 'boot_state': Node.fields['boot_state'], 'model': Node.fields['model'], - 'networks': [NodeNetwork.fields], + 'networks': [Interface.fields], 'session': Session.fields['session_id'], } @@ -38,8 +38,8 @@ class BootGetNodeDetails(Method): details['session'] = session['session_id'] - if self.caller['nodenetwork_ids']: - details['networks'] = NodeNetworks(self.api, self.caller['nodenetwork_ids']) + if self.caller['interface_ids']: + details['networks'] = Interfaces(self.api, self.caller['interface_ids']) # XXX Boot Manager cannot unmarshal None for network in details['networks']: for field in network: diff --git a/PLC/Methods/BootUpdateNode.py b/PLC/Methods/BootUpdateNode.py index 52381cb..530a24f 100644 --- a/PLC/Methods/BootUpdateNode.py +++ b/PLC/Methods/BootUpdateNode.py @@ -3,7 +3,7 @@ from PLC.Method import Method from PLC.Parameter import Parameter, Mixed from PLC.Auth import Auth, BootAuth, SessionAuth from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks +from PLC.Interfaces import Interface, Interfaces can_update = lambda (field, value): field in \ ['method', 'mac', 'gateway', 'network', @@ -19,12 +19,12 @@ class BootUpdateNode(Method): roles = ['node'] - nodenetwork_fields = dict(filter(can_update, NodeNetwork.fields.items())) + interface_fields = dict(filter(can_update, Interface.fields.items())) accepts = [ Mixed(BootAuth(), SessionAuth()), {'boot_state': Node.fields['boot_state'], - 'primary_network': nodenetwork_fields, + 'primary_network': interface_fields, 'ssh_host_key': Node.fields['ssh_rsa_key']} ] @@ -41,22 +41,22 @@ class BootUpdateNode(Method): if node_fields.has_key('primary_network'): primary_network = node_fields['primary_network'] - if 'nodenetwork_id' not in primary_network: + if 'interface_id' not in primary_network: raise PLCInvalidArgument, "Node network not specified" - if primary_network['nodenetwork_id'] not in self.caller['nodenetwork_ids']: + if primary_network['interface_id'] not in self.caller['interface_ids']: raise PLCInvalidArgument, "Node network not associated with calling node" - nodenetworks = NodeNetworks(self.api, [primary_network['nodenetwork_id']]) - if not nodenetworks: + interfaces = Interfaces(self.api, [primary_network['interface_id']]) + if not interfaces: raise PLCInvalidArgument, "No such node network" - nodenetwork = nodenetworks[0] + interface = interfaces[0] - if not nodenetwork['is_primary']: + if not interface['is_primary']: raise PLCInvalidArgument, "Not the primary node network on record" - nodenetwork_fields = dict(filter(can_update, primary_network.items())) - nodenetwork.update(nodenetwork_fields) - nodenetwork.sync(commit = False) + interface_fields = dict(filter(can_update, primary_network.items())) + interface.update(interface_fields) + interface.sync(commit = False) self.caller.sync(commit = True) self.message = "Node updated: %s" % ", ".join(node_fields.keys()) diff --git a/PLC/Methods/DeleteNodeNetwork.py b/PLC/Methods/DeleteInterface.py similarity index 69% rename from PLC/Methods/DeleteNodeNetwork.py rename to PLC/Methods/DeleteInterface.py index 4bdda21..046f1e0 100644 --- a/PLC/Methods/DeleteNodeNetwork.py +++ b/PLC/Methods/DeleteInterface.py @@ -3,9 +3,9 @@ from PLC.Method import Method from PLC.Parameter import Parameter, Mixed from PLC.Auth import Auth from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks +from PLC.Interfaces import Interface, Interfaces -class DeleteNodeNetwork(Method): +class DeleteInterface(Method): """ Deletes an existing node network interface. @@ -19,22 +19,22 @@ class DeleteNodeNetwork(Method): accepts = [ Auth(), - NodeNetwork.fields['nodenetwork_id'] + Interface.fields['interface_id'] ] returns = Parameter(int, '1 if successful') - def call(self, auth, nodenetwork_id): + def call(self, auth, interface_id): # Get node network information - nodenetworks = NodeNetworks(self.api, [nodenetwork_id]) - if not nodenetworks: + interfaces = Interfaces(self.api, [interface_id]) + if not interfaces: raise PLCInvalidArgument, "No such node network" - nodenetwork = nodenetworks[0] + interface = interfaces[0] # Get node information - nodes = Nodes(self.api, [nodenetwork['node_id']]) + nodes = Nodes(self.api, [interface['node_id']]) if not nodes: raise PLCInvalidArgument, "No such node" node = nodes[0] @@ -48,10 +48,10 @@ class DeleteNodeNetwork(Method): if node['site_id'] not in self.caller['site_ids']: raise PLCPermissionDenied, "Not allowed to delete this node network" - nodenetwork.delete() + interface.delete() # Logging variables - self.event_objects = {'NodeNetwork': [nodenetwork['nodenetwork_id']]} - self.message = "Node network %d deleted" % nodenetwork['nodenetwork_id'] + self.event_objects = {'Interface': [interface['interface_id']]} + self.message = "Node network %d deleted" % interface['interface_id'] return 1 diff --git a/PLC/Methods/DeleteInterfaceSetting.py b/PLC/Methods/DeleteInterfaceSetting.py new file mode 100644 index 0000000..eda18e3 --- /dev/null +++ b/PLC/Methods/DeleteInterfaceSetting.py @@ -0,0 +1,73 @@ +# +# Thierry Parmentelat - INRIA +# +# $Revision$ +# + +from PLC.Faults import * +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.Auth import Auth + +from PLC.InterfaceSettings import InterfaceSetting, InterfaceSettings +from PLC.Interfaces import Interface, Interfaces + +from PLC.Nodes import Node, Nodes +from PLC.Sites import Site, Sites + +class DeleteInterfaceSetting(Method): + """ + Deletes the specified interface setting + + Attributes may require the caller to have a particular role in order + to be deleted, depending on the related interface setting type. + Admins may delete attributes of any slice or sliver. + + Returns 1 if successful, faults otherwise. + """ + + roles = ['admin', 'pi', 'user'] + + accepts = [ + Auth(), + InterfaceSetting.fields['interface_setting_id'] + ] + + returns = Parameter(int, '1 if successful') + + object_type = 'Interface' + + + def call(self, auth, interface_setting_id): + interface_settings = InterfaceSettings(self.api, [interface_setting_id]) + if not interface_settings: + raise PLCInvalidArgument, "No such interface setting %r"%interface_setting_id + interface_setting = interface_settings[0] + + ### reproducing a check from UpdateSliceAttribute, looks dumb though + interfaces = Interfaces(self.api, [interface_setting['interface_id']]) + if not interfaces: + raise PLCInvalidArgument, "No such interface %r"%interface_setting['interface_id'] + interface = interfaces[0] + + assert interface_setting['interface_setting_id'] in interface['setting_ids'] + + # check permission : it not admin, is the user affiliated with the right site + if 'admin' not in self.caller['roles']: + # locate node + node = Nodes (self.api,[interface['node_id']])[0] + # locate site + site = Sites (self.api, [node['site_id']])[0] + # check caller is affiliated with this site + if self.caller['person_id'] not in site['person_ids']: + raise PLCPermissionDenied, "Not a member of the hosting site %s"%site['abbreviated_site'] + + required_min_role = interface_setting_type ['min_role_id'] + if required_min_role is not None and \ + min(self.caller['role_ids']) > required_min_role: + raise PLCPermissionDenied, "Not allowed to modify the specified interface setting, requires role %d",required_min_role + + interface_setting.delete() + self.object_ids = [interface_setting['interface_setting_id']] + + return 1 diff --git a/PLC/Methods/DeleteInterfaceSettingType.py b/PLC/Methods/DeleteInterfaceSettingType.py new file mode 100644 index 0000000..48af8cc --- /dev/null +++ b/PLC/Methods/DeleteInterfaceSettingType.py @@ -0,0 +1,39 @@ +# +# Thierry Parmentelat - INRIA +# +# $Revision$ +# +from PLC.Faults import * +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.InterfaceSettingTypes import InterfaceSettingType, InterfaceSettingTypes +from PLC.Auth import Auth + +class DeleteInterfaceSettingType(Method): + """ + Deletes the specified interface setting type. + + Returns 1 if successful, faults otherwise. + """ + + roles = ['admin'] + + accepts = [ + Auth(), + Mixed(InterfaceSettingType.fields['interface_setting_type_id'], + InterfaceSettingType.fields['name']), + ] + + returns = Parameter(int, '1 if successful') + + + def call(self, auth, interface_setting_type_id_or_name): + interface_setting_types = InterfaceSettingTypes(self.api, [interface_setting_type_id_or_name]) + if not interface_setting_types: + raise PLCInvalidArgument, "No such interface setting type" + interface_setting_type = interface_setting_types[0] + + interface_setting_type.delete() + self.object_ids = [interface_setting_type['interface_setting_type_id']] + + return 1 diff --git a/PLC/Methods/DeleteNodeFromNodeGroup.py b/PLC/Methods/DeleteNodeFromNodeGroup.py deleted file mode 100644 index 2bc6770..0000000 --- a/PLC/Methods/DeleteNodeFromNodeGroup.py +++ /dev/null @@ -1,53 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.NodeGroups import NodeGroup, NodeGroups -from PLC.Nodes import Node, Nodes -from PLC.Auth import Auth - -class DeleteNodeFromNodeGroup(Method): - """ - Removes a node from the specified node group. - - Returns 1 if successful, faults otherwise. - """ - - roles = ['admin'] - - accepts = [ - Auth(), - Mixed(Node.fields['node_id'], - Node.fields['hostname']), - Mixed(NodeGroup.fields['nodegroup_id'], - NodeGroup.fields['name']), - ] - - returns = Parameter(int, '1 if successful') - - - def call(self, auth, node_id_or_hostname, nodegroup_id_or_name): - # Get node info - nodes = Nodes(self.api, [node_id_or_hostname]) - if not nodes: - raise PLCInvalidArgument, "No such node" - - node = nodes[0] - - # Get nodegroup info - nodegroups = NodeGroups(self.api, [nodegroup_id_or_name]) - if not nodegroups: - raise PLCInvalidArgument, "No such nodegroup" - - nodegroup = nodegroups[0] - - # Remove node from nodegroup - if node['node_id'] in nodegroup['node_ids']: - nodegroup.remove_node(node) - - # Logging variables - self.event_objects = {'NodeGroup': [nodegroup['nodegroup_id']], - 'Node': [node['node_id']]} - self.message = 'node %d deleted from node group %d' % \ - (node['node_id'], nodegroup['nodegroup_id']) - - return 1 diff --git a/PLC/Methods/DeleteNodeNetworkSetting.py b/PLC/Methods/DeleteNodeNetworkSetting.py deleted file mode 100644 index eae2112..0000000 --- a/PLC/Methods/DeleteNodeNetworkSetting.py +++ /dev/null @@ -1,73 +0,0 @@ -# -# Thierry Parmentelat - INRIA -# -# $Revision$ -# - -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Auth import Auth - -from PLC.NodeNetworkSettings import NodeNetworkSetting, NodeNetworkSettings -from PLC.NodeNetworks import NodeNetwork, NodeNetworks - -from PLC.Nodes import Node, Nodes -from PLC.Sites import Site, Sites - -class DeleteNodeNetworkSetting(Method): - """ - Deletes the specified nodenetwork setting - - Attributes may require the caller to have a particular role in order - to be deleted, depending on the related nodenetwork setting type. - Admins may delete attributes of any slice or sliver. - - Returns 1 if successful, faults otherwise. - """ - - roles = ['admin', 'pi', 'user'] - - accepts = [ - Auth(), - NodeNetworkSetting.fields['nodenetwork_setting_id'] - ] - - returns = Parameter(int, '1 if successful') - - object_type = 'NodeNetwork' - - - def call(self, auth, nodenetwork_setting_id): - nodenetwork_settings = NodeNetworkSettings(self.api, [nodenetwork_setting_id]) - if not nodenetwork_settings: - raise PLCInvalidArgument, "No such nodenetwork setting %r"%nodenetwork_setting_id - nodenetwork_setting = nodenetwork_settings[0] - - ### reproducing a check from UpdateSliceAttribute, looks dumb though - nodenetworks = NodeNetworks(self.api, [nodenetwork_setting['nodenetwork_id']]) - if not nodenetworks: - raise PLCInvalidArgument, "No such nodenetwork %r"%nodenetwork_setting['nodenetwork_id'] - nodenetwork = nodenetworks[0] - - assert nodenetwork_setting['nodenetwork_setting_id'] in nodenetwork['nodenetwork_setting_ids'] - - # check permission : it not admin, is the user affiliated with the right site - if 'admin' not in self.caller['roles']: - # locate node - node = Nodes (self.api,[nodenetwork['node_id']])[0] - # locate site - site = Sites (self.api, [node['site_id']])[0] - # check caller is affiliated with this site - if self.caller['person_id'] not in site['person_ids']: - raise PLCPermissionDenied, "Not a member of the hosting site %s"%site['abbreviated_site'] - - required_min_role = nodenetwork_setting_type ['min_role_id'] - if required_min_role is not None and \ - min(self.caller['role_ids']) > required_min_role: - raise PLCPermissionDenied, "Not allowed to modify the specified nodenetwork setting, requires role %d",required_min_role - - nodenetwork_setting.delete() - self.object_ids = [nodenetwork_setting['nodenetwork_setting_id']] - - return 1 diff --git a/PLC/Methods/DeleteNodeNetworkSettingType.py b/PLC/Methods/DeleteNodeNetworkSettingType.py deleted file mode 100644 index 0ab1219..0000000 --- a/PLC/Methods/DeleteNodeNetworkSettingType.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# Thierry Parmentelat - INRIA -# -# $Revision$ -# -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.NodeNetworkSettingTypes import NodeNetworkSettingType, NodeNetworkSettingTypes -from PLC.Auth import Auth - -class DeleteNodeNetworkSettingType(Method): - """ - Deletes the specified nodenetwork setting type. - - Returns 1 if successful, faults otherwise. - """ - - roles = ['admin'] - - accepts = [ - Auth(), - Mixed(NodeNetworkSettingType.fields['nodenetwork_setting_type_id'], - NodeNetworkSettingType.fields['name']), - ] - - returns = Parameter(int, '1 if successful') - - - def call(self, auth, nodenetwork_setting_type_id_or_name): - nodenetwork_setting_types = NodeNetworkSettingTypes(self.api, [nodenetwork_setting_type_id_or_name]) - if not nodenetwork_setting_types: - raise PLCInvalidArgument, "No such nodenetwork setting type" - nodenetwork_setting_type = nodenetwork_setting_types[0] - - nodenetwork_setting_type.delete() - self.object_ids = [nodenetwork_setting_type['nodenetwork_setting_type_id']] - - return 1 diff --git a/PLC/Methods/GenerateNodeConfFile.py b/PLC/Methods/GenerateNodeConfFile.py index 0b5cf8e..b993984 100644 --- a/PLC/Methods/GenerateNodeConfFile.py +++ b/PLC/Methods/GenerateNodeConfFile.py @@ -5,7 +5,7 @@ from PLC.Faults import * from PLC.Method import Method from PLC.Parameter import Parameter, Mixed from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks +from PLC.Interfaces import Interface, Interfaces from PLC.Auth import Auth class GenerateNodeConfFile(Method): @@ -49,10 +49,10 @@ class GenerateNodeConfFile(Method): # Get node networks for this node primary = None - nodenetworks = NodeNetworks(self.api, node['nodenetwork_ids']) - for nodenetwork in nodenetworks: - if nodenetwork['is_primary']: - primary = nodenetwork + interfaces = Interfaces(self.api, node['interface_ids']) + for interface in interfaces: + if interface['is_primary']: + primary = interface break if primary is None: raise PLCInvalidArgument, "No primary network configured" @@ -97,11 +97,11 @@ class GenerateNodeConfFile(Method): file += 'HOST_NAME="%s"\n' % host file += 'DOMAIN_NAME="%s"\n' % domain - for nodenetwork in nodenetworks: - if nodenetwork['method'] == 'ipmi': - file += 'IPMI_ADDRESS="%s"\n' % nodenetwork['ip'] - if nodenetwork['mac']: - file += 'IPMI_MAC="%s"\n' % nodenetwork['mac'].lower() + for interface in interfaces: + if interface['method'] == 'ipmi': + file += 'IPMI_ADDRESS="%s"\n' % interface['ip'] + if interface['mac']: + file += 'IPMI_MAC="%s"\n' % interface['mac'].lower() break return file diff --git a/PLC/Methods/GetBootMedium.py b/PLC/Methods/GetBootMedium.py index 0c62d14..e05f34b 100644 --- a/PLC/Methods/GetBootMedium.py +++ b/PLC/Methods/GetBootMedium.py @@ -10,8 +10,8 @@ from PLC.Parameter import Parameter, Mixed from PLC.Auth import Auth from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks -from PLC.NodeNetworkSettings import NodeNetworkSetting, NodeNetworkSettings +from PLC.Interfaces import Interface, Interfaces +from PLC.InterfaceSettings import InterfaceSetting, InterfaceSettings from PLC.NodeGroups import NodeGroup, NodeGroups # could not define this in the class.. @@ -153,10 +153,10 @@ class GetBootMedium(Method): # Get node networks for this node primary = None - nodenetworks = NodeNetworks(self.api, node['nodenetwork_ids']) - for nodenetwork in nodenetworks: - if nodenetwork['is_primary']: - primary = nodenetwork + interfaces = Interfaces(self.api, node['interface_ids']) + for interface in interfaces: + if interface['is_primary']: + primary = interface break if primary is None: raise PLCInvalidArgument, "No primary network configured on %s"%node['hostname'] @@ -192,8 +192,8 @@ class GetBootMedium(Method): file += 'HOST_NAME="%s"\n' % host file += 'DOMAIN_NAME="%s"\n' % domain - # define various nodenetwork settings attached to the primary nodenetwork - settings = NodeNetworkSettings (self.api, {'nodenetwork_id':nodenetwork['nodenetwork_id']}) + # define various interface settings attached to the primary interface + settings = InterfaceSettings (self.api, {'interface_id':interface['interface_id']}) categories = set() for setting in settings: @@ -201,18 +201,18 @@ class GetBootMedium(Method): categories.add(setting['category']) for category in categories: - category_settings = NodeNetworkSettings(self.api,{'nodenetwork_id':nodenetwork['nodenetwork_id'], + category_settings = InterfaceSettings(self.api,{'interface_id':interface['interface_id'], 'category':category}) if category_settings: file += '### Category : %s\n'%category for setting in category_settings: file += '%s_%s="%s"\n'%(category.upper(),setting['name'].upper(),setting['value']) - for nodenetwork in nodenetworks: - if nodenetwork['method'] == 'ipmi': - file += 'IPMI_ADDRESS="%s"\n' % nodenetwork['ip'] - if nodenetwork['mac']: - file += 'IPMI_MAC="%s"\n' % nodenetwork['mac'].lower() + for interface in interfaces: + if interface['method'] == 'ipmi': + file += 'IPMI_ADDRESS="%s"\n' % interface['ip'] + if interface['mac']: + file += 'IPMI_MAC="%s"\n' % interface['mac'].lower() break return file diff --git a/PLC/Methods/GetInterfaceSettingTypes.py b/PLC/Methods/GetInterfaceSettingTypes.py new file mode 100644 index 0000000..236d8ce --- /dev/null +++ b/PLC/Methods/GetInterfaceSettingTypes.py @@ -0,0 +1,33 @@ +# +# Thierry Parmentelat - INRIA +# +# $Revision$ +# +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.Filter import Filter +from PLC.Auth import Auth +from PLC.InterfaceSettingTypes import InterfaceSettingType, InterfaceSettingTypes + +class GetInterfaceSettingTypes(Method): + """ + Returns an array of structs containing details about + interface setting types. + + The usual filtering scheme applies on this method. + """ + + roles = ['admin', 'pi', 'user', 'tech', 'node'] + + accepts = [ + Auth(), + Mixed([Mixed(InterfaceSettingType.fields['interface_setting_type_id'], + InterfaceSettingType.fields['name'])], + Filter(InterfaceSettingType.fields)), + Parameter([str], "List of fields to return", nullok = True) + ] + + returns = [InterfaceSettingType.fields] + + def call(self, auth, interface_setting_type_filter = None, return_fields = None): + return InterfaceSettingTypes(self.api, interface_setting_type_filter, return_fields) diff --git a/PLC/Methods/GetInterfaceSettings.py b/PLC/Methods/GetInterfaceSettings.py new file mode 100644 index 0000000..779ef0c --- /dev/null +++ b/PLC/Methods/GetInterfaceSettings.py @@ -0,0 +1,45 @@ +# +# Thierry Parmentelat - INRIA +# +# $Revision$ +# +from PLC.Faults import * +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.Filter import Filter +from PLC.Persons import Person, Persons +from PLC.Auth import Auth + +from PLC.InterfaceSettings import InterfaceSetting, InterfaceSettings +from PLC.Sites import Site, Sites +from PLC.Interfaces import Interface, Interfaces + +class GetInterfaceSettings(Method): + """ + Returns an array of structs containing details about + interfaces and related settings. + + If interface_setting_filter is specified and is an array of + interface setting identifiers, only interface settings matching + the filter will be returned. If return_fields is specified, only + the specified details will be returned. + """ + + roles = ['admin', 'pi', 'user', 'node'] + + accepts = [ + Auth(), + Mixed([InterfaceSetting.fields['interface_setting_id']], + Parameter(int,"Interface setting id"), + Filter(InterfaceSetting.fields)), + Parameter([str], "List of fields to return", nullok = True) + ] + + returns = [InterfaceSetting.fields] + + + def call(self, auth, interface_setting_filter = None, return_fields = None): + + interface_settings = InterfaceSettings(self.api, interface_setting_filter, return_fields) + + return interface_settings diff --git a/PLC/Methods/GetNodeNetworks.py b/PLC/Methods/GetInterfaces.py similarity index 57% rename from PLC/Methods/GetNodeNetworks.py rename to PLC/Methods/GetInterfaces.py index 150f87d..2bd7f7c 100644 --- a/PLC/Methods/GetNodeNetworks.py +++ b/PLC/Methods/GetInterfaces.py @@ -2,13 +2,13 @@ from PLC.Faults import * from PLC.Method import Method from PLC.Parameter import Parameter, Mixed from PLC.Filter import Filter -from PLC.NodeNetworks import NodeNetwork, NodeNetworks +from PLC.Interfaces import Interface, Interfaces from PLC.Auth import Auth -class GetNodeNetworks(Method): +class GetInterfaces(Method): """ Returns an array of structs containing details about node network - interfacess. If nodenetworks_filter is specified and is an array + interfacess. If interfaces_filter is specified and is an array of node network identifiers, or a struct of node network fields and values, only node network interfaces matching the filter will be returned. @@ -20,13 +20,13 @@ class GetNodeNetworks(Method): accepts = [ Auth(), - Mixed([NodeNetwork.fields['nodenetwork_id']], - Parameter (int, "nodenetwork id"), - Filter(NodeNetwork.fields)), + Mixed([Interface.fields['interface_id']], + Parameter (int, "interface id"), + Filter(Interface.fields)), Parameter([str], "List of fields to return", nullok = True) ] - returns = [NodeNetwork.fields] + returns = [Interface.fields] - def call(self, auth, nodenetwork_filter = None, return_fields = None): - return NodeNetworks(self.api, nodenetwork_filter, return_fields) + def call(self, auth, interface_filter = None, return_fields = None): + return Interfaces(self.api, interface_filter, return_fields) diff --git a/PLC/Methods/GetNodeNetworkSettingTypes.py b/PLC/Methods/GetNodeNetworkSettingTypes.py deleted file mode 100644 index 10d7b39..0000000 --- a/PLC/Methods/GetNodeNetworkSettingTypes.py +++ /dev/null @@ -1,33 +0,0 @@ -# -# Thierry Parmentelat - INRIA -# -# $Revision$ -# -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Filter import Filter -from PLC.Auth import Auth -from PLC.NodeNetworkSettingTypes import NodeNetworkSettingType, NodeNetworkSettingTypes - -class GetNodeNetworkSettingTypes(Method): - """ - Returns an array of structs containing details about - nodenetwork setting types. - - The usual filtering scheme applies on this method. - """ - - roles = ['admin', 'pi', 'user', 'tech', 'node'] - - accepts = [ - Auth(), - Mixed([Mixed(NodeNetworkSettingType.fields['nodenetwork_setting_type_id'], - NodeNetworkSettingType.fields['name'])], - Filter(NodeNetworkSettingType.fields)), - Parameter([str], "List of fields to return", nullok = True) - ] - - returns = [NodeNetworkSettingType.fields] - - def call(self, auth, nodenetwork_setting_type_filter = None, return_fields = None): - return NodeNetworkSettingTypes(self.api, nodenetwork_setting_type_filter, return_fields) diff --git a/PLC/Methods/GetNodeNetworkSettings.py b/PLC/Methods/GetNodeNetworkSettings.py deleted file mode 100644 index 42359ce..0000000 --- a/PLC/Methods/GetNodeNetworkSettings.py +++ /dev/null @@ -1,45 +0,0 @@ -# -# Thierry Parmentelat - INRIA -# -# $Revision$ -# -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Filter import Filter -from PLC.Persons import Person, Persons -from PLC.Auth import Auth - -from PLC.NodeNetworkSettings import NodeNetworkSetting, NodeNetworkSettings -from PLC.Sites import Site, Sites -from PLC.NodeNetworks import NodeNetwork, NodeNetworks - -class GetNodeNetworkSettings(Method): - """ - Returns an array of structs containing details about - nodenetworks and related settings. - - If nodenetwork_setting_filter is specified and is an array of - nodenetwork setting identifiers, only nodenetwork settings matching - the filter will be returned. If return_fields is specified, only - the specified details will be returned. - """ - - roles = ['admin', 'pi', 'user', 'node'] - - accepts = [ - Auth(), - Mixed([NodeNetworkSetting.fields['nodenetwork_setting_id']], - Parameter(int,"Nodenetwork setting id"), - Filter(NodeNetworkSetting.fields)), - Parameter([str], "List of fields to return", nullok = True) - ] - - returns = [NodeNetworkSetting.fields] - - - def call(self, auth, nodenetwork_setting_filter = None, return_fields = None): - - nodenetwork_settings = NodeNetworkSettings(self.api, nodenetwork_setting_filter, return_fields) - - return nodenetwork_settings diff --git a/PLC/Methods/GetSlivers.py b/PLC/Methods/GetSlivers.py index e23e5fc..5624c0c 100644 --- a/PLC/Methods/GetSlivers.py +++ b/PLC/Methods/GetSlivers.py @@ -6,7 +6,7 @@ from PLC.Parameter import Parameter, Mixed from PLC.Filter import Filter from PLC.Auth import Auth from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks +from PLC.Interfaces import Interface, Interfaces from PLC.NodeGroups import NodeGroup, NodeGroups from PLC.ConfFiles import ConfFile, ConfFiles from PLC.Slices import Slice, Slices @@ -110,7 +110,7 @@ class GetSlivers(Method): node. All of the information returned by this call can be gathered from - other calls, e.g. GetNodes, GetNodeNetworks, GetSlices, etc. This + other calls, e.g. GetNodes, GetInterfaces, GetSlices, etc. This function exists almost solely for the benefit of Node Manager. """ @@ -126,7 +126,7 @@ class GetSlivers(Method): 'timestamp': Parameter(int, "Timestamp of this call, in seconds since UNIX epoch"), 'node_id': Node.fields['node_id'], 'hostname': Node.fields['hostname'], - 'networks': [NodeNetwork.fields], + 'networks': [Interface.fields], 'groups': [NodeGroup.fields['name']], 'conf_files': [ConfFile.fields], 'initscripts': [InitScript.fields], @@ -164,8 +164,8 @@ class GetSlivers(Method): if node['peer_id'] is not None: raise PLCInvalidArgument, "Not a local node" - # Get nodenetwork information - networks = NodeNetworks(self.api, node['nodenetwork_ids']) + # Get interface information + networks = Interfaces(self.api, node['interface_ids']) # Get node group information nodegroups = NodeGroups(self.api, node['nodegroup_ids']).dict('name') diff --git a/PLC/Methods/RebootNode.py b/PLC/Methods/RebootNode.py index bea6b89..7efefd2 100644 --- a/PLC/Methods/RebootNode.py +++ b/PLC/Methods/RebootNode.py @@ -4,7 +4,7 @@ from PLC.Faults import * from PLC.Method import Method from PLC.Parameter import Parameter, Mixed from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks +from PLC.Interfaces import Interface, Interfaces from PLC.Auth import Auth from PLC.POD import udp_pod @@ -55,10 +55,10 @@ class RebootNode(Method): # Only use the hostname as a backup, try to use the primary ID # address instead. host = node['hostname'] - nodenetworks = NodeNetworks(self.api, node['nodenetwork_ids']) - for nodenetwork in nodenetworks: - if nodenetwork['is_primary'] == 1: - host = nodenetwork['ip'] + interfaces = Interfaces(self.api, node['interface_ids']) + for interface in interfaces: + if interface['is_primary'] == 1: + host = interface['ip'] break try: diff --git a/PLC/Methods/UpdateNodeNetwork.py b/PLC/Methods/UpdateInterface.py similarity index 62% rename from PLC/Methods/UpdateNodeNetwork.py rename to PLC/Methods/UpdateInterface.py index dc1e65a..c13680b 100644 --- a/PLC/Methods/UpdateNodeNetwork.py +++ b/PLC/Methods/UpdateInterface.py @@ -2,19 +2,19 @@ from PLC.Faults import * from PLC.Method import Method from PLC.Parameter import Parameter, Mixed from PLC.Nodes import Node, Nodes -from PLC.NodeNetworks import NodeNetwork, NodeNetworks +from PLC.Interfaces import Interface, Interfaces from PLC.Auth import Auth can_update = lambda (field, value): field not in \ - ['nodenetwork_id','node_id'] + ['interface_id','node_id'] -class UpdateNodeNetwork(Method): +class UpdateInterface(Method): """ Updates an existing node network. Any values specified in - nodenetwork_fields are used, otherwise defaults are + interface_fields are used, otherwise defaults are used. Acceptable values for method are dhcp and static. If type is static, then ip, gateway, network, broadcast, netmask, and dns1 - must all be specified in nodenetwork_fields. If type is dhcp, + must all be specified in interface_fields. If type is dhcp, these parameters, even if specified, are ignored. PIs and techs may only update networks associated with their own @@ -25,25 +25,25 @@ class UpdateNodeNetwork(Method): roles = ['admin', 'pi', 'tech'] - nodenetwork_fields = dict(filter(can_update, NodeNetwork.fields.items())) + interface_fields = dict(filter(can_update, Interface.fields.items())) accepts = [ Auth(), - NodeNetwork.fields['nodenetwork_id'], - nodenetwork_fields + Interface.fields['interface_id'], + interface_fields ] returns = Parameter(int, '1 if successful') - def call(self, auth, nodenetwork_id, nodenetwork_fields): - nodenetwork_fields = dict(filter(can_update, nodenetwork_fields.items())) + def call(self, auth, interface_id, interface_fields): + interface_fields = dict(filter(can_update, interface_fields.items())) # Get node network information - nodenetworks = NodeNetworks(self.api, [nodenetwork_id]) - if not nodenetworks: + interfaces = Interfaces(self.api, [interface_id]) + if not interfaces: raise PLCInvalidArgument, "No such node network" - nodenetwork = nodenetworks[0] + interface = interfaces[0] # Authenticated function assert self.caller is not None @@ -51,7 +51,7 @@ class UpdateNodeNetwork(Method): # If we are not an admin, make sure that the caller is a # member of the site where the node exists. if 'admin' not in self.caller['roles']: - nodes = Nodes(self.api, [nodenetwork['node_id']]) + nodes = Nodes(self.api, [interface['node_id']]) if not nodes: raise PLCPermissionDenied, "Node network is not associated with a node" node = nodes[0] @@ -59,11 +59,11 @@ class UpdateNodeNetwork(Method): raise PLCPermissionDenied, "Not allowed to update node network" # Update node network - nodenetwork.update(nodenetwork_fields) - nodenetwork.sync() + interface.update(interface_fields) + interface.sync() - self.event_objects = {'NodeNetwork': [nodenetwork['nodenetwork_id']]} + self.event_objects = {'Interface': [interface['interface_id']]} self.message = "Node network %d updated: %s " % \ - (nodenetwork['nodenetwork_id'], ", ".join(nodenetwork_fields.keys())) + (interface['interface_id'], ", ".join(interface_fields.keys())) return 1 diff --git a/PLC/Methods/UpdateInterfaceSetting.py b/PLC/Methods/UpdateInterfaceSetting.py new file mode 100644 index 0000000..cfefafc --- /dev/null +++ b/PLC/Methods/UpdateInterfaceSetting.py @@ -0,0 +1,72 @@ +# +# Thierry Parmentelat - INRIA +# +# $Revision$ +# + +from PLC.Faults import * +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.Auth import Auth + +from PLC.InterfaceSettings import InterfaceSetting, InterfaceSettings +from PLC.Interfaces import Interface, Interfaces + +from PLC.Nodes import Nodes +from PLC.Sites import Sites + +class UpdateInterfaceSetting(Method): + """ + Updates the value of an existing interface setting + + Access rights depend on the interface setting type. + + Returns 1 if successful, faults otherwise. + """ + + roles = ['admin', 'pi', 'tech', 'user'] + + accepts = [ + Auth(), + InterfaceSetting.fields['interface_setting_id'], + InterfaceSetting.fields['value'] + ] + + returns = Parameter(int, '1 if successful') + + object_type = 'Interface' + + def call(self, auth, interface_setting_id, value): + interface_settings = InterfaceSettings(self.api, [interface_setting_id]) + if not interface_settings: + raise PLCInvalidArgument, "No such interface setting %r"%interface_setting_id + interface_setting = interface_settings[0] + + ### reproducing a check from UpdateSliceAttribute, looks dumb though + interfaces = Interfaces(self.api, [interface_setting['interface_id']]) + if not interfaces: + raise PLCInvalidArgument, "No such interface %r"%interface_setting['interface_id'] + interface = interfaces[0] + + assert interface_setting['interface_setting_id'] in interface['setting_ids'] + + # check permission : it not admin, is the user affiliated with the right site + if 'admin' not in self.caller['roles']: + # locate node + node = Nodes (self.api,[interface['node_id']])[0] + # locate site + site = Sites (self.api, [node['site_id']])[0] + # check caller is affiliated with this site + if self.caller['person_id'] not in site['person_ids']: + raise PLCPermissionDenied, "Not a member of the hosting site %s"%site['abbreviated_site'] + + required_min_role = interface_setting_type ['min_role_id'] + if required_min_role is not None and \ + min(self.caller['role_ids']) > required_min_role: + raise PLCPermissionDenied, "Not allowed to modify the specified interface setting, requires role %d",required_min_role + + interface_setting['value'] = value + interface_setting.sync() + + self.object_ids = [interface_setting['interface_setting_id']] + return 1 diff --git a/PLC/Methods/UpdateInterfaceSettingType.py b/PLC/Methods/UpdateInterfaceSettingType.py new file mode 100644 index 0000000..b16a750 --- /dev/null +++ b/PLC/Methods/UpdateInterfaceSettingType.py @@ -0,0 +1,48 @@ +# +# Thierry Parmentelat - INRIA +# +# $Revision$ +# +from PLC.Faults import * +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.InterfaceSettingTypes import InterfaceSettingType, InterfaceSettingTypes +from PLC.Auth import Auth + +can_update = lambda (field, value): field in \ + ['name', 'description', 'category', 'min_role_id'] + +class UpdateInterfaceSettingType(Method): + """ + Updates the parameters of an existing setting type + with the values in interface_setting_type_fields. + + Returns 1 if successful, faults otherwise. + """ + + roles = ['admin'] + + interface_setting_type_fields = dict(filter(can_update, InterfaceSettingType.fields.items())) + + accepts = [ + Auth(), + Mixed(InterfaceSettingType.fields['interface_setting_type_id'], + InterfaceSettingType.fields['name']), + interface_setting_type_fields + ] + + returns = Parameter(int, '1 if successful') + + def call(self, auth, interface_setting_type_id_or_name, interface_setting_type_fields): + interface_setting_type_fields = dict(filter(can_update, interface_setting_type_fields.items())) + + interface_setting_types = InterfaceSettingTypes(self.api, [interface_setting_type_id_or_name]) + if not interface_setting_types: + raise PLCInvalidArgument, "No such setting type" + interface_setting_type = interface_setting_types[0] + + interface_setting_type.update(interface_setting_type_fields) + interface_setting_type.sync() + self.object_ids = [interface_setting_type['interface_setting_type_id']] + + return 1 diff --git a/PLC/Methods/UpdateNodeNetworkSetting.py b/PLC/Methods/UpdateNodeNetworkSetting.py deleted file mode 100644 index bd59879..0000000 --- a/PLC/Methods/UpdateNodeNetworkSetting.py +++ /dev/null @@ -1,72 +0,0 @@ -# -# Thierry Parmentelat - INRIA -# -# $Revision$ -# - -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Auth import Auth - -from PLC.NodeNetworkSettings import NodeNetworkSetting, NodeNetworkSettings -from PLC.NodeNetworks import NodeNetwork, NodeNetworks - -from PLC.Nodes import Nodes -from PLC.Sites import Sites - -class UpdateNodeNetworkSetting(Method): - """ - Updates the value of an existing nodenetwork setting - - Access rights depend on the nodenetwork setting type. - - Returns 1 if successful, faults otherwise. - """ - - roles = ['admin', 'pi', 'tech', 'user'] - - accepts = [ - Auth(), - NodeNetworkSetting.fields['nodenetwork_setting_id'], - NodeNetworkSetting.fields['value'] - ] - - returns = Parameter(int, '1 if successful') - - object_type = 'NodeNetwork' - - def call(self, auth, nodenetwork_setting_id, value): - nodenetwork_settings = NodeNetworkSettings(self.api, [nodenetwork_setting_id]) - if not nodenetwork_settings: - raise PLCInvalidArgument, "No such nodenetwork setting %r"%nodenetwork_setting_id - nodenetwork_setting = nodenetwork_settings[0] - - ### reproducing a check from UpdateSliceAttribute, looks dumb though - nodenetworks = NodeNetworks(self.api, [nodenetwork_setting['nodenetwork_id']]) - if not nodenetworks: - raise PLCInvalidArgument, "No such nodenetwork %r"%nodenetwork_setting['nodenetwork_id'] - nodenetwork = nodenetworks[0] - - assert nodenetwork_setting['nodenetwork_setting_id'] in nodenetwork['nodenetwork_setting_ids'] - - # check permission : it not admin, is the user affiliated with the right site - if 'admin' not in self.caller['roles']: - # locate node - node = Nodes (self.api,[nodenetwork['node_id']])[0] - # locate site - site = Sites (self.api, [node['site_id']])[0] - # check caller is affiliated with this site - if self.caller['person_id'] not in site['person_ids']: - raise PLCPermissionDenied, "Not a member of the hosting site %s"%site['abbreviated_site'] - - required_min_role = nodenetwork_setting_type ['min_role_id'] - if required_min_role is not None and \ - min(self.caller['role_ids']) > required_min_role: - raise PLCPermissionDenied, "Not allowed to modify the specified nodenetwork setting, requires role %d",required_min_role - - nodenetwork_setting['value'] = value - nodenetwork_setting.sync() - - self.object_ids = [nodenetwork_setting['nodenetwork_setting_id']] - return 1 diff --git a/PLC/Methods/UpdateNodeNetworkSettingType.py b/PLC/Methods/UpdateNodeNetworkSettingType.py deleted file mode 100644 index 5501c11..0000000 --- a/PLC/Methods/UpdateNodeNetworkSettingType.py +++ /dev/null @@ -1,48 +0,0 @@ -# -# Thierry Parmentelat - INRIA -# -# $Revision$ -# -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.NodeNetworkSettingTypes import NodeNetworkSettingType, NodeNetworkSettingTypes -from PLC.Auth import Auth - -can_update = lambda (field, value): field in \ - ['name', 'description', 'category', 'min_role_id'] - -class UpdateNodeNetworkSettingType(Method): - """ - Updates the parameters of an existing setting type - with the values in nodenetwork_setting_type_fields. - - Returns 1 if successful, faults otherwise. - """ - - roles = ['admin'] - - nodenetwork_setting_type_fields = dict(filter(can_update, NodeNetworkSettingType.fields.items())) - - accepts = [ - Auth(), - Mixed(NodeNetworkSettingType.fields['nodenetwork_setting_type_id'], - NodeNetworkSettingType.fields['name']), - nodenetwork_setting_type_fields - ] - - returns = Parameter(int, '1 if successful') - - def call(self, auth, nodenetwork_setting_type_id_or_name, nodenetwork_setting_type_fields): - nodenetwork_setting_type_fields = dict(filter(can_update, nodenetwork_setting_type_fields.items())) - - nodenetwork_setting_types = NodeNetworkSettingTypes(self.api, [nodenetwork_setting_type_id_or_name]) - if not nodenetwork_setting_types: - raise PLCInvalidArgument, "No such setting type" - nodenetwork_setting_type = nodenetwork_setting_types[0] - - nodenetwork_setting_type.update(nodenetwork_setting_type_fields) - nodenetwork_setting_type.sync() - self.object_ids = [nodenetwork_setting_type['nodenetwork_setting_type_id']] - - return 1 diff --git a/PLC/Methods/__init__.py b/PLC/Methods/__init__.py index 45c9228..86731b5 100644 --- a/PLC/Methods/__init__.py +++ b/PLC/Methods/__init__.py @@ -3,101 +3,38 @@ AddAddressType AddAddressTypeToAddress AddBootState AddConfFile -AddConfFileToNodeGroup AddConfFileToNode +AddConfFileToNodeGroup AddInitScript +AddInterface +AddInterfaceSetting +AddInterfaceSettingType AddKeyType AddMessage AddNetworkMethod AddNetworkType -AddNodeGroup -AddNodeNetwork -AddNodeNetworkSetting -AddNodeNetworkSettingType AddNode -AddNodeToNodeGroup +AddNodeGroup AddNodeToPCU -AddPCUProtocolType AddPCU +AddPCUProtocolType AddPCUType AddPeer -AddPersonKey AddPerson +AddPersonKey AddPersonToSite AddPersonToSlice AddRole AddRoleToPerson AddSession -AddSiteAddress AddSite +AddSiteAddress +AddSlice 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 @@ -105,64 +42,63 @@ BootGetNodeDetails BootNotifyOwners BootUpdateNode DeleteAddress -DeleteAddressTypeFromAddress DeleteAddressType +DeleteAddressTypeFromAddress DeleteBootState -DeleteConfFileFromNodeGroup -DeleteConfFileFromNode DeleteConfFile +DeleteConfFileFromNode +DeleteConfFileFromNodeGroup DeleteInitScript +DeleteInterface +DeleteInterfaceSetting +DeleteInterfaceSettingType DeleteKey DeleteKeyType DeleteMessage DeleteNetworkMethod DeleteNetworkType -DeleteNodeFromNodeGroup +DeleteNode DeleteNodeFromPCU DeleteNodeGroup -DeleteNodeNetwork -DeleteNodeNetworkSetting -DeleteNodeNetworkSettingType -DeleteNode -DeletePCUProtocolType DeletePCU +DeletePCUProtocolType DeletePCUType DeletePeer +DeletePerson DeletePersonFromSite DeletePersonFromSlice -DeletePerson -DeleteRoleFromPerson DeleteRole +DeleteRoleFromPerson DeleteSession DeleteSite +DeleteSlice DeleteSliceAttribute DeleteSliceAttributeType DeleteSliceFromNodes DeleteSliceFromNodesWhitelist DeleteSliceInstantiation -DeleteSlice GenerateNodeConfFile -GetAddresses GetAddressTypes +GetAddresses GetBootMedium GetBootStates GetConfFiles GetEventObjects GetEvents GetInitScripts -GetKeys +GetInterfaceSettingTypes +GetInterfaceSettings +GetInterfaces GetKeyTypes +GetKeys GetMessages GetNetworkMethods GetNetworkTypes GetNodeGroups -GetNodeNetworkSettings -GetNodeNetworkSettingTypes -GetNodeNetworks GetNodes GetPCUProtocolTypes -GetPCUs GetPCUTypes +GetPCUs GetPeerData GetPeerName GetPeers @@ -172,13 +108,13 @@ GetRoles GetSession GetSessions GetSites -GetSliceAttributes GetSliceAttributeTypes +GetSliceAttributes GetSliceInstantiations GetSliceKeys -GetSlicesMD5 -GetSlices GetSliceTicket +GetSlices +GetSlicesMD5 GetSlivers GetWhitelist NotifyPersons @@ -203,29 +139,29 @@ SliceUpdate SliceUserAdd SliceUserDel SliceUsersList -system.listMethods -system.methodHelp -system.methodSignature -system.multicall UpdateAddress UpdateAddressType UpdateConfFile UpdateInitScript +UpdateInterface +UpdateInterfaceSetting +UpdateInterfaceSettingType UpdateKey UpdateMessage -UpdateNodeGroup -UpdateNodeNetwork -UpdateNodeNetworkSetting -UpdateNodeNetworkSettingType UpdateNode -UpdatePCUProtocolType +UpdateNodeGroup UpdatePCU +UpdatePCUProtocolType UpdatePCUType UpdatePeer UpdatePerson UpdateSite +UpdateSlice UpdateSliceAttribute UpdateSliceAttributeType -UpdateSlice VerifyPerson +system.listMethods +system.methodHelp +system.methodSignature +system.multicall """.split() diff --git a/PLC/Methods/system/.cvsignore b/PLC/Methods/system/.cvsignore deleted file mode 100644 index 0d20b64..0000000 --- a/PLC/Methods/system/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/PLC/Methods/system/__init__.py b/PLC/Methods/system/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/PLC/NetworkMethods.py b/PLC/NetworkMethods.py index 41ccfab..7133fa4 100644 --- a/PLC/NetworkMethods.py +++ b/PLC/NetworkMethods.py @@ -19,7 +19,7 @@ class NetworkMethod(Row): table_name = 'network_methods' primary_key = 'method' - join_tables = ['nodenetworks'] + join_tables = ['interfaces'] fields = { 'method': Parameter(str, "Network method", max = 20), } diff --git a/PLC/NetworkTypes.py b/PLC/NetworkTypes.py index f3a032f..c4c8367 100644 --- a/PLC/NetworkTypes.py +++ b/PLC/NetworkTypes.py @@ -19,7 +19,7 @@ class NetworkType(Row): table_name = 'network_types' primary_key = 'type' - join_tables = ['nodenetworks'] + join_tables = ['interfaces'] fields = { 'type': Parameter(str, "Network type", max = 20), } diff --git a/PLC/NodeGroups.py b/PLC/NodeGroups.py index a2b19d7..fdc3ba9 100644 --- a/PLC/NodeGroups.py +++ b/PLC/NodeGroups.py @@ -29,14 +29,13 @@ class NodeGroup(Row): fields = { 'nodegroup_id': Parameter(int, "Node group identifier"), 'name': Parameter(str, "Node group name", max = 50), - 'description': Parameter(str, "Node group description", max = 200, nullok = True), - 'node_ids': Parameter([int], "List of nodes in this node group"), - 'conf_file_ids': Parameter([int], "List of configuration files specific to this node group"), + 'tag_name' : Parameter(str, "Tag name that the nodegroup definition is based upon"), + 'tag_value' : Parameter(str, "value that the nodegroup definition is based upon"), +# 'node_ids': Parameter([int], "List of nodes in this node group"), +# 'conf_file_ids': Parameter([int], "List of configuration files specific to this node group"), } related_fields = { 'conf_files': [Parameter(int, "ConfFile identifier")], - 'nodes': [Mixed(Parameter(int, "Node identifier"), - Parameter(str, "Fully qualified hostname"))] } def validate_name(self, name): @@ -52,86 +51,6 @@ class NodeGroup(Row): return name - def add_node(self, node, commit = True): - """ - Add node to existing nodegroup. - """ - - assert 'nodegroup_id' in self - assert isinstance(node, Node) - assert 'node_id' in node - - node_id = node['node_id'] - nodegroup_id = self['nodegroup_id'] - - if node_id not in self['node_ids']: - assert nodegroup_id not in node['nodegroup_ids'] - - self.api.db.do("INSERT INTO nodegroup_node (nodegroup_id, node_id)" \ - " VALUES(%(nodegroup_id)d, %(node_id)d)", - locals()) - - if commit: - self.api.db.commit() - - self['node_ids'].append(node_id) - node['nodegroup_ids'].append(nodegroup_id) - - def remove_node(self, node, commit = True): - """ - Remove node from existing nodegroup. - """ - - assert 'nodegroup_id' in self - assert isinstance(node, Node) - assert 'node_id' in node - - node_id = node['node_id'] - nodegroup_id = self['nodegroup_id'] - - if node_id in self['node_ids']: - assert nodegroup_id in node['nodegroup_ids'] - - self.api.db.do("DELETE FROM nodegroup_node" \ - " WHERE nodegroup_id = %(nodegroup_id)d" \ - " AND node_id = %(node_id)d", - locals()) - - if commit: - self.api.db.commit() - - self['node_ids'].remove(node_id) - node['nodegroup_ids'].remove(nodegroup_id) - - def associate_nodes(self, auth, field, value): - """ - Adds nodes found in value list to this nodegroup (using AddNodeToNodeGroup). - Deletes nodes not found in value list from this slice (using DeleteNodeFromNodeGroup). - """ - - assert 'node_ids' in self - assert 'nodegroup_id' in self - assert isinstance(value, list) - - (node_ids, hostnames) = self.separate_types(value)[0:2] - - # Translate hostnames into node_ids - if hostnames: - nodes = Nodes(self.api, hostnames, ['node_id']).dict('node_id') - node_ids += nodes.keys() - - # Add new ids, remove stale ids - if self['node_ids'] != node_ids: - from PLC.Methods.AddNodeToNodeGroup import AddNodeToNodeGroup - from PLC.Methods.DeleteNodeFromNodeGroup import DeleteNodeFromNodeGroup - new_nodes = set(node_ids).difference(self['node_ids']) - stale_nodes = set(self['node_ids']).difference(node_ids) - - for new_node in new_nodes: - AddNodeToNodeGroup.__call__(AddNodeToNodeGroup(self.api), auth, new_node, self['nodegroup_id']) - for stale_node in stale_nodes: - DeleteNodeFromNodeGroup.__call__(DeleteNodeFromNodeGroup(self.api), auth, stale_node, self['nodegroup_id']) - def associate_conf_files(self, auth, field, value): """ Add conf_files found in value list (AddConfFileToNodeGroup) diff --git a/PLC/NodeNetworkSettingTypes.py b/PLC/NodeNetworkSettingTypes.py deleted file mode 100644 index 20718dd..0000000 --- a/PLC/NodeNetworkSettingTypes.py +++ /dev/null @@ -1,83 +0,0 @@ -# -# Thierry Parmentelat - INRIA -# -# $Revision:$ -# -from types import StringTypes - -from PLC.Faults import * -from PLC.Parameter import Parameter -from PLC.Filter import Filter -from PLC.Table import Row, Table -from PLC.Roles import Role, Roles - -class NodeNetworkSettingType (Row): - - """ - Representation of a row in the nodenetwork_setting_types table. - """ - - table_name = 'nodenetwork_setting_types' - primary_key = 'nodenetwork_setting_type_id' - join_tables = ['nodenetwork_setting'] - fields = { - 'nodenetwork_setting_type_id': Parameter(int, "Nodenetwork setting type identifier"), - 'name': Parameter(str, "Nodenetwork setting type name", max = 100), - 'description': Parameter(str, "Nodenetwork setting type description", max = 254), - 'category' : Parameter (str, "Nodenetwork setting category", max=64), - 'min_role_id': Parameter(int, "Minimum (least powerful) role that can set or change this attribute"), - } - - # for Cache - class_key = 'name' - foreign_fields = ['category','description','min_role_id'] - foreign_xrefs = [] - - def validate_name(self, name): - if not len(name): - raise PLCInvalidArgument, "nodenetwork setting type name must be set" - - conflicts = NodeNetworkSettingTypes(self.api, [name]) - for setting_type in conflicts: - if 'nodenetwork_setting_type_id' not in self or \ - self['nodenetwork_setting_type_id'] != setting_type['nodenetwork_setting_type_id']: - raise PLCInvalidArgument, "nodenetwork setting type name already in use" - - return name - - def validate_min_role_id(self, role_id): - roles = [row['role_id'] for row in Roles(self.api)] - if role_id not in roles: - raise PLCInvalidArgument, "Invalid role" - - return role_id - -class NodeNetworkSettingTypes(Table): - """ - Representation of row(s) from the nodenetwork_setting_types table - in the database. - """ - - def __init__(self, api, nodenetwork_setting_type_filter = None, columns = None): - Table.__init__(self, api, NodeNetworkSettingType, columns) - - sql = "SELECT %s FROM nodenetwork_setting_types WHERE True" % \ - ", ".join(self.columns) - - if nodenetwork_setting_type_filter is not None: - if isinstance(nodenetwork_setting_type_filter, (list, tuple, set)): - # Separate the list into integers and strings - ints = filter(lambda x: isinstance(x, (int, long)), nodenetwork_setting_type_filter) - strs = filter(lambda x: isinstance(x, StringTypes), nodenetwork_setting_type_filter) - nodenetwork_setting_type_filter = Filter(NodeNetworkSettingType.fields, {'nodenetwork_setting_type_id': ints, 'name': strs}) - sql += " AND (%s) %s" % nodenetwork_setting_type_filter.sql(api, "OR") - elif isinstance(nodenetwork_setting_type_filter, dict): - nodenetwork_setting_type_filter = Filter(NodeNetworkSettingType.fields, nodenetwork_setting_type_filter) - sql += " AND (%s) %s" % nodenetwork_setting_type_filter.sql(api, "AND") - elif isinstance (nodenetwork_setting_type_filter, StringTypes): - nodenetwork_setting_type_filter = Filter(NodeNetworkSettingType.fields, {'name':[nodenetwork_setting_type_filter]}) - sql += " AND (%s) %s" % nodenetwork_setting_type_filter.sql(api, "AND") - else: - raise PLCInvalidArgument, "Wrong nodenetwork setting type filter %r"%nodenetwork_setting_type_filter - - self.selectall(sql) diff --git a/PLC/NodeNetworkSettings.py b/PLC/NodeNetworkSettings.py deleted file mode 100644 index c85bae5..0000000 --- a/PLC/NodeNetworkSettings.py +++ /dev/null @@ -1,57 +0,0 @@ -# -# Thierry Parmentelat - INRIA -# -# $Revision$ -# -from PLC.Faults import * -from PLC.Parameter import Parameter -from PLC.Filter import Filter -from PLC.Table import Row, Table -from PLC.NodeNetworkSettingTypes import NodeNetworkSettingType, NodeNetworkSettingTypes - -class NodeNetworkSetting(Row): - """ - Representation of a row in the nodenetwork_setting. - To use, instantiate with a dict of values. - """ - - table_name = 'nodenetwork_setting' - primary_key = 'nodenetwork_setting_id' - fields = { - 'nodenetwork_setting_id': Parameter(int, "Nodenetwork setting identifier"), - 'nodenetwork_id': Parameter(int, "NodeNetwork identifier"), - 'nodenetwork_setting_type_id': NodeNetworkSettingType.fields['nodenetwork_setting_type_id'], - 'name': NodeNetworkSettingType.fields['name'], - 'description': NodeNetworkSettingType.fields['description'], - 'category': NodeNetworkSettingType.fields['category'], - 'min_role_id': NodeNetworkSettingType.fields['min_role_id'], - 'value': Parameter(str, "Nodenetwork setting value"), - ### relations - - } - -class NodeNetworkSettings(Table): - """ - Representation of row(s) from the nodenetwork_setting table in the - database. - """ - - def __init__(self, api, nodenetwork_setting_filter = None, columns = None): - Table.__init__(self, api, NodeNetworkSetting, columns) - - sql = "SELECT %s FROM view_nodenetwork_settings WHERE True" % \ - ", ".join(self.columns) - - if nodenetwork_setting_filter is not None: - if isinstance(nodenetwork_setting_filter, (list, tuple, set)): - nodenetwork_setting_filter = Filter(NodeNetworkSetting.fields, {'nodenetwork_setting_id': nodenetwork_setting_filter}) - elif isinstance(nodenetwork_setting_filter, dict): - nodenetwork_setting_filter = Filter(NodeNetworkSetting.fields, nodenetwork_setting_filter) - elif isinstance(nodenetwork_setting_filter, int): - nodenetwork_setting_filter = Filter(NodeNetworkSetting.fields, {'nodenetwork_setting_id': [nodenetwork_setting_filter]}) - else: - raise PLCInvalidArgument, "Wrong nodenetwork setting filter %r"%nodenetwork_setting_filter - sql += " AND (%s) %s" % nodenetwork_setting_filter.sql(api) - - - self.selectall(sql) diff --git a/PLC/Nodes.py b/PLC/Nodes.py index 08612f6..01328e3 100644 --- a/PLC/Nodes.py +++ b/PLC/Nodes.py @@ -15,7 +15,7 @@ from PLC.Parameter import Parameter, Mixed from PLC.Filter import Filter from PLC.Debug import profile from PLC.Table import Row, Table -from PLC.NodeNetworks import NodeNetwork, NodeNetworks +from PLC.Interfaces import Interface, Interfaces from PLC.BootStates import BootStates def valid_hostname(hostname): @@ -38,7 +38,7 @@ class Node(Row): table_name = 'nodes' primary_key = 'node_id' - # Thierry -- we use delete on nodenetworks so the related NodeNetworkSettings get deleted too + # Thierry -- we use delete on interfaces so the related InterfaceSettings get deleted too join_tables = ['nodegroup_node', 'conf_file_node', 'pcu_node', 'slice_node', 'slice_attribute', 'node_session', 'peer_node','node_slice_whitelist'] fields = { 'node_id': Parameter(int, "Node identifier"), @@ -54,7 +54,7 @@ class Node(Row): 'last_contact': Parameter(int, "Date and time when node last contacted plc", ro = True), 'key': Parameter(str, "(Admin only) Node key", max = 256), 'session': Parameter(str, "(Admin only) Node session value", max = 256, ro = True), - 'nodenetwork_ids': Parameter([int], "List of network interfaces that this node has"), + 'interface_ids': Parameter([int], "List of network interfaces that this node has"), 'nodegroup_ids': Parameter([int], "List of node groups that this node is in"), '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"), @@ -64,10 +64,11 @@ class Node(Row): '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), 'peer_node_id': Parameter(int, "Foreign node identifier at peer", nullok = True), + 'tag_ids' : Parameter ([int], "List of tags attached to this node"), } related_fields = { - 'nodenetworks': [Mixed(Parameter(int, "NodeNetwork identifier"), - Filter(NodeNetwork.fields))], + 'interfaces': [Mixed(Parameter(int, "Interface identifier"), + Filter(Interface.fields))], 'nodegroups': [Mixed(Parameter(int, "NodeGroup identifier"), Parameter(str, "NodeGroup name"))], 'conf_files': [Parameter(int, "ConfFile identifier")], @@ -134,26 +135,26 @@ class Node(Row): " where node_id = %d" % (self['node_id']) ) self.sync(commit) - def associate_nodenetworks(self, auth, field, value): + def associate_interfaces(self, auth, field, value): """ - Delete nodenetworks not found in value list (using DeleteNodeNetwor)k - Add nodenetworks found in value list (using AddNodeNetwork) - Updates nodenetworks found w/ nodenetwork_id in value list (using UpdateNodeNetwork) + Delete interfaces not found in value list (using DeleteNodeNetwor)k + Add interfaces found in value list (using AddInterface) + Updates interfaces found w/ interface_id in value list (using UpdateInterface) """ - assert 'nodenetworkp_ids' in self + assert 'interfacep_ids' in self assert 'node_id' in self assert isinstance(value, list) - (nodenetwork_ids, blank, nodenetworks) = self.separate_types(value) + (interface_ids, blank, interfaces) = self.separate_types(value) - if self['nodenetwork_ids'] != nodenetwork_ids: - from PLC.Methods.DeleteNodeNetwork import DeleteNodeNetwork + if self['interface_ids'] != interface_ids: + from PLC.Methods.DeleteInterface import DeleteInterface - stale_nodenetworks = set(self['nodenetwork_ids']).difference(nodenetwork_ids) + stale_interfaces = set(self['interface_ids']).difference(interface_ids) - for stale_nodenetwork in stale_nodenetworks: - DeleteNodeNetwork.__call__(DeleteNodeNetwork(self.api), auth, stale_nodenetwork['nodenetwork_id']) + for stale_interface in stale_interfaces: + DeleteInterface.__call__(DeleteInterface(self.api), auth, stale_interface['interface_id']) def associate_nodegroups(self, auth, field, value): """ @@ -276,11 +277,11 @@ class Node(Row): """ assert 'node_id' in self - assert 'nodenetwork_ids' in self + assert 'interface_ids' in self - # we need to clean up NodeNetworkSettings, so handling nodenetworks as part of join_tables does not work - for nodenetwork in NodeNetworks(self.api,self['nodenetwork_ids']): - nodenetwork.delete() + # we need to clean up InterfaceSettings, so handling interfaces as part of join_tables does not work + for interface in Interfaces(self.api,self['interface_ids']): + interface.delete() # Clean up miscellaneous join tables for table in self.join_tables: diff --git a/PLC/PCUs.py b/PLC/PCUs.py index 563acf9..27a94ae 100644 --- a/PLC/PCUs.py +++ b/PLC/PCUs.py @@ -12,7 +12,7 @@ from PLC.Parameter import Parameter from PLC.Filter import Filter from PLC.Debug import profile from PLC.Table import Row, Table -from PLC.NodeNetworks import valid_ip, NodeNetwork, NodeNetworks +from PLC.Interfaces import valid_ip, Interface, Interfaces from PLC.Nodes import Node, Nodes class PCU(Row): diff --git a/PLC/Test.py b/PLC/Test.py index 05796a6..48e1618 100644 --- a/PLC/Test.py +++ b/PLC/Test.py @@ -149,8 +149,8 @@ def random_node(boot_states): 'version': randstr(64), } -def random_nodenetwork(method, type): - nodenetwork_fields = { +def random_interface(method, type): + interface_fields = { 'method': method, 'type': type, 'bwlimit': randint(500000, 10000000), @@ -165,9 +165,9 @@ def random_nodenetwork(method, type): dns1 = randint(0, 0xffffffff) for field in 'ip', 'netmask', 'network', 'broadcast', 'gateway', 'dns1': - nodenetwork_fields[field] = socket.inet_ntoa(struct.pack('>L', locals()[field])) + interface_fields[field] = socket.inet_ntoa(struct.pack('>L', locals()[field])) - return nodenetwork_fields + return interface_fields def random_pcu(): return { @@ -218,7 +218,7 @@ class Test: 'keys_per_person': 1, 'nodegroups': 1, 'nodes_per_site': 1, - 'nodenetworks_per_node': 1, + 'interfaces_per_node': 1, 'pcus_per_site': 1, 'conf_files': 1, 'attribute_types': 1, @@ -234,7 +234,7 @@ class Test: 'keys_per_person': 2, 'nodegroups': 10, 'nodes_per_site': 2, - 'nodenetworks_per_node': 1, + 'interfaces_per_node': 1, 'pcus_per_site': 1, 'conf_files': 10, 'attribute_types': 10, @@ -254,7 +254,7 @@ class Test: self.key_ids = [] self.nodegroup_ids = [] self.node_ids = [] - self.nodenetwork_ids = [] + self.interface_ids = [] self.pcu_ids = [] self.conf_file_ids = [] self.attribute_type_ids = [] @@ -298,7 +298,7 @@ class Test: self.AddKeys(params['keys_per_person']) self.AddNodeGroups(params['nodegroups']) self.AddNodes(params['nodes_per_site']) - self.AddNodeNetworks(params['nodenetworks_per_node']) + self.AddInterfaces(params['interfaces_per_node']) self.AddPCUs(params['pcus_per_site']) self.AddConfFiles(params['conf_files']) self.AddSliceAttributeTypes(params['attribute_types']) @@ -313,7 +313,7 @@ class Test: self.UpdateKeys() self.UpdateNodeGroups() self.UpdateNodes() - self.UpdateNodeNetworks() + self.UpdateInterfaces() self.UpdatePCUs() self.UpdateConfFiles() self.UpdateSliceAttributeTypes() @@ -327,7 +327,7 @@ class Test: self.DeleteKeys() self.DeleteConfFiles() self.DeletePCUs() - self.DeleteNodeNetworks() + self.DeleteInterfaces() self.DeleteNodes() self.DeletePersons() self.DeleteNodeGroups() @@ -927,7 +927,7 @@ class Test: self.node_ids = [] - def AddNodeNetworks(self, per_node = 1): + def AddInterfaces(self, per_node = 1): """ Add a number of random network interfaces to each node. """ @@ -946,23 +946,23 @@ class Test: type = random.sample(network_types, 1)[0] # Add node network - nodenetwork_fields = random_nodenetwork(method, type) - nodenetwork_id = self.api.AddNodeNetwork(node_id, nodenetwork_fields) + interface_fields = random_interface(method, type) + interface_id = self.api.AddInterface(node_id, interface_fields) - # Should return a unique nodenetwork_id - assert nodenetwork_id not in self.nodenetwork_ids - self.nodenetwork_ids.append(nodenetwork_id) + # Should return a unique interface_id + assert interface_id not in self.interface_ids + self.interface_ids.append(interface_id) if self.check: # Check node network - nodenetwork = self.api.GetNodeNetworks([nodenetwork_id])[0] - for field in nodenetwork_fields: - assert nodenetwork[field] == nodenetwork_fields[field] + interface = self.api.GetInterfaces([interface_id])[0] + for field in interface_fields: + assert interface[field] == interface_fields[field] if self.verbose: - print "Added node network", nodenetwork_id, "to node", node_id + print "Added node network", interface_id, "to node", node_id - def UpdateNodeNetworks(self): + def UpdateInterfaces(self): """ Make random changes to any network interfaces we may have added. """ @@ -975,41 +975,41 @@ class Test: if not network_types: raise Exception, "No network types" - for nodenetwork_id in self.nodenetwork_ids: + for interface_id in self.interface_ids: method = random.sample(network_methods, 1)[0] type = random.sample(network_types, 1)[0] - # Update nodenetwork - nodenetwork_fields = random_nodenetwork(method, type) - self.api.UpdateNodeNetwork(nodenetwork_id, nodenetwork_fields) + # Update interface + interface_fields = random_interface(method, type) + self.api.UpdateInterface(interface_id, interface_fields) if self.check: - # Check nodenetwork - nodenetwork = self.api.GetNodeNetworks([nodenetwork_id])[0] - for field in nodenetwork_fields: - assert nodenetwork[field] == nodenetwork_fields[field] + # Check interface + interface = self.api.GetInterfaces([interface_id])[0] + for field in interface_fields: + assert interface[field] == interface_fields[field] if self.verbose: - print "Updated node network", nodenetwork_id + print "Updated node network", interface_id - def DeleteNodeNetworks(self): + def DeleteInterfaces(self): """ Delete any random network interfaces we may have added. """ - for nodenetwork_id in self.nodenetwork_ids: - self.api.DeleteNodeNetwork(nodenetwork_id) + for interface_id in self.interface_ids: + self.api.DeleteInterface(interface_id) if self.check: - assert not self.api.GetNodeNetworks([nodenetwork_id]) + assert not self.api.GetInterfaces([interface_id]) if self.verbose: - print "Deleted node network", nodenetwork_id + print "Deleted node network", interface_id if self.check: - assert not self.api.GetNodeNetworks(self.nodenetwork_ids) + assert not self.api.GetInterfaces(self.interface_ids) - self.nodenetwork_ids = [] + self.interface_ids = [] def AddPCUs(self, per_site = 1): """ diff --git a/PLC/__init__.py b/PLC/__init__.py index d5ddda8..10f6edf 100644 --- a/PLC/__init__.py +++ b/PLC/__init__.py @@ -1,7 +1,7 @@ all = """ -Addresses -AddressTypes API +AddressTypes +Addresses Auth Boot BootStates @@ -14,35 +14,35 @@ Faults Filter GPG InitScripts -Keys +InterfaceSettingTypes +InterfaceSettings +Interfaces KeyTypes +Keys Messages Method NetworkMethods NetworkTypes NodeGroups -NodeNetworkSettings -NodeNetworkSettingTypes -NodeNetworks Nodes -Parameter PCUProtocolTypes -PCUs PCUTypes +PCUs +POD +Parameter Peers Persons -POD PostgreSQL PyCurl Roles -sendmail Sessions Shell Sites -SliceAttributes SliceAttributeTypes +SliceAttributes SliceInstantiations Slices Table Test +sendmail """.split() diff --git a/doc/PLCAPI.xml.in b/doc/PLCAPI.xml.in index ffc0057..f52353e 100644 --- a/doc/PLCAPI.xml.in +++ b/doc/PLCAPI.xml.in @@ -134,7 +134,7 @@ GetNodes({'node_id': [1,2,3]}) Would be equivalent queries. Attributes that are - themselves arrays (such as nodenetwork_ids + themselves arrays (such as interface_ids and slice_ids for nodes) cannot be used in filters. diff --git a/migrations/001-down-subversion.sql b/migrations/001-down-subversion.sql deleted file mode 100644 index 5e3255c..0000000 --- a/migrations/001-down-subversion.sql +++ /dev/null @@ -1,3 +0,0 @@ --- you may also write downgrader scripts, though they are not - yet - supported - -ALTER TABLE plc_db_version DROP subversion; diff --git a/migrations/001-up-subversion.sql b/migrations/001-up-subversion.sql deleted file mode 100644 index 01046a5..0000000 --- a/migrations/001-up-subversion.sql +++ /dev/null @@ -1,5 +0,0 @@ --- Add plc_db_version.subversion field -ALTER TABLE plc_db_version ADD subversion integer NOT NULL DEFAULT 0; - --- Bump subversion -UPDATE plc_db_version SET subversion = 1; diff --git a/migrations/002-up-slices.sql b/migrations/002-up-slices.sql deleted file mode 100644 index 4bf656d..0000000 --- a/migrations/002-up-slices.sql +++ /dev/null @@ -1,6 +0,0 @@ --- Remove NOT NULL constraint from creator_person_id in case the --- creator is deleted. -ALTER TABLE slices ALTER creator_person_id DROP NOT NULL; - --- Bump subversion -UPDATE plc_db_version SET subversion = 2; diff --git a/migrations/003-down-network-settings.sql b/migrations/003-down-network-settings.sql deleted file mode 100644 index 796e4b4..0000000 --- a/migrations/003-down-network-settings.sql +++ /dev/null @@ -1,24 +0,0 @@ --- IMPORTANT NOTICE --- --- this down script is provided for convenience only --- DO NOT USE on an operational site --- the change in migration 003 involves creating --- the new view view_nodenetworks for fetching instances --- of NodeNetworks --- AND to alter NodeNetworks.py accordingly --- so this change cannot be easily undone --- unless you also revert the API itself - -DROP VIEW view_nodenetworks; - -DROP VIEW view_nodenetwork_settings; - -DROP VIEW nodenetwork_settings; - -DROP TABLE nodenetwork_setting; - -DROP TABLE nodenetwork_setting_types; - --- deflate subversion -UPDATE plc_db_version SET subversion = 2; -SELECT subversion from plc_db_version; diff --git a/migrations/003-test.py b/migrations/003-test.py deleted file mode 100755 index aed650b..0000000 --- a/migrations/003-test.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env plcsh - -nnst = GetNodeNetworkSettingTypes(['interface_name']) -if nnst: - print 'NodeNetworkSettingType interface_name already defined' -else: - AddNodeNetworkSettingType({ - 'category':'general', - 'min_role_id':30, - 'name':'interface_name', - 'description':'allows to specify a custom interface name' - }) -nnst_ifname_id = GetNodeNetworkSettingTypes(['interface_name'])[0]['nodenetwork_setting_type_id'] - - -nnst = GetNodeNetworkSettingTypes(['ssid']) -if nnst: - print 'NodeNetworkSettingType ssid already defined' -else: - AddNodeNetworkSettingType({ - 'category':'wifi', - 'min_role_id':30, - 'name':'ssid', - 'description':'allows to set ESSID' - }) -nnst_ssid_id = GetNodeNetworkSettingTypes(['ssid'])[0]['nodenetwork_setting_type_id'] - -nodename = 'onelab2.inria.fr' - -nodenetwork_id=GetNodes(nodename)[0]['nodenetwork_ids'][0] - -####### -nns_ifname = GetNodeNetworkSettings ({'nodenetwork_id':nodenetwork_id, - 'nodenetwork_setting_type_id':nnst_ifname_id}) -if nns_ifname: - print "interface name for %s already set (got %s - cat=%s)" %\ - (nodename,nns_ifname[0]['value'],nns_ifname[0]['category']) -else: - AddNodeNetworkSetting(nodenetwork_id, 'interface_name', 'custom-eth0') - -nns_ifname_id = GetNodeNetworkSettings ({'nodenetwork_id':nodenetwork_id, - 'nodenetwork_setting_type_id':nnst_ifname_id})[0]['nodenetwork_setting_id'] -####### -nns_ssid = GetNodeNetworkSettings ({'nodenetwork_id':nodenetwork_id, - 'nodenetwork_setting_type_id':nnst_ssid_id}) -if nns_ssid: - print "ssid for %s already set (got %s - cat=%s)" %\ - (nodename,nns_ifname[0]['value'],nns_ifname[0]['category']) -else: - AddNodeNetworkSetting(nodenetwork_id, 'ssid', 'init-onelab-g') - -nns_ssid_id = GetNodeNetworkSettings ({'nodenetwork_id':nodenetwork_id, - 'nodenetwork_setting_type_id':nnst_ssid_id})[0]['nodenetwork_setting_id'] - -####### - -UpdateNodeNetworkSetting (nns_ssid_id,'onelab-g') - -DeleteNodeNetworkSetting (nns_ifname_id) - diff --git a/migrations/003-up-network-settings.sql b/migrations/003-up-network-settings.sql deleted file mode 100644 index 64b0ff6..0000000 --- a/migrations/003-up-network-settings.sql +++ /dev/null @@ -1,86 +0,0 @@ --- --- Thierry Parmentelat -- INRIA --- --- migration 003 --- --- purpose : provide a generic mechanism for assigning --- nodenetworks (read, network interfaces) with --- custom settings --- --- design --- mimicks the way slice attributes are being handled, --- not that this design is particularly attractive --- but let's not add confusion here --- i.e: --- (*) nodenetwork_setting_types (see slice_attribute_types) --- allows to define a new setting --- e.g, define one such object for storing wifi SSID --- --- (*) nodenetwork_setting (see slice_attribute) --- allow to associate a nodenetwork, a nodenetwork_setting_type, and a value --- --- NOTE. with slice_attributes there is a trick that allows to define --- the attribute either on the slice globally or on a particular node only. --- of course we do not need such a trick - -CREATE TABLE nodenetwork_setting_types ( - nodenetwork_setting_type_id serial PRIMARY KEY, - -- Setting Type Identifier - name text UNIQUE NOT NULL, -- Setting Name - description text, -- Optional Description - category text NOT NULL, -- Category, e.g. Wifi, or whatever - min_role_id integer references roles -- If set, minimal role required -) WITH OIDS; - -CREATE TABLE nodenetwork_setting ( - nodenetwork_setting_id serial PRIMARY KEY, -- Nodenetwork Setting Identifier - nodenetwork_id integer REFERENCES nodenetworks NOT NULL, - -- the nodenetwork this applies to - nodenetwork_setting_type_id integer REFERENCES nodenetwork_setting_types NOT NULL, - -- the setting type - value text -) WITH OIDS; - - -CREATE OR REPLACE VIEW nodenetwork_settings AS -SELECT nodenetwork_id, -array_accum(nodenetwork_setting_id) AS nodenetwork_setting_ids -FROM nodenetwork_setting -GROUP BY nodenetwork_id; - -CREATE OR REPLACE VIEW view_nodenetwork_settings AS -SELECT -nodenetwork_setting.nodenetwork_setting_id, -nodenetwork_setting.nodenetwork_id, -nodenetwork_setting_types.nodenetwork_setting_type_id, -nodenetwork_setting_types.name, -nodenetwork_setting_types.description, -nodenetwork_setting_types.category, -nodenetwork_setting_types.min_role_id, -nodenetwork_setting.value -FROM nodenetwork_setting -INNER JOIN nodenetwork_setting_types USING (nodenetwork_setting_type_id); - -CREATE VIEW view_nodenetworks AS -SELECT -nodenetworks.nodenetwork_id, -nodenetworks.node_id, -nodenetworks.is_primary, -nodenetworks.type, -nodenetworks.method, -nodenetworks.ip, -nodenetworks.mac, -nodenetworks.gateway, -nodenetworks.network, -nodenetworks.broadcast, -nodenetworks.netmask, -nodenetworks.dns1, -nodenetworks.dns2, -nodenetworks.bwlimit, -nodenetworks.hostname, -COALESCE((SELECT nodenetwork_setting_ids FROM nodenetwork_settings WHERE nodenetwork_settings.nodenetwork_id = nodenetworks.nodenetwork_id), '{}') AS nodenetwork_setting_ids -FROM nodenetworks; - --- Bump subversion -UPDATE plc_db_version SET subversion = 3; -SELECT subversion from plc_db_version; diff --git a/migrations/004-up-fix-site-nodes.sql b/migrations/004-up-fix-site-nodes.sql deleted file mode 100644 index 8bc9c58..0000000 --- a/migrations/004-up-fix-site-nodes.sql +++ /dev/null @@ -1,16 +0,0 @@ --- --- bugfix --- the site_nodes should restrict to nodes where deleted is false --- - -CREATE OR REPLACE VIEW site_nodes AS -SELECT site_id, -array_accum(node_id) AS node_ids -FROM nodes -WHERE deleted is false -GROUP BY site_id; - --- Bump subversion -UPDATE plc_db_version SET subversion = 4; -SELECT subversion from plc_db_version; - diff --git a/migrations/005-down-import-apr-2007.sql b/migrations/005-down-import-apr-2007.sql deleted file mode 100644 index fa16b12..0000000 --- a/migrations/005-down-import-apr-2007.sql +++ /dev/null @@ -1,112 +0,0 @@ --- revert migration 005 --- --- this is a rather complex example, so for next times, make sure that you --- * first restore old columns or tables --- * then create or replace views --- * and only finally drop new columns and tables --- otherwise the columns may refuse to get dropped if they are still used by views --- - ----------- creations - -ALTER TABLE events ADD object_type text NOT NULL Default 'Unknown'; - ----------- view changes - --- for some reason these views require to be dropped first -DROP VIEW view_events; -DROP VIEW event_objects; -DROP VIEW view_nodes; -DROP VIEW view_sites; - -CREATE OR REPLACE VIEW event_objects AS -SELECT event_id, -array_accum(object_id) AS object_ids -FROM event_object -GROUP BY event_id; - -CREATE OR REPLACE VIEW view_events AS -SELECT -events.event_id, -events.person_id, -events.node_id, -events.fault_code, -events.call_name, -events.call, -events.object_type, -events.message, -events.runtime, -CAST(date_part('epoch', events.time) AS bigint) AS time, -COALESCE((SELECT object_ids FROM event_objects WHERE event_objects.event_id = events.event_id), '{}') AS object_ids -FROM events; - -CREATE OR REPLACE VIEW view_nodes AS -SELECT -nodes.node_id, -nodes.hostname, -nodes.site_id, -nodes.boot_state, -nodes.deleted, -nodes.model, -nodes.boot_nonce, -nodes.version, -nodes.ssh_rsa_key, -nodes.key, -CAST(date_part('epoch', nodes.date_created) AS bigint) AS date_created, -CAST(date_part('epoch', nodes.last_updated) AS bigint) AS last_updated, -peer_node.peer_id, -peer_node.peer_node_id, -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 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, -node_session.session_id AS session -FROM nodes -LEFT JOIN peer_node USING (node_id) -LEFT JOIN node_session USING (node_id); - -CREATE OR REPLACE VIEW view_sites AS -SELECT -sites.site_id, -sites.login_base, -sites.name, -sites.abbreviated_name, -sites.deleted, -sites.enabled, -sites.is_public, -sites.max_slices, -sites.max_slivers, -sites.latitude, -sites.longitude, -sites.url, -CAST(date_part('epoch', sites.date_created) AS bigint) AS date_created, -CAST(date_part('epoch', sites.last_updated) AS bigint) AS last_updated, -peer_site.peer_id, -peer_site.peer_site_id, -COALESCE((SELECT person_ids FROM site_persons WHERE site_persons.site_id = sites.site_id), '{}') AS person_ids, -COALESCE((SELECT node_ids FROM site_nodes WHERE site_nodes.site_id = sites.site_id), '{}') AS node_ids, -COALESCE((SELECT address_ids FROM site_addresses WHERE site_addresses.site_id = sites.site_id), '{}') AS address_ids, -COALESCE((SELECT slice_ids FROM site_slices WHERE site_slices.site_id = sites.site_id), '{}') AS slice_ids, -COALESCE((SELECT pcu_ids FROM site_pcus WHERE site_pcus.site_id = sites.site_id), '{}') AS pcu_ids -FROM sites -LEFT JOIN peer_site USING (site_id); - ----------- deletions - -ALTER TABLE sites DROP COLUMN ext_consortium_id; - -ALTER TABLE nodes DROP COLUMN last_contact; - -DROP INDEX initscripts_name_idx; -DROP TABLE initscripts; - -ALTER TABLE events DROP COLUMN auth_type; - -ALTER TABLE event_object DROP COLUMN object_type; - ----------- revert subversion - -UPDATE plc_db_version SET subversion = 4; -SELECT subversion from plc_db_version; diff --git a/migrations/005-up-import-apr-2007.sql b/migrations/005-up-import-apr-2007.sql deleted file mode 100644 index 3a34f25..0000000 --- a/migrations/005-up-import-apr-2007.sql +++ /dev/null @@ -1,154 +0,0 @@ --- --- to apply changes from import done in april 2007 from the --- planetlab-4_0-branch tag --- --- this is a rather complex example, so for next times, make sure that you --- * first add new columns and new tables --- * then create or replace views --- * and only finally drop columns --- otherwise the columns may refuse to get dropped if they are still used by views --- - ----------- creations - -ALTER TABLE sites ADD ext_consortium_id integer; - -ALTER TABLE nodes ADD last_contact timestamp without time zone; - --- Initscripts -CREATE TABLE initscripts ( - initscript_id serial PRIMARY KEY, -- Initscript identifier - name text NOT NULL, -- Initscript name - enabled bool NOT NULL DEFAULT true, -- Initscript is active - script text NOT NULL, -- Initscript - UNIQUE (name) -) WITH OIDS; -CREATE INDEX initscripts_name_idx ON initscripts (name); - --- rather drop the tables altogether, --- ALTER TABLE events ADD auth_type text; --- ALTER TABLE event_object ADD COLUMN object_type text NOT NULL Default 'Unknown'; --- CREATE INDEX event_object_object_type_idx ON event_object (object_type); - --- for some reason these views require to be dropped first -DROP VIEW view_events; -DROP VIEW event_objects; -DROP VIEW view_nodes; -DROP VIEW view_sites; - -----dropping tables must be preceded by dropping views using those tables -----otherwise dependency problems -DROP TABLE event_object; -DROP TABLE events; - -CREATE TABLE events ( - event_id serial PRIMARY KEY, -- Event identifier - person_id integer REFERENCES persons, -- Person responsible for event, if any - node_id integer REFERENCES nodes, -- Node responsible for event, if any - auth_type text, -- Type of auth used. i.e. AuthMethod - fault_code integer NOT NULL DEFAULT 0, -- Did this event result in error - call_name text NOT NULL, -- Call responsible for this event - call text NOT NULL, -- Call responsible for this event, including parameters - message text, -- High level description of this event - runtime float DEFAULT 0, -- Event run time - time timestamp without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP -- Event timestamp -) WITH OIDS; - --- Database object(s) that may have been affected by a particular event -CREATE TABLE event_object ( - event_id integer REFERENCES events NOT NULL, -- Event identifier - object_id integer NOT NULL, -- Object identifier - object_type text NOT NULL Default 'Unknown' -- What type of object is this event affecting -) WITH OIDS; -CREATE INDEX event_object_event_id_idx ON event_object (event_id); -CREATE INDEX event_object_object_id_idx ON event_object (object_id); -CREATE INDEX event_object_object_type_idx ON event_object (object_type); - ----------- view changes - -CREATE OR REPLACE VIEW event_objects AS -SELECT event_id, -array_accum(object_id) AS object_ids, -array_accum(object_type) AS object_types -FROM event_object -GROUP BY event_id; - -CREATE OR REPLACE VIEW view_events AS -SELECT -events.event_id, -events.person_id, -events.node_id, -events.auth_type, -events.fault_code, -events.call_name, -events.call, -events.message, -events.runtime, -CAST(date_part('epoch', events.time) AS bigint) AS time, -COALESCE((SELECT object_ids FROM event_objects WHERE event_objects.event_id = events.event_id), '{}') AS object_ids, -COALESCE((SELECT object_types FROM event_objects WHERE event_objects.event_id = events.event_id), '{}') AS object_types -FROM events; - -CREATE OR REPLACE VIEW view_nodes AS -SELECT -nodes.node_id, -nodes.hostname, -nodes.site_id, -nodes.boot_state, -nodes.deleted, -nodes.model, -nodes.boot_nonce, -nodes.version, -nodes.ssh_rsa_key, -nodes.key, -CAST(date_part('epoch', nodes.date_created) AS bigint) AS date_created, -CAST(date_part('epoch', nodes.last_updated) AS bigint) AS last_updated, -CAST(date_part('epoch', nodes.last_contact) AS bigint) AS last_contact, -peer_node.peer_id, -peer_node.peer_node_id, -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 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, -node_session.session_id AS session -FROM nodes -LEFT JOIN peer_node USING (node_id) -LEFT JOIN node_session USING (node_id); - -CREATE OR REPLACE VIEW view_sites AS -SELECT -sites.site_id, -sites.login_base, -sites.name, -sites.abbreviated_name, -sites.deleted, -sites.enabled, -sites.is_public, -sites.max_slices, -sites.max_slivers, -sites.latitude, -sites.longitude, -sites.url, -sites.ext_consortium_id, -CAST(date_part('epoch', sites.date_created) AS bigint) AS date_created, -CAST(date_part('epoch', sites.last_updated) AS bigint) AS last_updated, -peer_site.peer_id, -peer_site.peer_site_id, -COALESCE((SELECT person_ids FROM site_persons WHERE site_persons.site_id = sites.site_id), '{}') AS person_ids, -COALESCE((SELECT node_ids FROM site_nodes WHERE site_nodes.site_id = sites.site_id), '{}') AS node_ids, -COALESCE((SELECT address_ids FROM site_addresses WHERE site_addresses.site_id = sites.site_id), '{}') AS address_ids, -COALESCE((SELECT slice_ids FROM site_slices WHERE site_slices.site_id = sites.site_id), '{}') AS slice_ids, -COALESCE((SELECT pcu_ids FROM site_pcus WHERE site_pcus.site_id = sites.site_id), '{}') AS pcu_ids -FROM sites -LEFT JOIN peer_site USING (site_id); - ----------- deletions ---dont need to drop this colum it doesn't exit anymore ------ALTER TABLE events DROP COLUMN object_type; - ----------- bump subversion - -UPDATE plc_db_version SET subversion = 5; -SELECT subversion from plc_db_version; diff --git a/migrations/006-down-slice-attribute-nodegroup.sql b/migrations/006-down-slice-attribute-nodegroup.sql deleted file mode 100644 index 0dc4bae..0000000 --- a/migrations/006-down-slice-attribute-nodegroup.sql +++ /dev/null @@ -1,25 +0,0 @@ ----------- view changes - -DROP VIEW view_slice_attributes; - -CREATE OR REPLACE VIEW view_slice_attributes AS -SELECT -slice_attribute.slice_attribute_id, -slice_attribute.slice_id, -slice_attribute.node_id, -slice_attribute_types.attribute_type_id, -slice_attribute_types.name, -slice_attribute_types.description, -slice_attribute_types.min_role_id, -slice_attribute.value -FROM slice_attribute -INNER JOIN slice_attribute_types USING (attribute_type_id); - ----------- deletions -DROP INDEX slice_attribute_nodegroup_id_idx; -ALTER TABLE slice_attribute DROP COLUMN nodegroup_id; - ----------- revert subversion - -UPDATE plc_db_version SET subversion = 5; -SELECT subversion from plc_db_version; diff --git a/migrations/006-up-slice-attribute-nodegroup.sql b/migrations/006-up-slice-attribute-nodegroup.sql deleted file mode 100644 index 801f2a0..0000000 --- a/migrations/006-up-slice-attribute-nodegroup.sql +++ /dev/null @@ -1,29 +0,0 @@ ----------- creations - -ALTER TABLE slice_attribute ADD nodegroup_id integer REFERENCES nodegroups; - -CREATE INDEX slice_attribute_nodegroup_id_idx ON slice_attribute (nodegroup_id); - ----------- view changes - -DROP VIEW view_slice_attributes; - -CREATE OR REPLACE VIEW view_slice_attributes AS -SELECT -slice_attribute.slice_attribute_id, -slice_attribute.slice_id, -slice_attribute.node_id, -slice_attribute.nodegroup_id, -slice_attribute_types.attribute_type_id, -slice_attribute_types.name, -slice_attribute_types.description, -slice_attribute_types.min_role_id, -slice_attribute.value -FROM slice_attribute -INNER JOIN slice_attribute_types USING (attribute_type_id); - - ----------- bump subversion - -UPDATE plc_db_version SET subversion = 6; -SELECT subversion from plc_db_version; diff --git a/migrations/007-down-event-objects-view.sql b/migrations/007-down-event-objects-view.sql deleted file mode 100644 index 09b86f3..0000000 --- a/migrations/007-down-event-objects-view.sql +++ /dev/null @@ -1,11 +0,0 @@ --- --- migration 007 - revert --- - -DROP VIEW view_event_objects; - ----------- revert subversion - -UPDATE plc_db_version SET subversion = 6; -SELECT subversion from plc_db_version; - diff --git a/migrations/007-up-event-objects-view.sql b/migrations/007-up-event-objects-view.sql deleted file mode 100644 index 2ed47ee..0000000 --- a/migrations/007-up-event-objects-view.sql +++ /dev/null @@ -1,26 +0,0 @@ --- --- migration 007 --- change the way event objects are fetched, use a view for that purpose --- - - -CREATE OR REPLACE VIEW view_event_objects AS -SELECT -events.event_id, -events.person_id, -events.node_id, -events.fault_code, -events.call_name, -events.call, -events.message, -events.runtime, -CAST(date_part('epoch', events.time) AS bigint) AS time, -event_object.object_id, -event_object.object_type -FROM events LEFT JOIN event_object USING (event_id); - - ----------- bump subversion - -UPDATE plc_db_version SET subversion = 7; -SELECT subversion from plc_db_version; diff --git a/migrations/008-down-import-aug-2007.sql b/migrations/008-down-import-aug-2007.sql deleted file mode 100644 index 9a3eaab..0000000 --- a/migrations/008-down-import-aug-2007.sql +++ /dev/null @@ -1,42 +0,0 @@ - -DELETE from slice_instantiations WHERE instantiation='nm-controller'; - - - -DROP VIEW view_nodes; -DROP VIEW node_slices_whitelist; -DROP TABLE node_slice_whitelist; - -CREATE OR REPLACE VIEW view_nodes AS -SELECT -nodes.node_id, -nodes.hostname, -nodes.site_id, -nodes.boot_state, -nodes.deleted, -nodes.model, -nodes.boot_nonce, -nodes.version, -nodes.ssh_rsa_key, -nodes.key, -CAST(date_part('epoch', nodes.date_created) AS bigint) AS date_created, -CAST(date_part('epoch', nodes.last_updated) AS bigint) AS last_updated, -CAST(date_part('epoch', nodes.last_contact) AS bigint) AS last_contact, -peer_node.peer_id, -peer_node.peer_node_id, -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 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, -node_session.session_id AS session -FROM nodes -LEFT JOIN peer_node USING (node_id) -LEFT JOIN node_session USING (node_id); - - ----------- revert subversion - -UPDATE plc_db_version SET subversion = 7; -SELECT subversion from plc_db_version; diff --git a/migrations/008-up-import-aug-2007.sql b/migrations/008-up-import-aug-2007.sql deleted file mode 100644 index 2220f8b..0000000 --- a/migrations/008-up-import-aug-2007.sql +++ /dev/null @@ -1,64 +0,0 @@ --- --- migration 008 --- import from Princeton codebase on august 2007 28 --- slice instantiation 'nm-controller' --- * white lists --- - -INSERT INTO slice_instantiations (instantiation) VALUES ('nm-controller'); -- NM Controller - --------------------------------------------------------------------------------- --- Slice whitelist --------------------------------------------------------------------------------- --- 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; - -DROP VIEW view_nodes; - - -CREATE OR REPLACE VIEW view_nodes AS -SELECT -nodes.node_id, -nodes.hostname, -nodes.site_id, -nodes.boot_state, -nodes.deleted, -nodes.model, -nodes.boot_nonce, -nodes.version, -nodes.ssh_rsa_key, -nodes.key, -CAST(date_part('epoch', nodes.date_created) AS bigint) AS date_created, -CAST(date_part('epoch', nodes.last_updated) AS bigint) AS last_updated, -CAST(date_part('epoch', nodes.last_contact) AS bigint) AS last_contact, -peer_node.peer_id, -peer_node.peer_node_id, -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, -node_session.session_id AS session -FROM nodes -LEFT JOIN peer_node USING (node_id) -LEFT JOIN node_session USING (node_id); - ----------- bump subversion - -UPDATE plc_db_version SET subversion = 8; -SELECT subversion from plc_db_version; diff --git a/migrations/009-down-pcu-types.sql b/migrations/009-down-pcu-types.sql deleted file mode 100644 index 1dbe9d2..0000000 --- a/migrations/009-down-pcu-types.sql +++ /dev/null @@ -1,13 +0,0 @@ --- --- 009 revert --- - -DROP VIEW view_pcu_types; - -DROP VIEW pcu_type_ports; - -DROP TABLE pcu_type_port; - -DROP TABLE pcu_types; - -UPDATE plc_db_version SET subversion = 7; diff --git a/migrations/009-up-pcu-types.sql b/migrations/009-up-pcu-types.sql deleted file mode 100644 index c7dd7b6..0000000 --- a/migrations/009-up-pcu-types.sql +++ /dev/null @@ -1,41 +0,0 @@ --- --- Tony Mack - PlanetLab --- --- migration 009 --- --- purpose: provide a means for storing details about pcu models --- --- - -CREATE TABLE pcu_types ( - pcu_type_id serial PRIMARY KEY, - model text NOT NULL, -- PCU model name - name text -- Full PCU model name -) WITH OIDS; -CREATE INDEX pcu_types_model_idx ON pcu_types (model); - -CREATE TABLE pcu_protocol_type ( - pcu_protocol_type_id serial PRIMARY KEY, - pcu_type_id integer REFERENCES pcu_types NOT NULL, -- PCU type identifier - port integer NOT NULL, -- PCU port - protocol text NOT NULL, -- Protocol - supported boolean NOT NULL DEFAULT True -- Does PLC support -) WITH OIDS; -CREATE INDEX pcu_protocol_type_pcu_type_id ON pcu_protocol_type (pcu_type_id); - - -CREATE OR REPLACE VIEW pcu_protocol_types AS -SELECT pcu_type_id, -array_accum(pcu_protocol_type_id) as pcu_protocol_type_ids -FROM pcu_protocol_type -GROUP BY pcu_type_id; - -CREATE OR REPLACE VIEW view_pcu_types AS -SELECT -pcu_types.pcu_type_id, -pcu_types.model, -pcu_types.name, -COALESCE((SELECT pcu_protocol_type_ids FROM pcu_protocol_types WHERE pcu_protocol_types.pcu_type_id = pcu_types.pcu_type_id), '{}') AS pcu_protocol_type_ids -FROM pcu_types; - -UPDATE plc_db_version SET subversion = 9; diff --git a/migrations/migrate-v4-to-v5.sh b/migrations/migrate-v4-to-v5.sh new file mode 100755 index 0000000..1d04800 --- /dev/null +++ b/migrations/migrate-v4-to-v5.sh @@ -0,0 +1,227 @@ +#!/bin/bash + +. /etc/planetlab/plc_config + +PLC_DB_USER + +# return 0 (yes) or 1 (no) whether the database exists +function check_for_database () { + dbname=$1; shift + psql --user=$PLC_DB_USER --quiet -c "SELECT subversion from plc_db_version LIMIT 1" $dbname 2> /dev/null + return $? +} + +# when 'service plc start' gets run, the planetlab5 DB gets created +# so this script will drop the planetlab5 DB and re-create it from scratch +# with the contents of the planetlab4 DB that is epxected to exist +function main () { + + set -e + cd /usr/share/plc_api + + # check that planetlab4 exists + if check_for_database planetlab4 ; then + echo OK : FOUND db planetlab4 + else + echo ERROR : planetlab4 NOT FOUND - exiting + exit 1 + fi + + # dump planetlab4 + DUMP4=planetlab4-$(date +%Y-%m-%d-%H-%M) + pg_dump --user=$PLC_DB_USER planetlab4 > $DUMP4.sql + + # check if planetlab5 exists + if check_for_database planetlab5 ; then + echo 'WARNING: found an existing DB named planetlab5' + i=0 + while true; do + i=$(($i+1)) + bkname=$(printf planetlab5-%03d $i) + if check_for_database $bkname ; then + echo "$bkname already exists - skipping" + else + echo "Renaming planetab5 into $bkname" + psql --user=$PLC_DB_USER -c "ALTER DATABASE planetlab5 RENAME TO $bkname" + echo "Done" + fi + done + fi + if check_for_database planetlab5 ; then + echo ERROR : FOUND planetlab5 - exiting + exit 1 + else + echo OK : db planetlab5 NOT FOUND + fi + + # create it + createdb --user=postgres --encoding=UNICODE --owner=$PLC_DB_USER planetlab5 + # populate it + psql --user=$PLC_DB_USER planetlab5 < $DUMP4.sql + + # run coarse-grain script + migration_script | psql --user=$PLC_DB_USER planetlab5 + +} + + +function migration_script () { + + cat <