cosmetic changes in sendmail.py - please the linter
[plcapi.git] / PLC / Peers.py
index 13eaabc..c24f925 100644 (file)
@@ -1,30 +1,30 @@
-# $Id$
-# $URL$
 #
 # Thierry Parmentelat - INRIA
 #
 # Thierry Parmentelat - INRIA
-# 
+#
 
 import re
 
 import re
-from types import StringTypes
-from urlparse import urlparse
+import traceback
+from urllib.parse import urlparse
 
 
+import PLC.Auth
+from PLC.Logger import logger
 from PLC.Faults import *
 from PLC.Faults import *
+from PLC.Namespace import hostname_to_hrn
 from PLC.Parameter import Parameter, Mixed
 from PLC.Filter import Filter
 from PLC.Table import Row, Table
 from PLC.Parameter import Parameter, Mixed
 from PLC.Filter import Filter
 from PLC.Table import Row, Table
-import PLC.Auth
-from PLC.Shell import *
 from PLC.Sites import Site, Sites
 from PLC.Persons import Person, Persons
 from PLC.Keys import Key, Keys
 from PLC.Nodes import Node, Nodes
 from PLC.TagTypes import TagType, TagTypes
 from PLC.Sites import Site, Sites
 from PLC.Persons import Person, Persons
 from PLC.Keys import Key, Keys
 from PLC.Nodes import Node, Nodes
 from PLC.TagTypes import TagType, TagTypes
+from PLC.NodeTags import NodeTag, NodeTags
 from PLC.SliceTags import SliceTag, SliceTags
 from PLC.Slices import Slice, Slices
 
 class Peer(Row):
     """
 from PLC.SliceTags import SliceTag, SliceTags
 from PLC.Slices import Slice, Slices
 
 class Peer(Row):
     """
-    Stores the list of peering PLCs in the peers table. 
+    Stores the list of peering PLCs in the peers table.
     See the Row class for more details
     """
 
     See the Row class for more details
     """
 
@@ -45,16 +45,16 @@ class Peer(Row):
         'key_ids': Parameter([int], "List of keys for which this peer is authoritative"),
         'node_ids': Parameter([int], "List of nodes for which this peer is authoritative"),
         'slice_ids': Parameter([int], "List of slices for which this peer is authoritative"),
         'key_ids': Parameter([int], "List of keys for which this peer is authoritative"),
         'node_ids': Parameter([int], "List of nodes for which this peer is authoritative"),
         'slice_ids': Parameter([int], "List of slices for which this peer is authoritative"),
-       }
+        }
 
     def validate_peername(self, peername):
         if not len(peername):
 
     def validate_peername(self, peername):
         if not len(peername):
-            raise PLCInvalidArgument, "Peer name must be specified"
+            raise PLCInvalidArgument("Peer name must be specified")
 
         conflicts = Peers(self.api, [peername])
         for peer in conflicts:
             if 'peer_id' not in self or self['peer_id'] != peer['peer_id']:
 
         conflicts = Peers(self.api, [peername])
         for peer in conflicts:
             if 'peer_id' not in self or self['peer_id'] != peer['peer_id']:
-                raise PLCInvalidArgument, "Peer name already in use"
+                raise PLCInvalidArgument("Peer name already in use")
 
         return peername
 
 
         return peername
 
@@ -65,11 +65,11 @@ class Peer(Row):
 
         (scheme, netloc, path, params, query, fragment) = urlparse(url)
         if scheme != "https":
 
         (scheme, netloc, path, params, query, fragment) = urlparse(url)
         if scheme != "https":
-            raise PLCInvalidArgument, "Peer URL scheme must be https"
+            raise PLCInvalidArgument("Peer URL scheme must be https")
         if path[-1] != '/':
         if path[-1] != '/':
-            raise PLCInvalidArgument, "Peer URL should end with /"
-        
-       return url
+            raise PLCInvalidArgument("Peer URL should end with /")
+
+        return url
 
     def delete(self, commit = True):
         """
 
     def delete(self, commit = True):
         """
@@ -108,7 +108,7 @@ class Peer(Row):
         """
         Unassociate a site with this peer.
         """
         """
         Unassociate a site with this peer.
         """
-        
+
         remove = Row.remove_object(Site, 'peer_site')
         remove(self, site, commit)
 
         remove = Row.remove_object(Site, 'peer_site')
         remove(self, site, commit)
 
@@ -123,12 +123,12 @@ class Peer(Row):
              'person_id': person['person_id'],
              'peer_person_id': peer_person_id},
             commit = commit)
              'person_id': person['person_id'],
              'peer_person_id': peer_person_id},
             commit = commit)
-    
+
     def remove_person(self, person, commit = True):
         """
         Unassociate a site with this peer.
         """
     def remove_person(self, person, commit = True):
         """
         Unassociate a site with this peer.
         """
-    
+
         remove = Row.remove_object(Person, 'peer_person')
         remove(self, person, commit)
 
         remove = Row.remove_object(Person, 'peer_person')
         remove(self, person, commit)
 
@@ -148,7 +148,7 @@ class Peer(Row):
         """
         Unassociate a key with this peer.
         """
         """
         Unassociate a key with this peer.
         """
-    
+
         remove = Row.remove_object(Key, 'peer_key')
         remove(self, key, commit)
 
         remove = Row.remove_object(Key, 'peer_key')
         remove(self, key, commit)
 
@@ -164,27 +164,33 @@ class Peer(Row):
              'peer_node_id': peer_node_id},
             commit = commit)
 
              'peer_node_id': peer_node_id},
             commit = commit)
 
-        # calling UpdateNode with the node's hostname 
-        # will force the 'hrn' tag to be updated with the 
-        # correct root auth
-        shell = Shell() 
-        UpdateNode = self.api.callable('UpdateNode')
-        UpdateNode(shell.auth, node['node_id'], {'hostname': node['hostname']})  
+        sites = Sites(self.api, node['site_id'], ['login_base'])
+        site = sites[0]
+        login_base = site['login_base']
+        try:
+            # attempt to manually update the 'hrn' tag with the remote prefix
+            hrn_root = self['hrn_root']
+            hrn = hostname_to_hrn(hrn_root, login_base, node['hostname'])
+            tags = {'hrn': hrn}
+            Node(self.api, node).update_tags(tags)
+        except:
+            logger.exception("Could not find out hrn on hostname=%s"%node['hostname'])
 
     def remove_node(self, node, commit = True):
         """
         Unassociate a node with this peer.
         """
 
     def remove_node(self, node, commit = True):
         """
         Unassociate a node with this peer.
         """
-    
+
         remove = Row.remove_object(Node, 'peer_node')
         remove(self, node, commit)
         remove = Row.remove_object(Node, 'peer_node')
         remove(self, node, commit)
-
-        # calling UpdateNode with the node's hostname
-        # will force the 'hrn' tag to be updated with the
-        # correct root auth
-        shell = Shell() 
-        UpdateNode = self.api.callable('UpdateNode')
-        UpdateNode(shell.auth, node['node_id'], {'hostname': node['hostname']})
+        # attempt to manually update the 'hrn' tag now that the node is local
+        root_auth = self.api.config.PLC_HRN_ROOT
+        sites = Sites(self.api, node['site_id'], ['login_base'])
+        site = sites[0]
+        login_base = site['login_base']
+        hrn = hostname_to_hrn(root_auth, login_base, node['hostname'])
+        tags = {'hrn': hrn}
+        Node(self.api, node).update_tags(tags)
 
     def add_slice(self, slice, peer_slice_id, commit = True):
         """
 
     def add_slice(self, slice, peer_slice_id, commit = True):
         """
@@ -211,9 +217,9 @@ class Peer(Row):
         Connect to this peer via XML-RPC.
         """
 
         Connect to this peer via XML-RPC.
         """
 
-        import xmlrpclib
+        import xmlrpc.client
         from PLC.PyCurl import PyCurlTransport
         from PLC.PyCurl import PyCurlTransport
-        self.server = xmlrpclib.ServerProxy(self['peer_url'],
+        self.server = xmlrpc.client.ServerProxy(self['peer_url'],
                                             PyCurlTransport(self['peer_url'], self['cacert']),
                                             allow_none = 1, **kwds)
 
                                             PyCurlTransport(self['peer_url'], self['cacert']),
                                             allow_none = 1, **kwds)
 
@@ -258,37 +264,45 @@ class Peer(Row):
             if api_function.accepts and \
                (isinstance(api_function.accepts[0], PLC.Auth.Auth) or \
                 (isinstance(api_function.accepts[0], Mixed) and \
             if api_function.accepts and \
                (isinstance(api_function.accepts[0], PLC.Auth.Auth) or \
                 (isinstance(api_function.accepts[0], Mixed) and \
-                 filter(lambda param: isinstance(param, Auth), api_function.accepts[0]))):
+                 [param for param in api_function.accepts[0] if isinstance(param, Auth)])):
                 function = getattr(self.server, methodname)
                 return self.add_auth(function, methodname)
                 function = getattr(self.server, methodname)
                 return self.add_auth(function, methodname)
-        except Exception, err:
+        except Exception as err:
             pass
 
         if hasattr(self, attr):
             return getattr(self, attr)
         else:
             pass
 
         if hasattr(self, attr):
             return getattr(self, attr)
         else:
-            raise AttributeError, "type object 'Peer' has no attribute '%s'" % attr
+            raise AttributeError("type object 'Peer' has no attribute '%s'" % attr)
 
 class Peers (Table):
 
 class Peers (Table):
-    """ 
+    """
     Maps to the peers table in the database
     """
     Maps to the peers table in the database
     """
-    
+
     def __init__ (self, api, peer_filter = None, columns = None):
         Table.__init__(self, api, Peer, columns)
 
     def __init__ (self, api, peer_filter = None, columns = None):
         Table.__init__(self, api, Peer, columns)
 
-       sql = "SELECT %s FROM view_peers WHERE deleted IS False" % \
+        sql = "SELECT %s FROM view_peers WHERE deleted IS False" % \
               ", ".join(self.columns)
 
         if peer_filter is not None:
             if isinstance(peer_filter, (list, tuple, set)):
                 # Separate the list into integers and strings
               ", ".join(self.columns)
 
         if peer_filter is not None:
             if isinstance(peer_filter, (list, tuple, set)):
                 # Separate the list into integers and strings
-                ints = filter(lambda x: isinstance(x, (int, long)), peer_filter)
-                strs = filter(lambda x: isinstance(x, StringTypes), peer_filter)
+                ints = [x for x in peer_filter if isinstance(x, int)]
+                strs = [x for x in peer_filter if isinstance(x, str)]
                 peer_filter = Filter(Peer.fields, {'peer_id': ints, 'peername': strs})
                 sql += " AND (%s) %s" % peer_filter.sql(api, "OR")
             elif isinstance(peer_filter, dict):
                 peer_filter = Filter(Peer.fields, peer_filter)
                 sql += " AND (%s) %s" % peer_filter.sql(api, "AND")
                 peer_filter = Filter(Peer.fields, {'peer_id': ints, 'peername': strs})
                 sql += " AND (%s) %s" % peer_filter.sql(api, "OR")
             elif isinstance(peer_filter, dict):
                 peer_filter = Filter(Peer.fields, peer_filter)
                 sql += " AND (%s) %s" % peer_filter.sql(api, "AND")
+            elif isinstance(peer_filter, int):
+                peer_filter = Filter(Peer.fields, {'peer_id': peer_filter})
+                sql += " AND (%s) %s" % peer_filter.sql(api, "AND")
+            elif isinstance(peer_filter, str):
+                peer_filter = Filter(Peer.fields, {'peername': peer_filter})
+                sql += " AND (%s) %s" % peer_filter.sql(api, "AND")
+            else:
+                raise PLCInvalidArgument("Wrong peer filter %r"%peer_filter)
 
 
-       self.selectall(sql)
+        self.selectall(sql)