This commit was manufactured by cvs2svn to create branch
authorPlanet-Lab Support <support@planet-lab.org>
Thu, 12 Jul 2007 18:09:11 +0000 (18:09 +0000)
committerPlanet-Lab Support <support@planet-lab.org>
Thu, 12 Jul 2007 18:09:11 +0000 (18:09 +0000)
'planetlab-4_0-branch'.

PLC/Methods/AddSession.py [new file with mode: 0644]
PLC/Methods/AddSliceToNodesWhitelist.py [new file with mode: 0644]
PLC/Methods/DeleteSliceFromNodesWhitelist.py [new file with mode: 0644]
PLC/Methods/GenerateNodeConfFile.py [new file with mode: 0644]
PLC/Methods/GetSessions.py [new file with mode: 0644]
refresh-peer.py [new file with mode: 0644]

diff --git a/PLC/Methods/AddSession.py b/PLC/Methods/AddSession.py
new file mode 100644 (file)
index 0000000..6f5bc88
--- /dev/null
@@ -0,0 +1,37 @@
+import time
+
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Auth import Auth
+from PLC.Sessions import Session, Sessions
+from PLC.Persons import Person, Persons
+
+class AddSession(Method):
+    """
+    Creates and returns a new session key for the specified user. 
+    (Used for website 'user sudo')
+    """
+
+    roles = ['admin']
+    accepts = [
+       Auth(),
+       Mixed(Person.fields['person_id'],
+              Person.fields['email'])
+       ]
+    returns = Session.fields['session_id']
+    
+
+    def call(self, auth, person_id_or_email):
+        
+       persons = Persons(self.api, [person_id_or_email], ['person_id', 'email'])
+       
+       if not persons:
+           raise PLCInvalidArgument, "No such person"
+       
+       person = persons[0]
+       session = Session(self.api)
+        session['expires'] = int(time.time()) + (24 * 60 * 60)
+       session.sync(commit = False)
+       session.add_person(person, commit = True)
+
+        return session['session_id']
diff --git a/PLC/Methods/AddSliceToNodesWhitelist.py b/PLC/Methods/AddSliceToNodesWhitelist.py
new file mode 100644 (file)
index 0000000..a6b4bd1
--- /dev/null
@@ -0,0 +1,54 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Nodes import Node, Nodes
+from PLC.Slices import Slice, Slices
+from PLC.Auth import Auth
+
+class AddSliceToNodesWhitelist(Method):
+    """
+    Adds the specified slice to the whitelist on the specified nodes. Nodes may be
+    either local or foreign nodes.
+
+    If the slice is already associated with a node, no errors are
+    returned.
+
+    Returns 1 if successful, faults otherwise.
+    """
+
+    roles = ['admin']
+
+    accepts = [
+        Auth(),
+        Mixed(Slice.fields['slice_id'],
+              Slice.fields['name']),
+       [Mixed(Node.fields['node_id'],
+               Node.fields['hostname'])]
+        ]
+
+    returns = Parameter(int, '1 if successful')
+
+    def call(self, auth, slice_id_or_name, node_id_or_hostname_list):
+        # Get slice information
+        slices = Slices(self.api, [slice_id_or_name])
+        if not slices:
+            raise PLCInvalidArgument, "No such slice"
+        slice = slices[0]
+
+        if slice['peer_id'] is not None:
+            raise PLCInvalidArgument, "Not a local slice"
+
+        # Get specified nodes, add them to the slice         
+        nodes = Nodes(self.api, node_id_or_hostname_list)
+       for node in nodes:
+           if node['peer_id'] is not None:
+                raise PLCInvalidArgument, "%s not a local node" % node['hostname']
+            if slice['slice_id'] not in node['slice_ids_whitelist']:
+                slice.add_to_node_whitelist(node, commit = False)
+           
+        slice.sync()
+
+       self.event_objects = {'Node': [node['node_id'] for node in nodes],
+                             'Slice': [slice['slice_id']]}
+
+        return 1
diff --git a/PLC/Methods/DeleteSliceFromNodesWhitelist.py b/PLC/Methods/DeleteSliceFromNodesWhitelist.py
new file mode 100644 (file)
index 0000000..8899d88
--- /dev/null
@@ -0,0 +1,54 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Nodes import Node, Nodes
+from PLC.Slices import Slice, Slices
+from PLC.Auth import Auth
+
+class DeleteSliceFromNodesWhitelist(Method):
+    """
+    Deletes the specified slice from the whitelist on the specified nodes. Nodes may be
+    either local or foreign nodes.
+
+    If the slice is already associated with a node, no errors are
+    returned.
+
+    Returns 1 if successful, faults otherwise.
+    """
+
+    roles = ['admin']
+
+    accepts = [
+        Auth(),
+        Mixed(Slice.fields['slice_id'],
+              Slice.fields['name']),
+       [Mixed(Node.fields['node_id'],
+               Node.fields['hostname'])]
+        ]
+
+    returns = Parameter(int, '1 if successful')
+
+    def call(self, auth, slice_id_or_name, node_id_or_hostname_list):
+        # Get slice information
+        slices = Slices(self.api, [slice_id_or_name])
+        if not slices:
+            raise PLCInvalidArgument, "No such slice"
+        slice = slices[0]
+
+        if slice['peer_id'] is not None:
+            raise PLCInvalidArgument, "Not a local slice"
+
+        # Get specified nodes, add them to the slice         
+        nodes = Nodes(self.api, node_id_or_hostname_list)
+       for node in nodes:
+            if node['peer_id'] is not None:
+                raise PLCInvalidArgument, "%s not a local node" % node['hostname']
+           if slice['slice_id'] in node['slice_ids_whitelist']:
+                slice.delete_from_node_whitelist(node, commit = False)
+
+        slice.sync()
+
+       self.event_objects = {'Node': [node['node_id'] for node in nodes],
+                             'Slice': [slice['slice_id']]}
+
+        return 1
diff --git a/PLC/Methods/GenerateNodeConfFile.py b/PLC/Methods/GenerateNodeConfFile.py
new file mode 100644 (file)
index 0000000..0b5cf8e
--- /dev/null
@@ -0,0 +1,107 @@
+import random
+import base64
+
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Nodes import Node, Nodes
+from PLC.NodeNetworks import NodeNetwork, NodeNetworks
+from PLC.Auth import Auth
+
+class GenerateNodeConfFile(Method):
+    """
+    Creates a new node configuration file if all network settings are
+    present. This function will generate a new node key for the
+    specified node, effectively invalidating any old configuration
+    files.
+
+    Non-admins can only generate files for nodes at their sites.
+
+    Returns the contents of the file if successful, faults otherwise.
+    """
+
+    roles = ['admin', 'pi', 'tech']
+
+    accepts = [
+        Auth(),
+        Mixed(Node.fields['node_id'],
+              Node.fields['hostname']),
+       Parameter(bool, "True if you want to regenerate node key")
+        ]
+
+    returns = Parameter(str, "Node configuration file")
+
+    def call(self, auth, node_id_or_hostname, regenerate_node_key = True):
+        # Get node information
+        nodes = Nodes(self.api, [node_id_or_hostname])
+        if not nodes:
+            raise PLCInvalidArgument, "No such node"
+        node = nodes[0]
+
+        if node['peer_id'] is not None:
+            raise PLCInvalidArgument, "Not a local node"
+
+        # If we are not an admin, make sure that the caller is a
+        # member of the site at which the node is located.
+        if 'admin' not in self.caller['roles']:
+            if node['site_id'] not in self.caller['site_ids']:
+                raise PLCPermissionDenied, "Not allowed to generate a configuration file for that node"
+
+       # Get node networks for this node
+        primary = None
+        nodenetworks = NodeNetworks(self.api, node['nodenetwork_ids'])
+        for nodenetwork in nodenetworks:
+            if nodenetwork['is_primary']:
+                primary = nodenetwork
+                break
+        if primary is None:
+            raise PLCInvalidArgument, "No primary network configured"
+
+        # Split hostname into host and domain parts
+        parts = node['hostname'].split(".", 1)
+        if len(parts) < 2:
+            raise PLCInvalidArgument, "Node hostname is invalid"
+        host = parts[0]
+        domain = parts[1]
+
+       if regenerate_node_key:
+            # Generate 32 random bytes
+            bytes = random.sample(xrange(0, 256), 32)
+            # Base64 encode their string representation
+            node['key'] = base64.b64encode("".join(map(chr, bytes)))
+            # XXX Boot Manager cannot handle = in the key
+            node['key'] = node['key'].replace("=", "")
+            # Save it
+            node.sync()
+
+        # Generate node configuration file suitable for BootCD
+        file = ""
+
+        file += 'NODE_ID="%d"\n' % node['node_id']
+        file += 'NODE_KEY="%s"\n' % node['key']
+
+        if primary['mac']:
+            file += 'NET_DEVICE="%s"\n' % primary['mac'].lower()
+
+        file += 'IP_METHOD="%s"\n' % primary['method']
+
+        if primary['method'] == 'static':
+            file += 'IP_ADDRESS="%s"\n' % primary['ip']
+            file += 'IP_GATEWAY="%s"\n' % primary['gateway']
+            file += 'IP_NETMASK="%s"\n' % primary['netmask']
+            file += 'IP_NETADDR="%s"\n' % primary['network']
+            file += 'IP_BROADCASTADDR="%s"\n' % primary['broadcast']
+            file += 'IP_DNS1="%s"\n' % primary['dns1']
+            file += 'IP_DNS2="%s"\n' % (primary['dns2'] or "")
+
+        file += 'HOST_NAME="%s"\n' % host
+        file += 'DOMAIN_NAME="%s"\n' % domain
+
+        for nodenetwork in nodenetworks:
+            if nodenetwork['method'] == 'ipmi':
+                file += 'IPMI_ADDRESS="%s"\n' % nodenetwork['ip']
+                if nodenetwork['mac']:
+                    file += 'IPMI_MAC="%s"\n' % nodenetwork['mac'].lower()
+                break
+
+        return file
diff --git a/PLC/Methods/GetSessions.py b/PLC/Methods/GetSessions.py
new file mode 100644 (file)
index 0000000..a72553c
--- /dev/null
@@ -0,0 +1,35 @@
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Filter import Filter
+from PLC.Sessions import Session, Sessions
+from PLC.Persons import Person, Persons
+from PLC.Auth import Auth
+
+class GetSessions(Method):
+    """
+    Returns an array of structs containing details about users sessions. If
+    session_filter is specified and is an array of user identifiers or
+    session_keys, or a struct of session attributes, only sessions matching the
+    filter will be returned. If return_fields is specified, only the
+    specified details will be returned.
+
+    
+    """
+
+    roles = ['admin']
+
+    accepts = [
+        Auth(),
+        Mixed([Mixed(Session.fields['person_id'],
+                     Session.fields['session_id'])],
+              Filter(Session.fields))
+        ]
+
+    returns = [Session.fields]
+    
+    def call(self, auth, session_filter = None):
+
+        sessions = Sessions(self.api, session_filter)
+       
+       return sessions
diff --git a/refresh-peer.py b/refresh-peer.py
new file mode 100644 (file)
index 0000000..ae38841
--- /dev/null
@@ -0,0 +1,38 @@
+#!/usr/bin/env plcsh
+# $Id: refresh-peer.py 154 2007-03-28 14:15:55Z thierry $
+
+import sys,os,time
+
+def Run (peername):
+    timestring=time.strftime("%Y-%m-%d-%H-%M-%S")
+    print 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',peername
+    print 'RefreshPeer on %s - starting on %s'%(peername,timestring)
+    print 'xxxxxxxxxx'
+    sys.stdout.flush()
+    start=time.time()
+    result=RefreshPeer(peername)
+    finish=time.time()
+
+    print 'Total duration',finish-start
+    print 'xxxxxxxxxx timers:'
+    keys=result.keys()
+    keys.sort()
+    for key in keys:
+        print key,result[key]
+    sys.stdout.flush()
+    sys.stderr.flush()
+
+def RunInLog (peername):
+    logname="/var/log/refresh-peer-%s.log"%(peername)
+    sys.stdout=open(logname,'a')
+    sys.stderr=sys.stdout
+    Run(peername)
+    sys.stderr.close()
+    sys.stdout.close()
+
+if __name__ == "__main__":
+    
+    for peername in sys.argv[1:]:
+        RunInLog (peername)
+
+