# 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
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
# 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 *
}
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
# 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 *
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),
# 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 *
}
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
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" \
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):
"""
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')
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']
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')
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
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):
"""
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')
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"
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']
from PLC.Auth import PasswordAuth
can_update = lambda (field, value): field in \
- ['description']
+ ['name', 'description']
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')
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']
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):
"""
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')
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]
# 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']
from PLC.Sites import Site, Sites
can_update = lambda (field, value): field in \
- ['hostname', 'protocol',
+ ['site_id',
+ 'ip', 'hostname', 'protocol',
'username', 'password',
'model', 'notes']
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')
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]
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']
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):
"""
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')
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']
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.
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')
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:
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']
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):
"""
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')
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']
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')
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']
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):
"""
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')
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):
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']
from PLC.Auth import PasswordAuth
can_update = lambda (field, value): field in \
- ['description', 'min_role_id']
+ ['name', 'description', 'min_role_id']
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')
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']
+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):
"""
status = "deprecated"
+
+ accepts = [
+ PasswordAuth(),
+ AddressType.fields['name']
+ ]
+
+ def call(self, auth, name):
+ return AddAddressType.call(self, auth, {'name': name})
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.
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)
]
def call(self, auth, name, description):
- return AddNodeGroup.call(self, auth, name, {'description': description})
+ return AddNodeGroup.call(self, auth, {'name': name, 'description': description})
+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)
+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)
]
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)
+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)
--- /dev/null
+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
--- /dev/null
+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
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],
'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': [{
nodes.append({
'timestamp': timestamp,
- 'id': node['node_id'],
+ 'node_id': node['node_id'],
'hostname': node['hostname'],
'networks': networks,
'groups': groups,
+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):
"""
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)
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')
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')
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')
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')
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')
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')
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')
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')
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')
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')
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')
-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()
# 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 *
}
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
# 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 *
}
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
# 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
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
# 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
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"),
'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"),
}
# 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
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),
# 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 *
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),
# 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
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),
# 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
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
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])
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),