- make Add() calling convention consistent among all functions that
authorMark Huang <mlhuang@cs.princeton.edu>
Tue, 24 Oct 2006 20:02:22 +0000 (20:02 +0000)
committerMark Huang <mlhuang@cs.princeton.edu>
Tue, 24 Oct 2006 20:02:22 +0000 (20:02 +0000)
  deal with objects, e.g. Add(auth, object_fields)
  - some functions such as AddSiteAddress and AddPersonKey may still
    take an additional argument, e.g. AddSiteAddress(auth, site, address)
- to support this convention, clear optional bit on mandatory
  object_fields, and set it for Update() functions

50 files changed:
PLC/AddressTypes.py
PLC/BootStates.py
PLC/ConfFiles.py
PLC/KeyTypes.py
PLC/Keys.py
PLC/Methods/AddAddressType.py
PLC/Methods/AddConfFile.py
PLC/Methods/AddNode.py
PLC/Methods/AddNodeGroup.py
PLC/Methods/AddNodeNetwork.py
PLC/Methods/AddPCU.py
PLC/Methods/AddPerson.py
PLC/Methods/AddPersonKey.py
PLC/Methods/AddSite.py
PLC/Methods/AddSiteAddress.py
PLC/Methods/AddSlice.py
PLC/Methods/AddSliceAttributeType.py
PLC/Methods/AdmAddAddressType.py
PLC/Methods/AdmAddNode.py
PLC/Methods/AdmAddNodeGroup.py
PLC/Methods/AdmAddNodeNetwork.py
PLC/Methods/AdmAddPerson.py
PLC/Methods/AdmAddPersonKey.py
PLC/Methods/AdmAddSite.py
PLC/Methods/DeleteConfFileFromNode.py [new file with mode: 0644]
PLC/Methods/DeleteConfFileFromNodeGroup.py [new file with mode: 0644]
PLC/Methods/GetSlivers.py
PLC/Methods/SliceCreate.py
PLC/Methods/UpdateAddress.py
PLC/Methods/UpdateAddressType.py
PLC/Methods/UpdateConfFile.py
PLC/Methods/UpdateKey.py
PLC/Methods/UpdateNode.py
PLC/Methods/UpdateNodeGroup.py
PLC/Methods/UpdateNodeNetwork.py
PLC/Methods/UpdatePerson.py
PLC/Methods/UpdateSite.py
PLC/Methods/UpdateSlice.py
PLC/Methods/UpdateSliceAttributeType.py
PLC/Methods/__init__.py
PLC/NetworkMethods.py
PLC/NetworkTypes.py
PLC/NodeGroups.py
PLC/NodeNetworks.py
PLC/Nodes.py
PLC/PCUs.py
PLC/Persons.py
PLC/Roles.py
PLC/SliceAttributeTypes.py
PLC/Slices.py

index dbb844a..889b79d 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: AddressTypes.py,v 1.3 2006/10/10 21:52:08 mlhuang Exp $
+# $Id: AddressTypes.py,v 1.4 2006/10/20 17:43:30 mlhuang Exp $
 #
 
 from types import StringTypes
@@ -23,16 +23,13 @@ class AddressType(Row):
     join_tables = ['address_address_type']
     fields = {
         'address_type_id': Parameter(int, "Address type identifier"),
-        'name': Parameter(str, "Address type", max = 20),
+        'name': Parameter(str, "Address type", max = 20, optional = False),
         'description': Parameter(str, "Address type description", max = 254),
         }
 
     def validate_name(self, name):
-       # Remove leading and trailing spaces
-       name = name.strip()
-
-       # Make sure name is not blank after we removed the spaces
-        if not name:
+       # Make sure name is not blank
+        if not len(name):
             raise PLCInvalidArgument, "Address type must be specified"
        
        # Make sure address type does not already exist
index 6757ca1..5384634 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: BootStates.py,v 1.4 2006/10/10 21:54:20 mlhuang Exp $
+# $Id: BootStates.py,v 1.5 2006/10/20 17:43:55 mlhuang Exp $
 #
 
 from PLC.Faults import *
@@ -25,11 +25,8 @@ class BootState(Row):
         }
 
     def validate_boot_state(self, name):
-       # Remove leading and trailing spaces
-       name = name.strip()
-
-       # Make sure name is not blank after we removed the spaces
-        if not name:
+       # Make sure name is not blank
+        if not len(name):
             raise PLCInvalidArgument, "Boot state must be specified"
        
        # Make sure boot state does not alredy exist
index b6cd64c..0e57913 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: ConfFiles.py,v 1.2 2006/10/23 20:39:16 mlhuang Exp $
+# $Id: ConfFiles.py,v 1.3 2006/10/24 13:46:43 mlhuang Exp $
 #
 
 from PLC.Faults import *
@@ -25,8 +25,8 @@ class ConfFile(Row):
     fields = {
         'conf_file_id': Parameter(int, "Configuration file identifier"),
         'enabled': Parameter(bool, "Configuration file is active"),
-        'source': Parameter(str, "Relative path on the boot server where file can be downloaded", max = 255),
-        'dest': Parameter(str, "Absolute path where file should be installed", max = 255),
+        'source': Parameter(str, "Relative path on the boot server where file can be downloaded", max = 255, optional = False),
+        'dest': Parameter(str, "Absolute path where file should be installed", max = 255, optional = False),
         'file_permissions': Parameter(str, "chmod(1) permissions", max = 20),
         'file_owner': Parameter(str, "chown(1) owner", max = 50),
         'file_group': Parameter(str, "chgrp(1) owner", max = 50),
index 7145020..6ac7111 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: KeyTypes.py,v 1.1 2006/10/10 22:09:31 mlhuang Exp $
+# $Id: KeyTypes.py,v 1.2 2006/10/20 17:44:57 mlhuang Exp $
 #
 
 from PLC.Faults import *
@@ -25,11 +25,8 @@ class KeyType(Row):
         }
 
     def validate_key_type(self, name):
-       # Remove leading and trailing spaces
-       name = name.strip()
-
-       # Make sure name is not blank after we removed the spaces
-        if not name:
+       # Make sure name is not blank
+        if not len(name):
             raise PLCInvalidArgument, "Key type must be specified"
        
        # Make sure key type does not alredy exist
index 37fddbd..542224d 100644 (file)
@@ -28,8 +28,6 @@ class Key(Row):
        return key_type
 
     def validate_key(self, key):
-        key = key.strip()
-
        # Key must not be blacklisted
        rows = self.api.db.selectall("SELECT 1 from keys" \
                                     " WHERE key = %(key)s" \
index 075fca2..373f804 100644 (file)
@@ -4,7 +4,7 @@ from PLC.Parameter import Parameter, Mixed
 from PLC.AddressTypes import AddressType, AddressTypes
 from PLC.Auth import PasswordAuth
 
-can_update = lambda (field, value): field in ['description']
+can_update = lambda (field, value): field not in ['address_type_id']
 
 class AddAddressType(Method):
     """
@@ -16,12 +16,11 @@ class AddAddressType(Method):
 
     roles = ['admin']
 
-    update_fields = dict(filter(can_update, AddressType.fields.items()))
+    address_type_fields = dict(filter(can_update, AddressType.fields.items()))
 
     accepts = [
         PasswordAuth(),
-        AddressType.fields['name'],
-        update_fields
+        address_type_fields
         ]
 
     returns = Parameter(int, 'New address_type_id (> 0) if successful')
@@ -30,11 +29,11 @@ class AddAddressType(Method):
     object_type = 'AddressType'
     object_ids = []
 
-    def call(self, auth, name, address_type_fields = {}):
+    def call(self, auth, address_type_fields = {}):
         address_type_fields = dict(filter(can_update, address_type_fields.items()))
         address_type = AddressType(self.api, address_type_fields)
-        address_type['name'] = name
         address_type.sync()
+
        self.object_ids = [address_type['address_type_id']]
         
        return address_type['address_type_id']
index 9641dd2..d258ab7 100644 (file)
@@ -17,13 +17,11 @@ class AddConfFile(Method):
 
     roles = ['admin']
 
-    update_fields = dict(filter(can_update, ConfFile.fields.items()))
+    conf_file_fields = dict(filter(can_update, ConfFile.fields.items()))
 
     accepts = [
         PasswordAuth(),
-        ConfFile.fields['source'],
-        ConfFile.fields['dest'],
-        update_fields
+        conf_file_fields
         ]
 
     returns = Parameter(int, '1 if successful')
@@ -32,12 +30,11 @@ class AddConfFile(Method):
     object_type = 'ConfFile'
     object_ids = []
 
-    def call(self, auth, source, dest, conf_file_fields = {}):
+    def call(self, auth, conf_file_fields = {}):
         conf_file_fields = dict(filter(can_update, conf_file_fields.items()))
         conf_file = ConfFile(self.api, conf_file_fields)
-        conf_file['source'] = source
-        conf_file['dest'] = dest
         conf_file.sync()
+
        self.object_ids = [conf_file['conf_file_id']]
 
         return 1
index a61fad6..a931c02 100644 (file)
@@ -7,7 +7,7 @@ from PLC.Sites import Site, Sites
 from PLC.Auth import PasswordAuth
 
 can_update = lambda (field, value): field in \
-             ['boot_state', 'model', 'version']
+             ['hostname', 'site_id', 'boot_state', 'model', 'version']
 
 class AddNode(Method):
     """
@@ -22,14 +22,11 @@ class AddNode(Method):
 
     roles = ['admin', 'pi', 'tech']
 
-    update_fields = dict(filter(can_update, Node.fields.items()))
+    node_fields = dict(filter(can_update, Node.fields.items()))
 
     accepts = [
         PasswordAuth(),
-        Mixed(Site.fields['site_id'],
-              Site.fields['login_base']),
-        Node.fields['hostname'],
-        update_fields
+        node_fields
         ]
 
     returns = Parameter(int, 'New node_id (> 0) if successful')
@@ -38,11 +35,11 @@ class AddNode(Method):
     object_type = 'Node'
     object_ids = []
 
-    def call(self, auth, site_id_or_login_base, hostname, node_fields = {}):
+    def call(self, auth, node_fields = {}):
         node_fields = dict(filter(can_update, node_fields.items()))
         
         # Get site information
-        sites = Sites(self.api, [site_id_or_login_base])
+        sites = Sites(self.api, [node_fields['site_id']])
         if not sites:
             raise PLCInvalidArgument, "No such site"
 
@@ -61,9 +58,8 @@ class AddNode(Method):
                 assert self.caller['person_id'] in site['person_ids']
 
         node = Node(self.api, node_fields)
-        node['hostname'] = hostname
-        node['site_id'] = site['site_id']
         node.sync()
-       self.object_ids = [node['node_id']]     
+
+       self.object_ids = [site['site_id'], node['node_id']]    
 
         return node['node_id']
index 75d4d91..34a73d2 100644 (file)
@@ -5,7 +5,7 @@ from PLC.NodeGroups import NodeGroup, NodeGroups
 from PLC.Auth import PasswordAuth
 
 can_update = lambda (field, value): field in \
-             ['description']
+             ['name', 'description']
 
 class AddNodeGroup(Method):
     """
@@ -17,12 +17,11 @@ class AddNodeGroup(Method):
 
     roles = ['admin']
 
-    update_fields = dict(filter(can_update, NodeGroup.fields.items()))
+    nodegroup_fields = dict(filter(can_update, NodeGroup.fields.items()))
 
     accepts = [
         PasswordAuth(),
-        NodeGroup.fields['name'],
-        update_fields
+        nodegroup_fields
         ]
 
     returns = Parameter(int, 'New nodegroup_id (> 0) if successful')
@@ -31,11 +30,11 @@ class AddNodeGroup(Method):
     object_type = 'NodeGroup'
     object_ids = []
 
-    def call(self, auth, name, nodegroup_fields = {}):
+    def call(self, auth, nodegroup_fields = {}):
         nodegroup_fields = dict(filter(can_update, nodegroup_fields.items()))
         nodegroup = NodeGroup(self.api, nodegroup_fields)
-        nodegroup['name'] = name
         nodegroup.sync()
+
        self.object_ids = [nodegroup['nodegroup_id']]
 
         return nodegroup['nodegroup_id']
index 16e3782..da08581 100644 (file)
@@ -5,9 +5,7 @@ from PLC.Nodes import Node, Nodes
 from PLC.NodeNetworks import NodeNetwork, NodeNetworks
 from PLC.Auth import PasswordAuth
 
-can_update = lambda (field, value): field in \
-             ['ip', 'mac', 'gateway', 'network', 'broadcast', 'netmask',
-              'dns1', 'dns2', 'hostname', 'bwlimit', 'is_primary']
+can_update = lambda (field, value): field not in ['nodenetwork_id']
 
 class AddNodeNetwork(Method):
     """
@@ -27,14 +25,11 @@ class AddNodeNetwork(Method):
 
     roles = ['admin', 'pi', 'tech']
 
-    update_fields = dict(filter(can_update, NodeNetwork.fields.items()))
+    nodenetwork_fields = dict(filter(can_update, NodeNetwork.fields.items()))
 
     accepts = [
         PasswordAuth(),
-        Node.fields['node_id'],
-        NodeNetwork.fields['method'],
-        NodeNetwork.fields['type'],
-        update_fields
+        nodenetwork_fields
         ]
 
     returns = Parameter(int, 'New nodenetwork_id (> 0) if successful')
@@ -43,11 +38,11 @@ class AddNodeNetwork(Method):
     object_type = 'NodeNetwork'
     object_ids = []
 
-    def call(self, auth, node_id, method, type, nodenetwork_fields = {}):
+    def call(self, auth, nodenetwork_fields = {}):
         nodenetwork_fields = dict(filter(can_update, nodenetwork_fields.items()))
 
         # Check if node exists
-        nodes = Nodes(self.api, [node_id]).values()
+        nodes = Nodes(self.api, [nodenetwork_fields['node_id']]).values()
         if not nodes:
             raise PLCInvalidArgument, "No such node"
        node = nodes[0]
@@ -63,10 +58,8 @@ class AddNodeNetwork(Method):
 
         # Add node network
        nodenetwork = NodeNetwork(self.api, nodenetwork_fields)
-        nodenetwork['node_id'] = node_id
-       nodenetwork['method'] = method
-        nodenetwork['type'] = type
         nodenetwork.sync()
-       self.object_ids = [nodenetwork['nodenetwork_id']]       
+
+       self.object_ids = [node['node_id'], nodenetwork['nodenetwork_id']]      
 
         return nodenetwork['nodenetwork_id']
index d311e37..2534079 100644 (file)
@@ -6,7 +6,8 @@ from PLC.Auth import PasswordAuth
 from PLC.Sites import Site, Sites
 
 can_update = lambda (field, value): field in \
-             ['hostname', 'protocol',
+             ['site_id',
+              'ip', 'hostname', 'protocol',
               'username', 'password',
               'model', 'notes']
 
@@ -23,14 +24,11 @@ class AddPCU(Method):
 
     roles = ['admin', 'pi', 'tech']
 
-    update_fields = dict(filter(can_update, PCU.fields.items()))
+    pcu_fields = dict(filter(can_update, PCU.fields.items()))
 
     accepts = [
         PasswordAuth(),
-        Mixed(Site.fields['site_id'],
-              Site.fields['login_base']),
-        PCU.fields['ip'],
-        update_fields
+        pcu_fields
         ]
 
     returns = Parameter(int, 'New pcu_id (> 0) if successful')
@@ -39,11 +37,11 @@ class AddPCU(Method):
     object_type = 'PCU'
     object_ids = []
 
-    def call(self, auth, site_id_or_login_base, ip, pcu_fields = {}):
+    def call(self, auth, pcu_fields = {}):
         pcu_fields = dict(filter(can_update, pcu_fields.items()))
 
         # Get associated site details
-        sites = Sites(self.api, [site_id_or_login_base]).values()
+        sites = Sites(self.api, [pcu_fields['site_id']]).values()
         if not sites:
             raise PLCInvalidArgument, "No such site"
         site = sites[0]
@@ -53,9 +51,8 @@ class AddPCU(Method):
                 raise PLCPermissionDenied, "Not allowed to add a PCU to that site"
 
         pcu = PCU(self.api, pcu_fields)
-        pcu['site_id'] = site['site_id']
-        pcu['ip'] = ip
         pcu.sync()
-       self.object_ids = [pcu['pcu_id']]       
+
+       self.object_ids = [site['site_id'], pcu['pcu_id']]
 
         return pcu['pcu_id']
index a2899de..6af541b 100644 (file)
@@ -5,7 +5,8 @@ from PLC.Persons import Person, Persons
 from PLC.Auth import PasswordAuth
 
 can_update = lambda (field, value): field in \
-             ['title', 'email', 'password', 'phone', 'url', 'bio']
+             ['first_name', 'last_name', 'title',
+              'email', 'password', 'phone', 'url', 'bio']
 
 class AddPerson(Method):
     """
@@ -20,13 +21,11 @@ class AddPerson(Method):
 
     roles = ['admin', 'pi']
 
-    update_fields = dict(filter(can_update, Person.fields.items()))
+    person_fields = dict(filter(can_update, Person.fields.items()))
 
     accepts = [
         PasswordAuth(),
-        Person.fields['first_name'],
-        Person.fields['last_name'],
-        update_fields
+        person_fields
         ]
 
     returns = Parameter(int, 'New person_id (> 0) if successful')
@@ -35,13 +34,11 @@ class AddPerson(Method):
     object_type = 'Person'
     object_ids = []
 
-    def call(self, auth, first_name, last_name, person_fields = {}):
+    def call(self, auth, person_fields = {}):
         person_fields = dict(filter(can_update, person_fields.items()))
         person = Person(self.api, person_fields)
-        person['first_name'] = first_name
-        person['last_name'] = last_name
-        person['enabled'] = False
         person.sync()
+
        self.object_ids = [person['person_id']]
 
         return person['person_id']
index edad2cb..3749ecd 100644 (file)
@@ -5,6 +5,8 @@ from PLC.Keys import Key, Keys
 from PLC.Persons import Person, Persons
 from PLC.Auth import PasswordAuth
 
+can_update = lambda (field, value): field not in ['key_id']
+
 class AddPersonKey(Method):
     """
     Adds a new key to the specified account.
@@ -16,12 +18,13 @@ class AddPersonKey(Method):
 
     roles = ['admin', 'pi', 'tech', 'user']
 
+    key_fields = dict(filter(can_update, Key.fields.items()))
+
     accepts = [
         PasswordAuth(),
         Mixed(Person.fields['person_id'],
               Person.fields['email']),
-        Key.fields['key_type'],
-        Key.fields['key']
+        key_fields
         ]
 
     returns = Parameter(int, 'New key_id (> 0) if successful')
@@ -30,7 +33,9 @@ class AddPersonKey(Method):
     object_type = 'Key'
     object_ids = []
 
-    def call(self, auth, person_id_or_email, key_type, key_value):
+    def call(self, auth, person_id_or_email, key_fields):
+        key_fields = dict(filter(can_update, key_fields.items()))
+
         # Get account details
         persons = Persons(self.api, [person_id_or_email]).values()
         if not persons:
@@ -42,12 +47,10 @@ class AddPersonKey(Method):
             if person['person_id'] != self.caller['person_id']:
                 raise PLCPermissionDenied, "You may only modify your own keys"
 
-        key = Key(self.api)
-        key['person_id'] = person['person_id']
-        key['key_type'] = key_type
-        key['key'] = key_value
+        key = Key(self.api, key_fields)
         key.sync(commit = False)
         person.add_key(key, commit = True)
-        self.object_ids = [key['key_id']]
+
+        self.object_ids = [person['person_id'], key['key_id']]
 
         return key['key_id']
index 8f77d86..10d6585 100644 (file)
@@ -5,7 +5,8 @@ from PLC.Sites import Site, Sites
 from PLC.Auth import PasswordAuth
 
 can_update = lambda (field, value): field in \
-             ['is_public', 'latitude', 'longitude', 'url']
+             ['name', 'abbreviated_name', 'login_base',
+              'is_public', 'latitude', 'longitude', 'url']
 
 class AddSite(Method):
     """
@@ -18,14 +19,11 @@ class AddSite(Method):
 
     roles = ['admin']
 
-    update_fields = dict(filter(can_update, Site.fields.items()))
+    site_fields = dict(filter(can_update, Site.fields.items()))
 
     accepts = [
         PasswordAuth(),
-        Site.fields['name'],
-        Site.fields['abbreviated_name'],
-        Site.fields['login_base'],
-        update_fields
+        site_fields
         ]
 
     returns = Parameter(int, 'New site_id (> 0) if successful')
@@ -34,13 +32,11 @@ class AddSite(Method):
     object_type = 'Site'
     object_ids = []
 
-    def call(self, auth, name, abbreviated_name, login_base, site_fields = {}):
+    def call(self, auth, site_fields):
         site_fields = dict(filter(can_update, site_fields.items()))
         site = Site(self.api, site_fields)
-        site['name'] = name
-        site['abbreviated_name'] = abbreviated_name
-        site['login_base'] = login_base
         site.sync()
+
        self.object_ids = [site['site_id']]
         
        return site['site_id']
index 662250c..4524996 100644 (file)
@@ -21,13 +21,13 @@ class AddSiteAddress(Method):
 
     roles = ['admin', 'pi']
 
-    update_fields = dict(filter(can_update, Address.fields.items()))
+    address_fields = dict(filter(can_update, Address.fields.items()))
 
     accepts = [
         PasswordAuth(),
         Mixed(Site.fields['site_id'],
               Site.fields['login_base']),
-        update_fields
+        address_fields
         ]
 
     returns = Parameter(int, 'New address_id (> 0) if successful')
@@ -50,8 +50,9 @@ class AddSiteAddress(Method):
                 raise PLCPermissionDenied, "Address must be associated with one of your sites"
 
         address = Address(self.api, address_fields)
-        address['site_id'] = site['site_id']
-        address.sync()
-       self.object_ids = [address['address_id']]
+        address.sync(commit = False)
+        site.add_address(address, commit = True)
+
+       self.object_ids = [site['site_id'], address['address_id']]
 
         return address['address_id']
index 58bce63..0116803 100644 (file)
@@ -8,7 +8,7 @@ from PLC.Auth import PasswordAuth
 from PLC.Sites import Site, Sites
 
 can_update = lambda (field, value): field in \
-             ['instantiation', 'url', 'description', 'max_nodes']
+             ['name', 'instantiation', 'url', 'description', 'max_nodes']
 
 class AddSlice(Method):
     """
@@ -29,12 +29,11 @@ class AddSlice(Method):
 
     roles = ['admin', 'pi']
 
-    update_fields = dict(filter(can_update, Slice.fields.items()))
+    slice_fields = dict(filter(can_update, Slice.fields.items()))
 
     accepts = [
         PasswordAuth(),
-        Slice.fields['name'],
-        update_fields
+        slice_fields
         ]
 
     returns = Parameter(int, 'New slice_id (> 0) if successful')
@@ -43,13 +42,14 @@ class AddSlice(Method):
     object_type = 'Slice'
     object_ids = []
 
-    def call(self, auth, name, slice_fields = {}):
+    def call(self, auth, slice_fields = {}):
         slice_fields = dict(filter(can_update, slice_fields.items()))
 
         # 1. Lowercase.
         # 2. Begins with login_base (only letters).
         # 3. Then single underscore after login_base.
         # 4. Then letters, numbers, or underscores.
+        name = slice_fields['name']
         good_name = r'^[a-z]+_[a-z0-9_]+$'
         if not name or \
            not re.match(good_name, name):
@@ -71,9 +71,9 @@ class AddSlice(Method):
 
         slice = Slice(self.api, slice_fields)
         slice['creator_person_id'] = self.caller['person_id']
-        slice['name'] = name
         slice['site_id'] = site['site_id']
         slice.sync()
+
        self.object_ids = [slice['slice_id']]
 
         return slice['slice_id']
index c1d3fce..8ed1d58 100644 (file)
@@ -5,7 +5,7 @@ from PLC.SliceAttributeTypes import SliceAttributeType, SliceAttributeTypes
 from PLC.Auth import PasswordAuth
 
 can_update = lambda (field, value): field in \
-             ['description', 'min_role_id']
+             ['name', 'description', 'min_role_id']
 
 class AddSliceAttributeType(Method):
     """
@@ -18,12 +18,11 @@ class AddSliceAttributeType(Method):
 
     roles = ['admin']
 
-    update_fields = dict(filter(can_update, SliceAttributeType.fields.items()))
+    attribute_type_fields = dict(filter(can_update, SliceAttributeType.fields.items()))
 
     accepts = [
         PasswordAuth(),
-        SliceAttributeType.fields['name'],
-        update_fields
+        attribute_type_fields
         ]
 
     returns = Parameter(int, 'New attribute_id (> 0) if successful')
@@ -32,11 +31,11 @@ class AddSliceAttributeType(Method):
     object_type = 'SliceAttributeType'
     object_ids = []
 
-    def call(self, auth, name, attribute_type_fields = {}):
+    def call(self, auth, 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()
+
        self.object_ids = [attribute_type['attribute_type_id']]
 
         return attribute_type['attribute_type_id']
index d969dae..fb56b49 100644 (file)
@@ -1,3 +1,8 @@
+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 PasswordAuth
 from PLC.Methods.AddAddressType import AddAddressType
 
 class AdmAddAddressType(AddAddressType):
@@ -6,3 +11,11 @@ class AdmAddAddressType(AddAddressType):
     """
 
     status = "deprecated"
+
+    accepts = [
+        PasswordAuth(),
+        AddressType.fields['name']
+        ]
+
+    def call(self, auth, name):
+        return AddAddressType.call(self, auth, {'name': name})
index 8026a8f..77bc9f1 100644 (file)
@@ -6,6 +6,9 @@ from PLC.Sites import Site, Sites
 from PLC.Auth import PasswordAuth
 from PLC.Methods.AddNode import AddNode
 
+can_update = lambda (field, value): field in \
+             ['model', 'version']
+
 class AdmAddNode(AddNode):
     """
     Deprecated. See AddNode.
@@ -13,15 +16,18 @@ class AdmAddNode(AddNode):
 
     status = "deprecated"
 
+    node_fields = dict(filter(can_update, Node.fields.items()))
+
     accepts = [
         PasswordAuth(),
-        Mixed(Site.fields['site_id'],
-              Site.fields['login_base']),
+        Site.fields['site_id'],
         Node.fields['hostname'],
         Node.fields['boot_state'],
-        AddNode.update_fields
+        node_fields
         ]
 
-    def call(self, auth, site_id_or_login_base, hostname, 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, site_id_or_login_base, hostname, node_fields)
+        return AddNode.call(self, auth, node_fields)
index 1ecb9be..03faa7b 100644 (file)
@@ -19,4 +19,4 @@ class AdmAddNodeGroup(AddNodeGroup):
         ]
 
     def call(self, auth, name, description):
-        return AddNodeGroup.call(self, auth, name, {'description': description})
+        return AddNodeGroup.call(self, auth, {'name': name, 'description': description})
index c578417..58c9874 100644 (file)
@@ -1,8 +1,31 @@
+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 PasswordAuth
 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 = [
+        PasswordAuth(),
+        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)
index 7858b8f..c43b4d9 100644 (file)
@@ -1,8 +1,30 @@
+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 PasswordAuth
 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 = [
+        PasswordAuth(),
+        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)
index e6c5f77..b30fe14 100644 (file)
@@ -24,4 +24,5 @@ class AdmAddPersonKey(AddPersonKey):
         ]
 
     def call(self, auth, person_id_or_email, key_type, key_value, is_primary):
-        return AddPersonKey.call(self, auth, person_id_or_email, key_type, key_value)
+        key_fields = {'key_type': key_type, 'key_value': key_value}
+        return AddPersonKey.call(self, auth, person_id_or_email, key_fields)
index d49c070..fa85a4e 100644 (file)
@@ -1,8 +1,32 @@
+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 PasswordAuth
 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 = [
+        PasswordAuth(),
+        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/DeleteConfFileFromNode.py b/PLC/Methods/DeleteConfFileFromNode.py
new file mode 100644 (file)
index 0000000..bd4d01a
--- /dev/null
@@ -0,0 +1,51 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.ConfFiles import ConfFile, ConfFiles
+from PLC.Nodes import Node, Nodes
+from PLC.Auth import PasswordAuth
+
+class DeleteConfFileFromNode(Method):
+    """
+    Deletes a configuration file from the specified node. If the node
+    is not linked to the configuration file, no errors are returned.
+
+    Returns 1 if successful, faults otherwise.
+    """
+
+    roles = ['admin']
+
+    accepts = [
+        PasswordAuth(),
+        ConfFile.fields['conf_file_id'],
+        Mixed(Node.fields['node_id'],
+              Node.fields['hostname'])
+        ]
+
+    returns = Parameter(int, '1 if successful')
+
+    event_type = 'DeleteFrom'
+    object_type = 'ConfFile'
+    object_ids = []
+
+    def call(self, auth, conf_file_id, node_id_or_hostname):
+       # Get configuration file
+        conf_files = ConfFiles(self.api, [conf_file_id])
+        if not conf_files:
+            raise PLCInvalidArgument, "No such configuration file"
+        conf_file = conf_files.values()[0]
+
+        # Get node
+       nodes = Nodes(self.api, [node_id_or_hostname])
+       if not nodes:
+               raise PLCInvalidArgument, "No such node"
+       node = nodes.values()[0]
+       
+       # Link configuration file to node
+        if node['node_id'] in conf_file['node_ids']:
+            conf_file.remove_node(node)
+
+        # Log affected objects
+        self.object_ids = [conf_file_id, node['node_id']]
+
+        return 1
diff --git a/PLC/Methods/DeleteConfFileFromNodeGroup.py b/PLC/Methods/DeleteConfFileFromNodeGroup.py
new file mode 100644 (file)
index 0000000..183d431
--- /dev/null
@@ -0,0 +1,51 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.ConfFiles import ConfFile, ConfFiles
+from PLC.NodeGroups import NodeGroup, NodeGroups
+from PLC.Auth import PasswordAuth
+
+class DeleteConfFileFromNodeGroup(Method):
+    """
+    Deletes a configuration file from the specified nodegroup. If the nodegroup
+    is not linked to the configuration file, no errors are returned.
+
+    Returns 1 if successful, faults otherwise.
+    """
+
+    roles = ['admin']
+
+    accepts = [
+        PasswordAuth(),
+        ConfFile.fields['conf_file_id'],
+        Mixed(NodeGroup.fields['nodegroup_id'],
+              NodeGroup.fields['name'])
+        ]
+
+    returns = Parameter(int, '1 if successful')
+
+    event_type = 'DeleteFrom'
+    object_type = 'ConfFile'
+    object_ids = []
+
+    def call(self, auth, conf_file_id, nodegroup_id_or_name):
+       # Get configuration file
+        conf_files = ConfFiles(self.api, [conf_file_id])
+        if not conf_files:
+            raise PLCInvalidArgument, "No such configuration file"
+        conf_file = conf_files.values()[0]
+
+        # Get nodegroup
+       nodegroups = NodeGroups(self.api, [nodegroup_id_or_name])
+       if not nodegroups:
+               raise PLCInvalidArgument, "No such nodegroup"
+       nodegroup = nodegroups.values()[0]
+       
+       # Link configuration file to nodegroup
+        if nodegroup['nodegroup_id'] in conf_file['nodegroup_ids']:
+            conf_file.remove_nodegroup(nodegroup)
+
+        # Log affected objects
+        self.object_ids = [conf_file_id, nodegroup['nodegroup_id']]
+
+        return 1
index 032a754..b870f06 100644 (file)
@@ -35,7 +35,7 @@ class GetSlivers(Method):
 
     returns = [{
         'timestamp': Parameter(int, "Timestamp of this call, in seconds since UNIX epoch"),
-        'id': Node.fields['node_id'],
+        'node_id': Node.fields['node_id'],
         'hostname': Node.fields['hostname'],
         'boot_state': Node.fields['boot_state'],
         'networks': [NodeNetwork.fields],
@@ -43,7 +43,7 @@ class GetSlivers(Method):
         'conf_files': [ConfFile.fields],
         'slivers': [{
             'name': Slice.fields['name'],
-            'id': Slice.fields['slice_id'],
+            'slice_id': Slice.fields['slice_id'],
             'instantiation': Slice.fields['instantiation'],
             'expires': Slice.fields['expires'],
             'keys': [{
@@ -167,7 +167,7 @@ class GetSlivers(Method):
 
             nodes.append({
                 'timestamp': timestamp,
-                'id': node['node_id'],
+                'node_id': node['node_id'],
                 'hostname': node['hostname'],
                 'networks': networks,
                 'groups': groups,
index a749454..11a700c 100644 (file)
@@ -1,3 +1,8 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Auth import PasswordAuth
+from PLC.Slices import Slice, Slices
 from PLC.Methods.AddSlice import AddSlice
 
 class SliceCreate(AddSlice):
@@ -6,3 +11,13 @@ class SliceCreate(AddSlice):
     """
 
     status = "deprecated"
+    
+    accepts = [
+        PasswordAuth(),
+        Slice.fields['name'],
+        AddSlice.accepts[1]
+        ]
+
+    def call(self, auth, name, slice_fields = {}):
+        slice_fields['name'] = name
+        return AddSlice.call(self, auth, slice_fields)
index 0cd76ab..e6885d9 100644 (file)
@@ -20,12 +20,14 @@ class UpdateAddress(Method):
 
     roles = ['admin', 'pi']
 
-    update_fields = dict(filter(can_update, Address.fields.items()))
+    address_fields = dict(filter(can_update, Address.fields.items()))
+    for field in address_fields.values():
+        field.optional = True
 
     accepts = [
         PasswordAuth(),
         Address.fields['address_id'],
-        update_fields
+        address_fields
         ]
 
     returns = Parameter(int, '1 if successful')
index 950c311..7e71431 100644 (file)
@@ -16,13 +16,15 @@ class UpdateAddressType(Method):
 
     roles = ['admin']
 
-    update_fields = dict(filter(can_update, AddressType.fields.items()))
+    address_type_fields = dict(filter(can_update, AddressType.fields.items()))
+    for field in address_type_fields.values():
+        field.optional = True
 
     accepts = [
         PasswordAuth(),
         Mixed(AddressType.fields['address_type_id'],
               AddressType.fields['name']),
-        update_fields
+        address_type_fields
         ]
 
     returns = Parameter(int, '1 if successful')
index b3dfc18..f68e0fe 100644 (file)
@@ -17,12 +17,14 @@ class UpdateConfFile(Method):
 
     roles = ['admin']
 
-    update_fields = dict(filter(can_update, ConfFile.fields.items()))
+    conf_file_fields = dict(filter(can_update, ConfFile.fields.items()))
+    for field in conf_file_fields.values():
+        field.optional = True
 
     accepts = [
         PasswordAuth(),
         ConfFile.fields['conf_file_id'],
-        update_fields
+        conf_file_fields
         ]
 
     returns = Parameter(int, '1 if successful')
index 3527908..58dfccb 100644 (file)
@@ -19,12 +19,14 @@ class UpdateKey(Method):
 
     roles = ['admin', 'pi', 'tech', 'user']
 
-    update_fields = dict(filter(can_update, Key.fields.items()))
+    key_fields = dict(filter(can_update, Key.fields.items()))
+    for field in key_fields.values():
+        field.optional = True
 
     accepts = [
         PasswordAuth(),
         Key.fields['key_id'],
-        update_fields
+        key_fields
         ]
 
     returns = Parameter(int, '1 if successful')
index c8be8db..3566a42 100644 (file)
@@ -21,13 +21,15 @@ class UpdateNode(Method):
 
     roles = ['admin', 'pi', 'tech']
 
-    update_fields = dict(filter(can_update, Node.fields.items()))
+    node_fields = dict(filter(can_update, Node.fields.items()))
+    for field in node_fields.values():
+        field.optional = True
 
     accepts = [
         PasswordAuth(),
         Mixed(Node.fields['node_id'],
               Node.fields['hostname']),
-        update_fields
+        node_fields
         ]
 
     returns = Parameter(int, '1 if successful')
index a47591b..e84d98e 100644 (file)
@@ -16,13 +16,15 @@ class UpdateNodeGroup(Method):
 
     roles = ['admin']
 
-    update_fields = dict(filter(can_update, NodeGroup.fields.items()))
+    nodegroup_fields = dict(filter(can_update, NodeGroup.fields.items()))
+    for field in nodegroup_fields.values():
+        field.optional = True
 
     accepts = [
         PasswordAuth(),
         Mixed(NodeGroup.fields['nodegroup_id'],
              NodeGroup.fields['name']),
-        update_fields
+        nodegroup_fields
         ]
 
     returns = Parameter(int, '1 if successful')
index d5ae238..8b4ba85 100644 (file)
@@ -25,13 +25,15 @@ class UpdateNodeNetwork(Method):
 
     roles = ['admin', 'pi', 'tech']
 
-    update_fields = dict(filter(can_update, NodeNetwork.fields.items()))
+    nodenetwork_fields = dict(filter(can_update, NodeNetwork.fields.items()))
+    for field in nodenetwork_fields.values():
+        field.optional = True
 
     accepts = [
         PasswordAuth(),
        Mixed(NodeNetwork.fields['nodenetwork_id'],
              NodeNetwork.fields['ip']),
-       update_fields
+       nodenetwork_fields
         ]
 
     returns = Parameter(int, '1 if successful')
index 36cb2c2..66392fe 100644 (file)
@@ -27,13 +27,15 @@ class UpdatePerson(Method):
 
     roles = ['admin', 'pi', 'user', 'tech']
 
-    update_fields = dict(filter(can_update, Person.fields.items()))
+    person_fields = dict(filter(can_update, Person.fields.items()))
+    for field in person_fields.values():
+        field.optional = True
 
     accepts = [
         PasswordAuth(),
         Mixed(Person.fields['person_id'],
               Person.fields['email']),
-        update_fields
+        person_fields
         ]
 
     returns = Parameter(int, '1 if successful')
index c405f49..e734f60 100644 (file)
@@ -27,13 +27,15 @@ class UpdateSite(Method):
 
     roles = ['admin', 'pi']
 
-    update_fields = dict(filter(can_update, Site.fields.items()))
+    site_fields = dict(filter(can_update, Site.fields.items()))
+    for field in site_fields.values():
+        field.optional = True
 
     accepts = [
         PasswordAuth(),
         Mixed(Site.fields['site_id'],
               Site.fields['login_base']),
-        update_fields
+        site_fields
         ]
 
     returns = Parameter(int, '1 if successful')
index 1dcbd26..058ad5b 100644 (file)
@@ -28,13 +28,15 @@ class UpdateSlice(Method):
 
     roles = ['admin', 'pi', 'user']
 
-    update_fields = dict(filter(can_update, Slice.fields.items()))
+    slice_fields = dict(filter(can_update, Slice.fields.items()))
+    for field in slice_fields.values():
+        field.optional = True
 
     accepts = [
         PasswordAuth(),
         Mixed(Slice.fields['slice_id'],
               Slice.fields['name']),
-        update_fields
+        slice_fields
         ]
 
     returns = Parameter(int, '1 if successful')
index e863b48..7bfe800 100644 (file)
@@ -17,13 +17,15 @@ class UpdateSliceAttributeType(Method):
 
     roles = ['admin']
 
-    update_fields = dict(filter(can_update, SliceAttributeType.fields.items()))
+    attribute_type_fields = dict(filter(can_update, SliceAttributeType.fields.items()))
+    for field in attribute_type_fields.values():
+        field.optional = True
 
     accepts = [
         PasswordAuth(),
         Mixed(SliceAttributeType.fields['attribute_type_id'],
               SliceAttributeType.fields['name']),
-        update_fields
+        attribute_type_fields
         ]
 
     returns = Parameter(int, '1 if successful')
index 2a9ac35..1ebb7bc 100644 (file)
@@ -1 +1 @@
-methods = 'AddAddressType AddAddressTypeToAddress AddBootState AddConfFile AddConfFileToNodeGroup AddConfFileToNode AddKeyType AddNetworkMethod AddNetworkType AddNodeGroup AddNodeNetwork AddNode AddNodeToNodeGroup AddNodeToPCU AddPCU AddPersonKey AddPerson AddPersonToSite AddPersonToSlice AddRole AddRoleToPerson AddSiteAddress AddSite AddSliceAttribute AddSliceAttributeType AddSlice AddSliceToNodes AdmAddAddressType AdmAddNodeGroup AdmAddNodeNetwork AdmAddNode AdmAddNodeToNodeGroup AdmAddPersonKey AdmAddPerson AdmAddPersonToSite AdmAddSitePowerControlUnit AdmAddSite AdmAssociateNodeToPowerControlUnitPort AdmAuthCheck AdmDeleteAddressType AdmDeleteAllPersonKeys AdmDeleteNodeGroup AdmDeleteNodeNetwork AdmDeleteNode AdmDeletePersonKeys AdmDeletePerson AdmDeleteSitePowerControlUnit AdmDeleteSite AdmDisassociatePowerControlUnitPort AdmGenerateNodeConfFile AdmGetAllAddressTypes AdmGetAllKeyTypes AdmGetAllNodeNetworks AdmGetAllRoles AdmGetNodeGroupNodes AdmGetNodeGroups AdmGetNodes AdmGetPersonKeys AdmGetPersonRoles AdmGetPersonSites AdmGetPersons AdmGetPowerControlUnitNodes AdmGetPowerControlUnits AdmGetSiteNodes AdmGetSitePersons AdmGetSitePIs AdmGetSitePowerControlUnits AdmGetSites AdmGetSiteTechContacts AdmGrantRoleToPerson AdmIsPersonInRole AdmQueryConfFile AdmQueryNode AdmQueryPerson AdmQueryPowerControlUnit AdmQuerySite AdmRebootNode AdmRemoveNodeFromNodeGroup AdmRemovePersonFromSite AdmRevokeRoleFromPerson AdmSetPersonEnabled AdmSetPersonPrimarySite AdmUpdateNodeGroup AdmUpdateNodeNetwork AdmUpdateNode AdmUpdatePerson AdmUpdateSitePowerControlUnit AdmUpdateSite AuthCheck BlacklistKey DeleteAddress DeleteAddressTypeFromAddress DeleteAddressType DeleteBootState DeleteConfFile DeleteKey DeleteKeyType DeleteNetworkMethod DeleteNetworkType DeleteNodeFromNodeGroup DeleteNodeFromPCU DeleteNodeGroup DeleteNodeNetwork DeleteNode DeletePCU DeletePersonFromSite DeletePersonFromSlice DeletePerson DeleteRoleFromPerson DeleteRole DeleteSite DeleteSliceAttribute DeleteSliceAttributeType DeleteSliceFromNodes DeleteSlice GetAddresses GetAddressTypes GetBootStates GetConfFiles GetEvents GetKeys GetKeyTypes GetNetworkMethods GetNetworkTypes GetNodeGroups GetNodeNetworks GetNodes GetPCUs GetPersons GetRoles GetSites GetSliceAttributes GetSliceAttributeTypes GetSlices GetSlivers RebootNode SetPersonPrimarySite SliceCreate SliceDelete UpdateAddress UpdateAddressType UpdateConfFile UpdateKey UpdateNodeGroup UpdateNodeNetwork UpdateNode UpdatePCU UpdatePerson UpdateSite UpdateSliceAttribute UpdateSliceAttributeType UpdateSlice  system.listMethods  system.methodHelp  system.methodSignature  system.multicall'.split()
+methods = 'AddAddressType AddAddressTypeToAddress AddBootState AddConfFile AddConfFileToNodeGroup AddConfFileToNode AddKeyType AddNetworkMethod AddNetworkType AddNodeGroup AddNodeNetwork AddNode AddNodeToNodeGroup AddNodeToPCU AddPCU AddPersonKey AddPerson AddPersonToSite AddPersonToSlice AddRole AddRoleToPerson AddSiteAddress AddSite AddSliceAttribute AddSliceAttributeType AddSlice AddSliceToNodes AdmAddAddressType AdmAddNodeGroup AdmAddNodeNetwork AdmAddNode AdmAddNodeToNodeGroup AdmAddPersonKey AdmAddPerson AdmAddPersonToSite AdmAddSitePowerControlUnit AdmAddSite AdmAssociateNodeToPowerControlUnitPort AdmAuthCheck AdmDeleteAddressType AdmDeleteAllPersonKeys AdmDeleteNodeGroup AdmDeleteNodeNetwork AdmDeleteNode AdmDeletePersonKeys AdmDeletePerson AdmDeleteSitePowerControlUnit AdmDeleteSite AdmDisassociatePowerControlUnitPort AdmGenerateNodeConfFile AdmGetAllAddressTypes AdmGetAllKeyTypes AdmGetAllNodeNetworks AdmGetAllRoles AdmGetNodeGroupNodes AdmGetNodeGroups AdmGetNodes AdmGetPersonKeys AdmGetPersonRoles AdmGetPersonSites AdmGetPersons AdmGetPowerControlUnitNodes AdmGetPowerControlUnits AdmGetSiteNodes AdmGetSitePersons AdmGetSitePIs AdmGetSitePowerControlUnits AdmGetSites AdmGetSiteTechContacts AdmGrantRoleToPerson AdmIsPersonInRole AdmQueryConfFile AdmQueryNode AdmQueryPerson AdmQueryPowerControlUnit AdmQuerySite AdmRebootNode AdmRemoveNodeFromNodeGroup AdmRemovePersonFromSite AdmRevokeRoleFromPerson AdmSetPersonEnabled AdmSetPersonPrimarySite AdmUpdateNodeGroup AdmUpdateNodeNetwork AdmUpdateNode AdmUpdatePerson AdmUpdateSitePowerControlUnit AdmUpdateSite AuthCheck BlacklistKey DeleteAddress DeleteAddressTypeFromAddress DeleteAddressType DeleteBootState DeleteConfFileFromNodeGroup DeleteConfFileFromNode DeleteConfFile DeleteKey DeleteKeyType DeleteNetworkMethod DeleteNetworkType DeleteNodeFromNodeGroup DeleteNodeFromPCU DeleteNodeGroup DeleteNodeNetwork DeleteNode DeletePCU DeletePersonFromSite DeletePersonFromSlice DeletePerson DeleteRoleFromPerson DeleteRole DeleteSite DeleteSliceAttribute DeleteSliceAttributeType DeleteSliceFromNodes DeleteSlice GetAddresses GetAddressTypes GetBootStates GetConfFiles GetEvents GetKeys GetKeyTypes GetNetworkMethods GetNetworkTypes GetNodeGroups GetNodeNetworks GetNodes GetPCUs GetPersons GetRoles GetSites GetSliceAttributes GetSliceAttributeTypes GetSlices GetSlivers RebootNode SetPersonPrimarySite SliceCreate SliceDelete UpdateAddress UpdateAddressType UpdateConfFile UpdateKey UpdateNodeGroup UpdateNodeNetwork UpdateNode UpdatePCU UpdatePerson UpdateSite UpdateSliceAttribute UpdateSliceAttributeType UpdateSlice  system.listMethods  system.methodHelp  system.methodSignature  system.multicall'.split()
index 0dbbe43..4311aec 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: NetworkMethods.py,v 1.1 2006/10/10 20:23:49 mlhuang Exp $
+# $Id: NetworkMethods.py,v 1.2 2006/10/20 17:46:02 mlhuang Exp $
 #
 
 from PLC.Faults import *
@@ -25,11 +25,8 @@ class NetworkMethod(Row):
         }
 
     def validate_method(self, name):
-       # Remove leading and trailing spaces
-       name = name.strip()
-
-       # Make sure name is not blank after we removed the spaces
-        if not name:
+       # Make sure name is not blank
+        if not len(name):
             raise PLCInvalidArgument, "Network method must be specified"
        
        # Make sure network method does not alredy exist
index 06ce1b9..a3416c8 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: NetworkTypes.py,v 1.1 2006/10/10 20:24:06 mlhuang Exp $
+# $Id: NetworkTypes.py,v 1.2 2006/10/20 17:47:34 mlhuang Exp $
 #
 
 from PLC.Faults import *
@@ -25,11 +25,8 @@ class NetworkType(Row):
         }
 
     def validate_type(self, name):
-       # Remove leading and trailing spaces
-       name = name.strip()
-
-       # Make sure name is not blank after we removed the spaces
-        if not name:
+       # Make sure name is not blank
+        if not len(name):
             raise PLCInvalidArgument, "Network type must be specified"
        
        # Make sure network type does not alredy exist
index c43c940..4ccf4b8 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: NodeGroups.py,v 1.12 2006/10/06 19:05:31 mlhuang Exp $
+# $Id: NodeGroups.py,v 1.13 2006/10/20 17:50:33 mlhuang Exp $
 #
 
 from types import StringTypes
@@ -27,18 +27,15 @@ class NodeGroup(Row):
     join_tables = ['nodegroup_node', 'conf_file_nodegroup']
     fields = {
         'nodegroup_id': Parameter(int, "Node group identifier"),
-        'name': Parameter(str, "Node group name", max = 50),
+        'name': Parameter(str, "Node group name", max = 50, optional = False),
         'description': Parameter(str, "Node group description", max = 200),
         '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"),
         }
 
     def validate_name(self, name):
-       # Remove leading and trailing spaces
-       name = name.strip()
-
-       # Make sure name is not blank after we removed the spaces
-        if not len(name) > 0:
+       # Make sure name is not blank
+        if not len(name):
                 raise PLCInvalidArgument, "Invalid node group name"
        
        # Make sure node group does not alredy exist
index c11f44b..e62b0fc 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: NodeNetworks.py,v 1.8 2006/10/16 18:23:53 mlhuang Exp $
+# $Id: NodeNetworks.py,v 1.9 2006/10/20 17:51:08 mlhuang Exp $
 #
 
 from types import StringTypes
@@ -49,8 +49,8 @@ class NodeNetwork(Row):
     primary_key = 'nodenetwork_id'
     fields = {
         'nodenetwork_id': Parameter(int, "Node interface identifier"),
-        'method': Parameter(str, "Addressing method (e.g., 'static' or 'dhcp')"),
-        'type': Parameter(str, "Address type (e.g., 'ipv4')"),
+        'method': Parameter(str, "Addressing method (e.g., 'static' or 'dhcp')", optional = False),
+        'type': Parameter(str, "Address type (e.g., 'ipv4')", optional = False),
         'ip': Parameter(str, "IP address"),
         'mac': Parameter(str, "MAC address"),
         'gateway': Parameter(str, "IP address of primary gateway"),
@@ -61,7 +61,7 @@ class NodeNetwork(Row):
         'dns2': Parameter(str, "IP address of secondary DNS server"),
         'bwlimit': Parameter(int, "Bandwidth limit", min = 0),
         'hostname': Parameter(str, "(Optional) Hostname"),
-        'node_id': Parameter(int, "Node associated with this interface (if any)"),
+        'node_id': Parameter(int, "Node associated with this interface", optional = False),
         'is_primary': Parameter(bool, "Is the primary interface for this node"),
         }
 
index 0da2865..7851fdb 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: Nodes.py,v 1.11 2006/10/11 20:48:58 mlhuang Exp $
+# $Id: Nodes.py,v 1.12 2006/10/20 17:51:32 mlhuang Exp $
 #
 
 from types import StringTypes
@@ -39,9 +39,9 @@ class Node(Row):
     primary_key = 'node_id'
     fields = {
         'node_id': Parameter(int, "Node identifier"),
-        'hostname': Parameter(str, "Fully qualified hostname", max = 255),
-        'site_id': Parameter(int, "Site at which this node is located"),
-        'boot_state': Parameter(str, "Boot state", max = 20),
+        'hostname': Parameter(str, "Fully qualified hostname", max = 255, optional = False),
+        'site_id': Parameter(int, "Site at which this node is located", optional = False),
+        'boot_state': Parameter(str, "Boot state", max = 20, optional = False),
         'model': Parameter(str, "Make and model of the actual machine", max = 255),
         'boot_nonce': Parameter(str, "(Admin only) Random value generated by the node at last boot", max = 128),
         'version': Parameter(str, "Apparent Boot CD version", max = 64),
index f591ab1..81c01c4 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: PCUs.py,v 1.3 2006/10/11 20:48:58 mlhuang Exp $
+# $Id: PCUs.py,v 1.4 2006/10/20 17:56:36 mlhuang Exp $
 #
 
 from PLC.Faults import *
@@ -25,9 +25,9 @@ class PCU(Row):
     join_tables = ['pcu_node']
     fields = {
         'pcu_id': Parameter(int, "PCU identifier"),
-        'site_id': Parameter(int, "Identifier of site where PCU is located"),
+        'site_id': Parameter(int, "Identifier of site where PCU is located", optional = False),
         'hostname': Parameter(str, "PCU hostname", max = 254),
-        'ip': Parameter(str, "PCU IP address", max = 254),
+        'ip': Parameter(str, "PCU IP address", max = 254, optional = False),
         'protocol': Parameter(str, "PCU protocol, e.g. ssh, https, telnet", max = 16),
         'username': Parameter(str, "PCU username", max = 254),
         'password': Parameter(str, "PCU username", max = 254),
index 1bc588e..970e6e0 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: Persons.py,v 1.11 2006/10/11 15:40:25 mlhuang Exp $
+# $Id: Persons.py,v 1.12 2006/10/20 17:52:24 mlhuang Exp $
 #
 
 from types import StringTypes
@@ -33,15 +33,15 @@ class Person(Row):
     primary_key = 'person_id'
     fields = {
         'person_id': Parameter(int, "Account identifier"),
-        'first_name': Parameter(str, "Given name", max = 128),
-        'last_name': Parameter(str, "Surname", max = 128),
+        'first_name': Parameter(str, "Given name", max = 128, optional = False),
+        'last_name': Parameter(str, "Surname", max = 128, optional = False),
         'title': Parameter(str, "Title", max = 128),
-        'email': Parameter(str, "Primary e-mail address", max = 254),
+        'email': Parameter(str, "Primary e-mail address", max = 254, optional = False),
         'phone': Parameter(str, "Telephone number", max = 64),
         'url': Parameter(str, "Home page", max = 254),
         'bio': Parameter(str, "Biography", max = 254),
         'enabled': Parameter(bool, "Has been enabled"),
-        'password': Parameter(str, "Account password in crypt() form", max = 254),
+        'password': Parameter(str, "Account password in crypt() form", max = 254, optional = False),
         'last_updated': Parameter(str, "Date and time of last update", ro = True),
         'date_created': Parameter(str, "Date and time when account was created", ro = True),
         'role_ids': Parameter([int], "List of role identifiers", ro = True),
index a7552cf..404827b 100644 (file)
@@ -4,7 +4,7 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: Roles.py,v 1.4 2006/10/16 21:57:05 mlhuang Exp $
+# $Id: Roles.py,v 1.5 2006/10/20 17:53:54 mlhuang Exp $
 #
 
 from types import StringTypes
@@ -35,11 +35,8 @@ class Role(Row):
         return role_id
 
     def validate_name(self, name):
-       # Remove leading and trailing spaces
-       name = name.strip()
-
-       # Make sure name is not blank after we removed the spaces
-        if not name:
+       # Make sure name is not blank
+        if not len(name):
             raise PLCInvalidArgument, "Role must be specified"
        
        # Make sure role does not already exist
index ad8672c..8c05eea 100644 (file)
@@ -16,15 +16,13 @@ class SliceAttributeType(Row):
     join_tables = ['slice_attribute']
     fields = {
         'attribute_type_id': Parameter(int, "Slice attribute type identifier"),
-        'name': Parameter(str, "Slice attribute type name", max = 100),
+        'name': Parameter(str, "Slice attribute type name", max = 100, optional = False),
         '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 validate_name(self, name):
-        name = name.strip()
-
-        if not name:
+        if not len(name):
             raise PLCInvalidArgument, "Slice attribute type name must be set"
 
         conflicts = SliceAttributeTypes(self.api, [name])
index fe72863..02c34c3 100644 (file)
@@ -23,7 +23,7 @@ class Slice(Row):
     fields = {
         'slice_id': Parameter(int, "Slice identifier"),
         'site_id': Parameter(int, "Identifier of the site to which this slice belongs"),
-        'name': Parameter(str, "Slice name", max = 32),
+        'name': Parameter(str, "Slice name", max = 32, optional = False),
         'instantiation': Parameter(str, "Slice instantiation state"),
         'url': Parameter(str, "URL further describing this slice", max = 254),
         'description': Parameter(str, "Slice description", max = 2048),