From fe0cd47e2b702d69bde8518a41e3661dd9ffbea7 Mon Sep 17 00:00:00 2001 From: Mark Huang Date: Mon, 16 Oct 2006 21:59:05 +0000 Subject: [PATCH] rename attributes to slice_attribute_types --- PLC/Attributes.py | 91 ------------------------- PLC/Methods/AddAttribute.py | 36 ---------- PLC/Methods/AddSliceAttribute.py | 22 +++--- PLC/Methods/AddSliceAttributeType.py | 37 ++++++++++ PLC/Methods/DeleteAttribute.py | 32 --------- PLC/Methods/DeleteSliceAttributeType.py | 32 +++++++++ PLC/Methods/GetAttributes.py | 30 -------- PLC/Methods/GetSliceAttributeTypes.py | 30 ++++++++ PLC/Methods/GetSliceAttributes.py | 42 +++++------- PLC/Methods/UpdateAttribute.py | 43 ------------ PLC/Methods/UpdateSliceAttributeType.py | 43 ++++++++++++ PLC/Methods/__init__.py | 2 +- PLC/Roles.py | 4 +- PLC/SliceAttributeTypes.py | 91 +++++++++++++++++++++++++ PLC/SliceAttributes.py | 13 ++-- PLC/__init__.py | 2 +- Test.py | 82 +++++++++++----------- planetlab4.sql | 18 ++--- 18 files changed, 319 insertions(+), 331 deletions(-) delete mode 100644 PLC/Attributes.py delete mode 100644 PLC/Methods/AddAttribute.py create mode 100644 PLC/Methods/AddSliceAttributeType.py delete mode 100644 PLC/Methods/DeleteAttribute.py create mode 100644 PLC/Methods/DeleteSliceAttributeType.py delete mode 100644 PLC/Methods/GetAttributes.py create mode 100644 PLC/Methods/GetSliceAttributeTypes.py delete mode 100644 PLC/Methods/UpdateAttribute.py create mode 100644 PLC/Methods/UpdateSliceAttributeType.py create mode 100644 PLC/SliceAttributeTypes.py diff --git a/PLC/Attributes.py b/PLC/Attributes.py deleted file mode 100644 index 77623d2..0000000 --- a/PLC/Attributes.py +++ /dev/null @@ -1,91 +0,0 @@ -from types import StringTypes - -from PLC.Faults import * -from PLC.Parameter import Parameter -from PLC.Table import Row, Table -from PLC.Roles import Role, Roles - -class Attribute(Row): - """ - Representation of a row in the attributes table. To use, instantiate - with a dict of values. - """ - - table_name = 'attributes' - primary_key = 'attribute_id' - fields = { - 'attribute_id': Parameter(int, "Attribute identifier"), - 'name': Parameter(str, "Attribute name", max = 100), - 'description': Parameter(str, "Attribute description", max = 254), - 'min_role_id': Parameter(int, "Minimum (least powerful) role that can set or change this attribute"), - } - - def __init__(self, api, fields = {}): - Row.__init__(self, fields) - self.api = api - - def validate_name(self, name): - name = name.strip() - - if not name: - raise PLCInvalidArgument, "Attribute name must be set" - - conflicts = Attributes(self.api, [name]) - for attribute_id, attribute in conflicts.iteritems(): - if 'attribute_id' not in self or self['attribute_id'] != attribute_id: - raise PLCInvalidArgument, "Attribute name already in use" - - return name - - def validate_min_role_id(self, role_id): - roles = Roles(self.api) - if role_id not in roles: - raise PLCInvalidArgument, "Invalid role" - - return role_id - - def delete(self, commit = True): - """ - Delete existing slice attribute type. - """ - - assert 'attribute_id' in self - - # Clean up miscellaneous join tables - for table in ['attributes', 'slice_attribute']: - self.api.db.do("DELETE FROM %s" \ - " WHERE attribute_id = %d" % \ - (table, self['attribute_id']), self) - - if commit: - self.api.db.commit() - -class Attributes(Table): - """ - Representation of row(s) from the attributes table in the - database. - """ - - def __init__(self, api, attribute_id_or_name_list = None): - self.api = api - - sql = "SELECT %s FROM attributes" % \ - ", ".join(Attribute.fields) - - if attribute_id_or_name_list: - # Separate the list into integers and strings - attribute_ids = filter(lambda attribute_id: isinstance(attribute_id, (int, long)), - attribute_id_or_name_list) - names = filter(lambda name: isinstance(name, StringTypes), - attribute_id_or_name_list) - sql += " WHERE (False" - if attribute_ids: - sql += " OR attribute_id IN (%s)" % ", ".join(map(str, attribute_ids)) - if names: - sql += " OR name IN (%s)" % ", ".join(api.db.quote(names)) - sql += ")" - - rows = self.api.db.selectall(sql) - - for row in rows: - self[row['attribute_id']] = Attribute(api, row) diff --git a/PLC/Methods/AddAttribute.py b/PLC/Methods/AddAttribute.py deleted file mode 100644 index 34cb104..0000000 --- a/PLC/Methods/AddAttribute.py +++ /dev/null @@ -1,36 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Attributes import Attribute, Attributes -from PLC.Auth import PasswordAuth - -can_update = lambda (field, value): field in \ - ['description', 'min_role_id'] - -class AddAttribute(Method): - """ - Adds a new type of attribute. Any fields specified in - attribute_fields are used, otherwise defaults are used. - - Returns the new attribute_id (> 0) if successful, faults otherwise. - """ - - roles = ['admin'] - - update_fields = dict(filter(can_update, Attribute.fields.items())) - - accepts = [ - PasswordAuth(), - Attribute.fields['name'], - update_fields - ] - - returns = Parameter(int, 'New attribute_id (> 0) if successful') - - def call(self, auth, name, attribute_fields = {}): - attribute_fields = dict(filter(can_update, attribute_fields.items())) - attribute = Attribute(self.api, attribute_fields) - attribute['name'] = name - attribute.sync() - - return attribute['attribute_id'] diff --git a/PLC/Methods/AddSliceAttribute.py b/PLC/Methods/AddSliceAttribute.py index b8d3a0c..e221be8 100644 --- a/PLC/Methods/AddSliceAttribute.py +++ b/PLC/Methods/AddSliceAttribute.py @@ -1,7 +1,7 @@ from PLC.Faults import * from PLC.Method import Method from PLC.Parameter import Parameter, Mixed -from PLC.Attributes import Attribute, Attributes +from PLC.SliceAttributeTypes import SliceAttributeType, SliceAttributeTypes from PLC.Slices import Slice, Slices from PLC.Nodes import Node, Nodes from PLC.SliceAttributes import SliceAttribute, SliceAttributes @@ -28,7 +28,7 @@ class AddSliceAttribute(Method): PasswordAuth(), Mixed(SliceAttribute.fields['slice_id'], SliceAttribute.fields['name']), - Mixed(SliceAttribute.fields['attribute_id'], + Mixed(SliceAttribute.fields['attribute_type_id'], SliceAttribute.fields['name']), SliceAttribute.fields['value'], Mixed(Node.fields['node_id'], @@ -37,16 +37,16 @@ class AddSliceAttribute(Method): returns = Parameter(int, 'New slice_attribute_id (> 0) if successful') - def call(self, auth, slice_id_or_name, attribute_id_or_name, value, node_id_or_hostname = None): + def call(self, auth, slice_id_or_name, attribute_type_id_or_name, value, node_id_or_hostname = None): slices = Slices(self.api, [slice_id_or_name]).values() if not slices: raise PLCInvalidArgument, "No such slice" slice = slices[0] - attributes = Attributes(self.api, [attribute_id_or_name]).values() - if not attributes: - raise PLCInvalidArgument, "No such attribute" - attribute = attributes[0] + attribute_types = SliceAttributeTypes(self.api, [attribute_type_id_or_name]).values() + if not attribute_types: + raise PLCInvalidArgument, "No such slice attribute type" + attribute_type = attribute_types[0] if 'admin' not in self.caller['roles']: if self.caller['person_id'] in slice['person_ids']: @@ -56,13 +56,13 @@ class AddSliceAttribute(Method): elif slice['site_id'] not in self.caller['site_ids']: raise PLCPermissionDenied, "Specified slice not associated with any of your sites" - if attribute['min_role_id'] is not None and \ - min(self.caller['role_ids']) > attribute['min_role_id']: - raise PLCPermissionDenied, "Not allowed to set the specified attribute" + if attribute_type['min_role_id'] is not None and \ + min(self.caller['role_ids']) > attribute_type['min_role_id']: + raise PLCPermissionDenied, "Not allowed to set the specified slice attribute" slice_attribute = SliceAttribute(self.api) slice_attribute['slice_id'] = slice['slice_id'] - slice_attribute['attribute_id'] = attribute['attribute_id'] + slice_attribute['attribute_type_id'] = attribute_type['attribute_type_id'] slice_attribute['value'] = value # Sliver attribute if node is specified diff --git a/PLC/Methods/AddSliceAttributeType.py b/PLC/Methods/AddSliceAttributeType.py new file mode 100644 index 0000000..413471e --- /dev/null +++ b/PLC/Methods/AddSliceAttributeType.py @@ -0,0 +1,37 @@ +from PLC.Faults import * +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.SliceAttributeTypes import SliceAttributeType, SliceAttributeTypes +from PLC.Auth import PasswordAuth + +can_update = lambda (field, value): field in \ + ['description', 'min_role_id'] + +class AddSliceAttributeType(Method): + """ + Adds a new type of slice attribute. Any fields specified in + attribute_type_fields are used, otherwise defaults are used. + + Returns the new attribute_type_id (> 0) if successful, faults + otherwise. + """ + + roles = ['admin'] + + update_fields = dict(filter(can_update, SliceAttributeType.fields.items())) + + accepts = [ + PasswordAuth(), + SliceAttributeType.fields['name'], + update_fields + ] + + returns = Parameter(int, 'New attribute_id (> 0) if successful') + + def call(self, auth, name, attribute_type_fields = {}): + attribute_type_fields = dict(filter(can_update, attribute_type_fields.items())) + attribute_type = SliceAttributeType(self.api, attribute_type_fields) + attribute_type['name'] = name + attribute_type.sync() + + return attribute_type['attribute_type_id'] diff --git a/PLC/Methods/DeleteAttribute.py b/PLC/Methods/DeleteAttribute.py deleted file mode 100644 index aafce7d..0000000 --- a/PLC/Methods/DeleteAttribute.py +++ /dev/null @@ -1,32 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Attributes import Attribute, Attributes -from PLC.Auth import PasswordAuth - -class DeleteAttribute(Method): - """ - Deletes the specified slice attribute. - - Returns 1 if successful, faults otherwise. - """ - - roles = ['admin'] - - accepts = [ - PasswordAuth(), - Mixed(Attribute.fields['attribute_id'], - Attribute.fields['name']), - ] - - returns = Parameter(int, '1 if successful') - - def call(self, auth, attribute_id_or_name): - attributes = Attributes(self.api, [attribute_id_or_name]).values() - if not attributes: - raise PLCInvalidArgument, "No such attribute" - attribute = attributes[0] - - attribute.delete() - - return 1 diff --git a/PLC/Methods/DeleteSliceAttributeType.py b/PLC/Methods/DeleteSliceAttributeType.py new file mode 100644 index 0000000..45626f7 --- /dev/null +++ b/PLC/Methods/DeleteSliceAttributeType.py @@ -0,0 +1,32 @@ +from PLC.Faults import * +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.SliceAttributeTypes import SliceAttributeType, SliceAttributeTypes +from PLC.Auth import PasswordAuth + +class DeleteSliceAttributeType(Method): + """ + Deletes the specified slice attribute. + + Returns 1 if successful, faults otherwise. + """ + + roles = ['admin'] + + accepts = [ + PasswordAuth(), + Mixed(SliceAttributeType.fields['attribute_type_id'], + SliceAttributeType.fields['name']), + ] + + returns = Parameter(int, '1 if successful') + + def call(self, auth, attribute_type_id_or_name): + attribute_types = SliceAttributeTypes(self.api, [attribute_type_id_or_name]).values() + if not attribute_types: + raise PLCInvalidArgument, "No such slice attribute type" + attribute_type = attribute_types[0] + + attribute_type.delete() + + return 1 diff --git a/PLC/Methods/GetAttributes.py b/PLC/Methods/GetAttributes.py deleted file mode 100644 index 8790e13..0000000 --- a/PLC/Methods/GetAttributes.py +++ /dev/null @@ -1,30 +0,0 @@ -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Auth import PasswordAuth -from PLC.Attributes import Attribute, Attributes - -class GetAttributes(Method): - """ - Return an array of structs containing details about all possible - slice and node attributes. If attribute_id_or_name_list is - specified, only the specified attributes will be queried. - """ - - roles = ['admin', 'pi', 'user', 'tech'] - - accepts = [ - PasswordAuth(), - [Mixed(Attribute.fields['attribute_id'], - Attribute.fields['name'])], - ] - - returns = [Attribute.fields] - - def call(self, auth, attribute_id_or_name_list = None): - # Get slice attribute information - attributes = Attributes(self.api, attribute_id_or_name_list).values() - - # Turn each attribute into a real dict. - attributes = [dict(attribute) for attribute in attributes] - - return attributes diff --git a/PLC/Methods/GetSliceAttributeTypes.py b/PLC/Methods/GetSliceAttributeTypes.py new file mode 100644 index 0000000..fa060b7 --- /dev/null +++ b/PLC/Methods/GetSliceAttributeTypes.py @@ -0,0 +1,30 @@ +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.Auth import PasswordAuth +from PLC.SliceAttributeTypes import SliceAttributeType, SliceAttributeTypes + +class GetSliceAttributeTypes(Method): + """ + Return an array of structs containing details about all possible + slice and node attributes. If attribute_id_or_name_list is + specified, only the specified attributes will be queried. + """ + + roles = ['admin', 'pi', 'user', 'tech'] + + accepts = [ + PasswordAuth(), + [Mixed(SliceAttributeType.fields['attribute_type_id'], + SliceAttributeType.fields['name'])], + ] + + returns = [SliceAttributeType.fields] + + def call(self, auth, attribute_type_id_or_name_list = None): + # Get slice attribute type information + attribute_types = SliceAttributeTypes(self.api, attribute_type_id_or_name_list).values() + + # Turn each attribute into a real dict. + attribute_types = [dict(attribute_type) for attribute_type in attribute_types] + + return attribute_types diff --git a/PLC/Methods/GetSliceAttributes.py b/PLC/Methods/GetSliceAttributes.py index 9d92c1e..be646c8 100644 --- a/PLC/Methods/GetSliceAttributes.py +++ b/PLC/Methods/GetSliceAttributes.py @@ -2,6 +2,7 @@ from PLC.Faults import * from PLC.Method import Method from PLC.Parameter import Parameter, Mixed from PLC.SliceAttributes import SliceAttribute, SliceAttributes +from PLC.Sites import Site, Sites from PLC.Slices import Slice, Slices from PLC.Nodes import Node, Nodes from PLC.Auth import PasswordAuth @@ -23,37 +24,26 @@ class GetSliceAttributes(Method): accepts = [ PasswordAuth(), - Mixed(Slice.fields['slice_id'], - Slice.fields['name']), [SliceAttribute.fields['slice_attribute_id']], ] returns = [SliceAttribute.fields] - def call(self, auth, slice_id_or_name, slice_attribute_id_list = None): - slices = Slices(self.api, [slice_id_or_name]).values() - if not slices: - raise PLCInvalidArgument, "No such slice" - slice = slices[0] - + def call(self, auth, slice_attribute_ids = None): + # If we are not admin, make sure to only return our own slice + # and sliver attributes. if 'admin' not in self.caller['roles']: - if self.caller['person_id'] in slice['person_ids']: - pass - elif 'pi' not in self.caller['roles']: - raise PLCPermissionDenied, "Not a member of the specified slice" - elif slice['site_id'] not in self.caller['site_ids']: - raise PLCPermissionDenied, "Specified slice not associated with any of your sites" - - if slice_attribute_id_list is None: - slice_attribute_id_list = slice['slice_attribute_ids'] - else: - if set(slice_attribute_id_list).intersection(slice['slice_attribute_ids']) != \ - set(slice_attribute_id_list): - raise PLCInvalidArgument, "Invalid slice attribute ID(s)" - - slice_attributes = SliceAttributes(self.api, slice_attribute_id_list).values() - # turn each slice attribute into a real dict - slice_attributes = [dict(slice_attribute) \ - for slice_attribute in slice_attributes] + if not slice_attribute_ids: + slice_attribute_ids = [] + slices = Slices(self.api, self.caller['slice_ids']).values() + if 'pi' in self.caller['roles']: + sites = Sites(self.api, self.caller['site_ids']).values() + slices += Slices(self.api, sites['slice_ids']).values() + for slice in slices: + slice_attribute_ids = set(slice_attribute_ids).union(slice['slice_attribute_ids']) + + slice_attributes = SliceAttributes(self.api, slice_attribute_ids).values() + + slice_attributes = [dict(slice_attribute) for slice_attribute in slice_attributes] return slice_attributes diff --git a/PLC/Methods/UpdateAttribute.py b/PLC/Methods/UpdateAttribute.py deleted file mode 100644 index 2ecfe45..0000000 --- a/PLC/Methods/UpdateAttribute.py +++ /dev/null @@ -1,43 +0,0 @@ -from PLC.Faults import * -from PLC.Method import Method -from PLC.Parameter import Parameter, Mixed -from PLC.Attributes import Attribute, Attributes -from PLC.Auth import PasswordAuth - -can_update = lambda (field, value): field in \ - ['description', 'min_role_id'] - -class UpdateAttribute(Method): - """ - Updates the parameters of an existing attribute with the values in - attribute_fields. - - Returns 1 if successful, faults otherwise. - """ - - roles = ['admin'] - - update_fields = dict(filter(can_update, Attribute.fields.items())) - - accepts = [ - PasswordAuth(), - Mixed(Attribute.fields['attribute_id'], - Attribute.fields['name']), - update_fields - ] - - returns = Parameter(int, '1 if successful') - - def call(self, auth, attribute_id_or_name, attribute_fields): - attribute_fields = dict(filter(can_update, attribute_fields.items())) - - attributes = Attributes(self.api, [attribute_id_or_name]).values() - if not attributes: - raise PLCInvalidArgument, "No such attribute" - attribute = attributes[0] - - attribute.update(attribute_fields) - - attribute.sync() - - return 1 diff --git a/PLC/Methods/UpdateSliceAttributeType.py b/PLC/Methods/UpdateSliceAttributeType.py new file mode 100644 index 0000000..3ab869c --- /dev/null +++ b/PLC/Methods/UpdateSliceAttributeType.py @@ -0,0 +1,43 @@ +from PLC.Faults import * +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.SliceAttributeTypes import SliceAttributeType, SliceAttributeTypes +from PLC.Auth import PasswordAuth + +can_update = lambda (field, value): field in \ + ['description', 'min_role_id'] + +class UpdateSliceAttributeType(Method): + """ + Updates the parameters of an existing attribute with the values in + attribute_type_fields. + + Returns 1 if successful, faults otherwise. + """ + + roles = ['admin'] + + update_fields = dict(filter(can_update, SliceAttributeType.fields.items())) + + accepts = [ + PasswordAuth(), + Mixed(SliceAttributeType.fields['attribute_type_id'], + SliceAttributeType.fields['name']), + update_fields + ] + + returns = Parameter(int, '1 if successful') + + def call(self, auth, attribute_type_id_or_name, attribute_type_fields): + attribute_type_fields = dict(filter(can_update, attribute_type_fields.items())) + + attribute_types = SliceAttributeTypes(self.api, [attribute_type_id_or_name]).values() + if not attribute_types: + raise PLCInvalidArgument, "No such attribute" + attribute_type = attribute_types[0] + + attribute_type.update(attribute_type_fields) + + attribute_type.sync() + + return 1 diff --git a/PLC/Methods/__init__.py b/PLC/Methods/__init__.py index 4ad102c..4511c72 100644 --- a/PLC/Methods/__init__.py +++ b/PLC/Methods/__init__.py @@ -1 +1 @@ -methods = 'AddAddress AddAddressType AddAddressTypeToAddress AddAttribute AddBootState AddKey AddKeyType AddNetworkMethod AddNetworkType AddNodeGroup AddNodeNetwork AddNode AddNodeToNodeGroup AddNodeToPCU AddPCU AddPerson AddPersonToSite AddPersonToSlice AddRole AddRoleToPerson AddSite AddSliceAttribute AddSlice AddSliceToNodes AdmAddAddressType AdmAddNodeGroup AdmAddNodeNetwork AdmAddNode AdmAddNodeToNodeGroup AdmAddPerson AdmAddPersonToSite AdmAddSitePowerControlUnit AdmAddSite AdmAssociateNodeToPowerControlUnitPort AdmAuthCheck AdmDeleteAddressType AdmDeleteNodeGroup AdmDeleteNodeNetwork AdmDeleteNode AdmDeletePerson AdmDeleteSitePowerControlUnit AdmDeleteSite AdmDisassociatePowerControlUnitPort AdmGenerateNodeConfFile AdmGetAllAddressTypes AdmGetAllNodeNetworks AdmGetAllRoles AdmGetNodeGroupNodes AdmGetNodeGroups AdmGetNodes AdmGetPersonRoles AdmGetPersonSites AdmGetPersons AdmGetPowerControlUnitNodes AdmGetPowerControlUnits AdmGetSiteNodes AdmGetSitePersons AdmGetSitePowerControlUnits AdmGetSites AdmGrantRoleToPerson AdmIsPersonInRole AdmRebootNode AdmRemoveNodeFromNodeGroup AdmRemovePersonFromSite AdmRevokeRoleFromPerson AdmSetPersonEnabled AdmSetPersonPrimarySite AdmUpdateNodeGroup AdmUpdateNodeNetwork AdmUpdateNode AdmUpdatePerson AdmUpdateSitePowerControlUnit AdmUpdateSite AuthCheck BlacklistKey DeleteAddress DeleteAddressTypeFromAddress DeleteAddressType DeleteAttribute DeleteBootState DeleteKey DeleteKeyType DeleteNetworkMethod DeleteNetworkType DeleteNodeFromNodeGroup DeleteNodeFromPCU DeleteNodeGroup DeleteNodeNetwork DeleteNode DeletePCU DeletePersonFromSite DeletePersonFromSlice DeletePerson DeleteRoleFromPerson DeleteRole DeleteSite DeleteSliceAttribute DeleteSliceFromNodes DeleteSlice GetAddresses GetAddressTypes GetAttributes GetBootStates GetKeys GetKeyTypes GetNetworkMethods GetNetworkTypes GetNodeGroups GetNodeNetworks GetNodes GetPCUs GetPersons GetRoles GetSites GetSliceAttributes GetSlices RebootNode SetPersonPrimarySite UpdateAddress UpdateAddressType UpdateAttribute UpdateKey UpdateNodeGroup UpdateNodeNetwork UpdateNode UpdatePCU UpdatePerson UpdateSite UpdateSliceAttribute UpdateSlice system.listMethods system.methodHelp system.methodSignature system.multicall'.split() +methods = 'AddAddressType AddAddressTypeToAddress AddBootState AddKey AddKeyType AddNetworkMethod AddNetworkType AddNodeGroup AddNodeNetwork AddNode AddNodeToNodeGroup AddNodeToPCU AddPCU AddPerson AddPersonToSite AddPersonToSlice AddRole AddRoleToPerson AddSiteAddress AddSite AddSliceAttribute AddSliceAttributeType AddSlice AddSliceToNodes AdmAddAddressType AdmAddNodeGroup AdmAddNodeNetwork AdmAddNode AdmAddNodeToNodeGroup AdmAddPerson AdmAddPersonToSite AdmAddSitePowerControlUnit AdmAddSite AdmAssociateNodeToPowerControlUnitPort AdmAuthCheck AdmDeleteAddressType AdmDeleteNodeGroup AdmDeleteNodeNetwork AdmDeleteNode AdmDeletePerson AdmDeleteSitePowerControlUnit AdmDeleteSite AdmDisassociatePowerControlUnitPort AdmGenerateNodeConfFile AdmGetAllAddressTypes AdmGetAllNodeNetworks AdmGetAllRoles AdmGetNodeGroupNodes AdmGetNodeGroups AdmGetNodes AdmGetPersonRoles AdmGetPersonSites AdmGetPersons AdmGetPowerControlUnitNodes AdmGetPowerControlUnits AdmGetSiteNodes AdmGetSitePersons AdmGetSitePowerControlUnits AdmGetSites AdmGrantRoleToPerson AdmIsPersonInRole AdmRebootNode AdmRemoveNodeFromNodeGroup AdmRemovePersonFromSite AdmRevokeRoleFromPerson AdmSetPersonEnabled AdmSetPersonPrimarySite AdmUpdateNodeGroup AdmUpdateNodeNetwork AdmUpdateNode AdmUpdatePerson AdmUpdateSitePowerControlUnit AdmUpdateSite AuthCheck BlacklistKey DeleteAddress DeleteAddressTypeFromAddress DeleteAddressType DeleteBootState DeleteKey DeleteKeyType DeleteNetworkMethod DeleteNetworkType DeleteNodeFromNodeGroup DeleteNodeFromPCU DeleteNodeGroup DeleteNodeNetwork DeleteNode DeletePCU DeletePersonFromSite DeletePersonFromSlice DeletePerson DeleteRoleFromPerson DeleteRole DeleteSite DeleteSliceAttribute DeleteSliceAttributeType DeleteSliceFromNodes DeleteSlice GetAddresses GetAddressTypes GetBootStates GetKeys GetKeyTypes GetNetworkMethods GetNetworkTypes GetNodeGroups GetNodeNetworks GetNodes GetPCUs GetPersons GetRoles GetSites GetSliceAttributes GetSliceAttributeTypes GetSlices RebootNode SetPersonPrimarySite UpdateAddress UpdateAddressType UpdateKey UpdateNodeGroup UpdateNodeNetwork UpdateNode UpdatePCU UpdatePerson UpdateSite UpdateSliceAttribute UpdateSliceAttributeType UpdateSlice system.listMethods system.methodHelp system.methodSignature system.multicall'.split() diff --git a/PLC/Roles.py b/PLC/Roles.py index 40c3277..8896647 100644 --- a/PLC/Roles.py +++ b/PLC/Roles.py @@ -4,7 +4,7 @@ # Mark Huang # Copyright (C) 2006 The Trustees of Princeton University # -# $Id: Roles.py,v 1.2 2006/10/06 18:19:41 mlhuang Exp $ +# $Id: Roles.py,v 1.3 2006/10/10 21:54:59 mlhuang Exp $ # from types import StringTypes @@ -61,7 +61,7 @@ class Role(Row): " WHERE role_id = %d" % \ (table, self['role_id']), self) - self.api.db.do("DELETE FROM attributes WHERE min_role_id = %d" % \ + self.api.db.do("DELETE FROM slice_attribute_types WHERE min_role_id = %d" % \ self['role_id']) if commit: diff --git a/PLC/SliceAttributeTypes.py b/PLC/SliceAttributeTypes.py new file mode 100644 index 0000000..e719868 --- /dev/null +++ b/PLC/SliceAttributeTypes.py @@ -0,0 +1,91 @@ +from types import StringTypes + +from PLC.Faults import * +from PLC.Parameter import Parameter +from PLC.Table import Row, Table +from PLC.Roles import Role, Roles + +class SliceAttributeType(Row): + """ + Representation of a row in the slice_attribute_types table. To + use, instantiate with a dict of values. + """ + + table_name = 'slice_attribute_types' + primary_key = 'attribute_type_id' + fields = { + 'attribute_type_id': Parameter(int, "Slice attribute type identifier"), + 'name': Parameter(str, "Slice attribute type name", max = 100), + 'description': Parameter(str, "Slice attribute type description", max = 254), + 'min_role_id': Parameter(int, "Minimum (least powerful) role that can set or change this attribute"), + } + + def __init__(self, api, fields = {}): + Row.__init__(self, fields) + self.api = api + + def validate_name(self, name): + name = name.strip() + + if not name: + raise PLCInvalidArgument, "Slice attribute type name must be set" + + conflicts = SliceAttributeTypes(self.api, [name]) + for attribute_type_id, attribute in conflicts.iteritems(): + if 'attribute_type_id' not in self or self['attribute_type_id'] != attribute_type_id: + raise PLCInvalidArgument, "Slice attribute type name already in use" + + return name + + def validate_min_role_id(self, role_id): + roles = Roles(self.api) + if role_id not in roles: + raise PLCInvalidArgument, "Invalid role" + + return role_id + + def delete(self, commit = True): + """ + Delete existing slice attribute type. + """ + + assert 'attribute_type_id' in self + + # Clean up miscellaneous join tables + for table in ['slice_attribute_types', 'slice_attribute']: + self.api.db.do("DELETE FROM %s" \ + " WHERE attribute_type_id = %d" % \ + (table, self['attribute_type_id']), self) + + if commit: + self.api.db.commit() + +class SliceAttributeTypes(Table): + """ + Representation of row(s) from the slice_attribute_types table in the + database. + """ + + def __init__(self, api, attribute_type_id_or_name_list = None): + self.api = api + + sql = "SELECT %s FROM slice_attribute_types" % \ + ", ".join(SliceAttributeType.fields) + + if attribute_type_id_or_name_list: + # Separate the list into integers and strings + attribute_type_ids = filter(lambda attribute_type_id: isinstance(attribute_type_id, (int, long)), + attribute_type_id_or_name_list) + names = filter(lambda name: isinstance(name, StringTypes), + attribute_type_id_or_name_list) + sql += " WHERE (False" + if attribute_type_ids: + sql += " OR attribute_type_id IN (%s)" % ", ".join(map(str, attribute_type_ids)) + if names: + sql += " OR name IN (%s)" % ", ".join(api.db.quote(names)) + sql += ")" + + rows = self.api.db.selectall(sql) + + for row in rows: + self[row['attribute_type_id']] = SliceAttributeType(api, row) diff --git a/PLC/SliceAttributes.py b/PLC/SliceAttributes.py index bf51c29..dd91131 100644 --- a/PLC/SliceAttributes.py +++ b/PLC/SliceAttributes.py @@ -3,7 +3,7 @@ from types import StringTypes from PLC.Faults import * from PLC.Parameter import Parameter from PLC.Table import Row, Table -from PLC.Attributes import Attribute, Attributes +from PLC.SliceAttributeTypes import SliceAttributeType, SliceAttributeTypes class SliceAttribute(Row): """ @@ -17,10 +17,10 @@ class SliceAttribute(Row): 'slice_attribute_id': Parameter(int, "Slice attribute identifier"), 'slice_id': Parameter(int, "Slice identifier"), 'node_id': Parameter(int, "Node identifier, if a sliver attribute"), - 'attribute_id': Attribute.fields['attribute_id'], - 'name': Attribute.fields['name'], - 'description': Attribute.fields['description'], - 'min_role_id': Attribute.fields['min_role_id'], + 'attribute_type_id': SliceAttributeType.fields['attribute_type_id'], + 'name': SliceAttributeType.fields['name'], + 'description': SliceAttributeType.fields['description'], + 'min_role_id': SliceAttributeType.fields['min_role_id'], # XXX Arbitrary max, make configurable 'value': Parameter(str, "Slice attribute value", max = 254), } @@ -57,7 +57,8 @@ class SliceAttributes(dict): sql = "SELECT %s FROM view_slice_attributes" % \ ", ".join(SliceAttribute.fields) - sql += " WHERE slice_attribute_id IN (%s)" % ", ".join(map(str, slice_attribute_id_list)) + if slice_attribute_id_list: + sql += " WHERE slice_attribute_id IN (%s)" % ", ".join(map(str, slice_attribute_id_list)) rows = self.api.db.selectall(sql) diff --git a/PLC/__init__.py b/PLC/__init__.py index ea834ec..704a114 100644 --- a/PLC/__init__.py +++ b/PLC/__init__.py @@ -1 +1 @@ -all = 'Addresses AddressTypes API Attributes Auth BootStates Config Debug Faults Keys KeyTypes Method NetworkMethods NetworkTypes NodeGroups NodeNetworks Nodes Parameter PCUs Persons POD PostgreSQL Roles Sites SliceAttributes SliceInstantiations Slices Table'.split() +all = 'Addresses AddressTypes API Auth BootStates Config Debug Faults Keys KeyTypes Method NetworkMethods NetworkTypes NodeGroups NodeNetworks Nodes Parameter PCUs Persons POD PostgreSQL Roles Sites SliceAttributes SliceAttributeTypes SliceInstantiations Slices Table'.split() diff --git a/Test.py b/Test.py index e845d11..35ad886 100755 --- a/Test.py +++ b/Test.py @@ -5,7 +5,7 @@ # Mark Huang # Copyright (C) 2006 The Trustees of Princeton University # -# $Id: Test.py,v 1.8 2006/10/03 19:33:16 mlhuang Exp $ +# $Id: Test.py,v 1.9 2006/10/11 15:46:09 mlhuang Exp $ # from pprint import pprint @@ -341,10 +341,6 @@ for nodegroup_id in nodegroup_ids: assert set(nodegroup_node_ids) == set(node_ids) print "=>", nodegroup_node_ids -print "AdmGetAllNodeNetworkBandwidthLimits", -bwlimits = AdmGetAllNodeNetworkBandwidthLimits(admin) -print "=>", bwlimits - # Add node networks nodenetwork_ids = [] for node_id in node_ids: @@ -410,41 +406,41 @@ for node_id in node_ids: assert address == locals()[key] print "=>", [nodenetwork['nodenetwork_id'] for nodenetwork in nodenetworks] -# Add attribute types -attribute_ids = [] +# Add node attribute types +attribute_type_ids = [] for i in range(3): name = randstr(100) description = randstr(254) min_role_id = random.sample(roles.values(), 1)[0] - # Add attribute - print "AddAttribute", - attribute_id = AddAttribute(admin, name, - {'description': description, - 'min_role_id': min_role_id}) + # Add slice attribute type + print "AddSliceAttributeType", + attribute_type_id = AddSliceAttributeType(admin, name, + {'description': description, + 'min_role_id': min_role_id}) - # Should return a unique attribute_id - assert attribute_id not in attribute_ids - attribute_ids.append(attribute_id) - print "=>", attribute_id + # Should return a unique attribute_type_id + assert attribute_type_id not in attribute_type_ids + attribute_type_ids.append(attribute_type_id) + print "=>", attribute_type_id - # Check attribute - print "GetAttributes(%d)" % attribute_id, - attribute = GetAttributes(admin, [attribute_id])[0] + # Check slice attribute type + print "GetSliceAttributeTypes(%d)" % attribute_type_id, + attribute_type = GetSliceAttributeTypes(admin, [attribute_type_id])[0] for key in 'min_role_id', 'description': - assert unicmp(attribute[key], locals()[key]) + assert unicmp(attribute_type[key], locals()[key]) print "=> OK" - # Update attribute + # Update slice attribute type description = randstr(254) min_role_id = random.sample(roles.values(), 1)[0] - print "UpdateAttribute(%d)" % attribute_id, - UpdateAttribute(admin, attribute_id, - {'description': description, - 'min_role_id': min_role_id}) - attribute = GetAttributes(admin, [attribute_id])[0] + print "UpdateSliceAttributeType(%d)" % attribute_type_id, + UpdateSliceAttributeType(admin, attribute_type_id, + {'description': description, + 'min_role_id': min_role_id}) + attribute_type = GetSliceAttributeTypes(admin, [attribute_type_id])[0] for key in 'min_role_id', 'description': - assert unicmp(attribute[key], locals()[key]) + assert unicmp(attribute_type[key], locals()[key]) print "=> OK" # Add slices and slice attributes @@ -488,18 +484,18 @@ for site in sites: # XXX Add people to slice # Set slice/sliver attributes - for attribute_id in attribute_ids: + for attribute_type_id in attribute_type_ids: value = randstr(254) # Make it a sliver attribute with 50% probability # node_id = random.sample(node_ids + [None] * len(node_ids), 1)[0] node_id = None # Add slice attribute - print "AddSliceAttribute(%s, %d)" % (name, attribute_id), + print "AddSliceAttribute(%s, %d)" % (name, attribute_type_id), if node_id is None: - slice_attribute_id = AddSliceAttribute(admin, slice_id, attribute_id, value) + slice_attribute_id = AddSliceAttribute(admin, slice_id, attribute_type_id, value) else: - slice_attribute_id = AddSliceAttribute(admin, slice_id, attribute_id, value, node_id) + slice_attribute_id = AddSliceAttribute(admin, slice_id, attribute_type_id, value, node_id) # Should return a unique slice_attribute_id assert slice_attribute_id not in slice_attribute_ids @@ -508,8 +504,8 @@ for site in sites: # Check slice attribute print "GetSliceAttributes(%d)" % slice_attribute_id, - slice_attribute = GetSliceAttributes(admin, slice_id, [slice_attribute_id])[0] - for key in 'attribute_id', 'slice_id', 'node_id', 'slice_attribute_id', 'value': + slice_attribute = GetSliceAttributes(admin, [slice_attribute_id])[0] + for key in 'attribute_type_id', 'slice_id', 'node_id', 'slice_attribute_id', 'value': assert unicmp(slice_attribute[key], locals()[key]) print "=> OK" @@ -518,8 +514,8 @@ for site in sites: description = randstr(2048) print "UpdateSliceAttribute(%s)" % name, UpdateSliceAttribute(admin, slice_attribute_id, value) - slice_attribute = GetSliceAttributes(admin, slice_id, [slice_attribute_id])[0] - for key in 'attribute_id', 'slice_id', 'node_id', 'slice_attribute_id', 'value': + slice_attribute = GetSliceAttributes(admin, [slice_attribute_id])[0] + for key in 'attribute_type_id', 'slice_id', 'node_id', 'slice_attribute_id', 'value': assert unicmp(slice_attribute[key], locals()[key]) print "=> OK" @@ -548,20 +544,20 @@ print "GetSlices", assert not GetSlices(admin, slice_ids) print "=> []" -# Delete attributes -for attribute_id in attribute_ids: +# Delete slice attribute types +for attribute_type_id in attribute_type_ids: # Delete attribute - print "DeleteAttribute(%d)" % attribute_id, - DeleteAttribute(admin, attribute_id) - assert not GetAttributes(admin, [attribute_id]) + print "DeleteAttribute(%d)" % attribute_type_id, + DeleteSliceAttributeType(admin, attribute_type_id) + assert not GetSliceAttributeTypes(admin, [attribute_type_id]) # Make sure it really deleted it - attributes = GetAttributes(admin, attribute_ids) - assert attribute_id not in [attribute['attribute_id'] for attribute in attributes] + attribute_types = GetSliceAttributeTypes(admin, attribute_type_ids) + assert attribute_type_id not in [attribute_type['attribute_type_id'] for attribute_type in attribute_types] print "=> OK" print "GetAttributes", -assert not GetAttributes(admin, attribute_ids) +assert not GetSliceAttributeTypes(admin, attribute_type_ids) print "=> []" # Delete node networks diff --git a/planetlab4.sql b/planetlab4.sql index c4cbe4b..9fefda0 100644 --- a/planetlab4.sql +++ b/planetlab4.sql @@ -9,7 +9,7 @@ -- -- Copyright (C) 2006 The Trustees of Princeton University -- --- $Id: planetlab4.sql,v 1.10 2006/10/11 20:49:39 mlhuang Exp $ +-- $Id: planetlab4.sql,v 1.11 2006/10/13 15:07:24 tmack Exp $ -- -------------------------------------------------------------------------------- @@ -506,8 +506,8 @@ GROUP BY person_id; -------------------------------------------------------------------------------- -- Slice attribute types -CREATE TABLE attributes ( - attribute_id serial PRIMARY KEY, -- Attribute type identifier +CREATE TABLE slice_attribute_types ( + attribute_type_id serial PRIMARY KEY, -- Attribute type identifier name text UNIQUE NOT NULL, -- Attribute name description text, -- Attribute description min_role_id integer REFERENCES roles DEFAULT 10 -- If set, minimum (least powerful) role that can set or change this attribute @@ -518,7 +518,7 @@ CREATE TABLE slice_attribute ( slice_attribute_id serial PRIMARY KEY, -- Slice attribute identifier slice_id integer REFERENCES slices NOT NULL, -- Slice identifier node_id integer REFERENCES nodes, -- Sliver attribute if set - attribute_id integer REFERENCES attributes NOT NULL, -- Attribute type identifier + attribute_type_id integer REFERENCES slice_attribute_types NOT NULL, -- Attribute type identifier value text ) WITH OIDS; CREATE INDEX slice_attribute_slice_id_idx ON slice_attribute (slice_id); @@ -745,13 +745,13 @@ SELECT slice_attribute.slice_attribute_id, slice_attribute.slice_id, slice_attribute.node_id, -attributes.attribute_id, -attributes.name, -attributes.description, -attributes.min_role_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 attributes USING (attribute_id); +INNER JOIN slice_attribute_types USING (attribute_type_id); -------------------------------------------------------------------------------- -- Built-in maintenance account and default site -- 2.43.0