[X2Go-Commits] [x2gobroker] 03/03: Fix remote agent detection if one ore more X2Go Servers are offline and hostname does not match host address (plus unit test).

git-admin at x2go.org git-admin at x2go.org
Wed Dec 10 11:52:32 CET 2014


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch master
in repository x2gobroker.

commit a9bc46b1a69ad769aa04f7bd9d24efd795d9d73e
Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
Date:   Wed Dec 10 11:52:08 2014 +0100

    Fix remote agent detection if one ore more X2Go Servers are offline and hostname does not match host address (plus unit test).
---
 debian/changelog                      |    2 ++
 x2gobroker/agent.py                   |   21 ++++++------
 x2gobroker/brokers/base_broker.py     |   20 +++++++----
 x2gobroker/tests/test_broker_agent.py |   59 ++++++++++++++++++++++++++++++---
 4 files changed, 81 insertions(+), 21 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index d040e38..ad3eb5e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -215,6 +215,8 @@ x2gobroker (0.0.3.0-0x2go1) UNRELEASED; urgency=low
       deploying SSH keys.
     - Allow resuming sessions from servers even if one offline server has
       left bogus in the session DB (plus unit tests).
+    - Fix remote agent detection if one ore more X2Go Servers are offline and
+      hostname does not match host address (plus unit test).
   * debian/control:
     + Provide separate bin:package for SSH brokerage: x2gobroker-ssh.
     + Replace LDAP support with session brokerage support in LONG_DESCRIPTION.
diff --git a/x2gobroker/agent.py b/x2gobroker/agent.py
index 8f7ae9e..56c66fd 100644
--- a/x2gobroker/agent.py
+++ b/x2gobroker/agent.py
@@ -164,17 +164,17 @@ def _call_remote_broker_agent(username, task, cmdline_args=[], remote_agent=None
 
     """
     if remote_agent is None:
-        logger_error.error('With the SSH agent-query-mode a remote agent host (hostname, port) has to be specified!')
+        logger_error.error('With the SSH agent-query-mode a remote agent host (hostname, hostaddr, port) has to be specified!')
     elif not remote_agent.has_key('host_key_policy'):
         remote_agent['host_key_policy'] = paramiko.WarningPolicy()
 
-    remote_hostname = remote_agent[u'hostname']
+    remote_hostaddr = remote_agent[u'hostaddr']
     if remote_agent.has_key(u'port'):
         remote_port = int(remote_agent[u'port'])
     else:
         remote_port = 22
 
-    if x2gobroker.utils.portscan(remote_hostname, remote_port):
+    if x2gobroker.utils.portscan(remote_hostaddr, remote_port):
         cmd_line = [
             '{x2gobroker_agent_binary}'.format(x2gobroker_agent_binary=x2gobroker.defaults.X2GOBROKER_AGENT_CMD),
             '{username}'.format(username=username),
@@ -192,7 +192,7 @@ def _call_remote_broker_agent(username, task, cmdline_args=[], remote_agent=None
             if os.path.exists(os.path.expanduser("~/.ssh/known_hosts")):
                 client.load_host_keys(os.path.expanduser("~/.ssh/known_hosts"))
             client.set_missing_host_key_policy(remote_agent['host_key_policy'])
-            client.connect(remote_hostname, remote_port, remote_username, look_for_keys=True, allow_agent=True)
+            client.connect(remote_hostaddr, remote_port, remote_username, look_for_keys=True, allow_agent=True)
 
             result = []
             ssh_transport = client.get_transport()
@@ -213,11 +213,11 @@ def _call_remote_broker_agent(username, task, cmdline_args=[], remote_agent=None
             else:
                 return (False, [])
         except paramiko.AuthenticationException:
-            raise x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException('Authentication to remote X2Go Broker Agent Host failed (user: {user}, hostname: {hostname}, port: {port}) failed'.format(user=remote_username, hostname=remote_hostname, port=remote_port))
+            raise x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException('Authentication to remote X2Go Broker Agent Host failed (user: {user}, hostname: {hostname}, host address: {hostaddr}, port: {port}) failed'.format(user=remote_username, hostname=remote_hostname, hostaddr=remote_hostaddr, port=remote_port))
         except (paramiko.SSHException, paramiko.BadHostKeyException, socket.error):
-            raise x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException('Query to remote X2Go Broker Agent (user: {user}, hostname: {hostname}, port: {port}) failed'.format(user=remote_username, hostname=remote_hostname, port=remote_port))
+            raise x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException('Query to remote X2Go Broker Agent (user: {user}, hostname: {hostname}, host address: {hostaddr}, port: {port}) failed'.format(user=remote_username, hostname=remote_hostname, hostaddr=remote_hostaddr, port=remote_port))
     else:
-        raise x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException('Could not ping remote X2Go Broker Agent host ({remote_hostname})'.format(remote_hostname=remote_hostname))
+        raise x2gobroker.x2gobroker_exceptions.X2GoBrokerAgentException('Could not ping remote X2Go Broker Agent host: {hostname} ({hostaddr})'.format(hostname=remote_hostname, hostaddr=remote_hostaddr))
 
 
 def ping(remote_agent=None, **kwargs):
@@ -233,7 +233,7 @@ def ping(remote_agent=None, **kwargs):
         return _call_local_broker_agent(username)[0]
     else:
         return remote_agent is not None and \
-               x2gobroker.utils.portscan(remote_agent['hostname'], remote_agent['port']) and \
+               (x2gobroker.utils.portscan(remote_agent['hostname'], remote_agent['port']) or x2gobroker.utils.portscan(remote_agent['hostname'], remote_agent['port'])) and \
                _call_remote_broker_agent(username, task='ping', remote_agent=remote_agent)[0]
 tasks['ping'] = ping
 
@@ -364,13 +364,14 @@ def delete_authorized_key(username, pubkey_hash, authorized_keys_file='%h/.x2go/
     """
     # this is for the logger output
     if remote_agent in ('LOCAL', None):
-        _hostname = 'LOCAL'
+        _hostname = _hostaddr = 'LOCAL'
     else:
         _hostname = remote_agent['hostname']
+        _hostaddr = remote_agent['hostaddr']
 
     if delay_deletion > 0:
         delayed_execution(delete_authorized_key, delay=delay_deletion, username=username, pubkey_hash=pubkey_hash, authorized_keys_file=authorized_keys_file, remote_agent=remote_agent, )
-        logger_broker.debug('Scheduled deletion of authorized key in {delay}s: user={user}, host={host}'.format(delay=delay_deletion, user=username, host=_hostname))
+        logger_broker.debug('Scheduled deletion of authorized key in {delay}s: user={user}, hostname={hostname}, hostaddr={hostaddr}'.format(delay=delay_deletion, user=username, hostname=_hostname, hostaddr=_hostaddr))
     else:
         return call_broker_agent(username, task='delauthkey', cmdline_args=[pubkey_hash, authorized_keys_file, ], remote_agent=remote_agent, **kwargs)
 tasks['delauthkey'] = delete_authorized_key
diff --git a/x2gobroker/brokers/base_broker.py b/x2gobroker/brokers/base_broker.py
index 4a6cb00..ebcf4af 100644
--- a/x2gobroker/brokers/base_broker.py
+++ b/x2gobroker/brokers/base_broker.py
@@ -1008,14 +1008,18 @@ class X2GoBroker(object):
 
             while server_list:
 
-                remote_agent_server = server_list[-1]
+                remote_agent_hostname = server_list[-1]
+                remote_agent_hostaddr = remote_agent_hostname
                 remote_agent_port = profile[u'sshport']
-                if profile.has_key('sshport={ras}'.format(ras=remote_agent_server)):
-                    remote_agent_port = profile["sshport={ras}".format(ras=remote_agent_server)]
-                if profile.has_key('host={ras}'.format(ras=remote_agent_server)):
-                    remote_agent_server = profile["host={ras}".format(ras=remote_agent_server)]
+                if profile.has_key('sshport={hostname}'.format(hostname=remote_agent_hostname)):
+                    remote_agent_port = profile["sshport={hostname}".format(hostname=remote_agent_hostname)]
+                if profile.has_key('host={hostname}'.format(hostname=remote_agent_hostname)):
+                    remote_agent_hostaddr = profile["host={hostname}".format(hostname=remote_agent_hostname)]
 
-                remote_agent = {u'hostname': remote_agent_server, u'port': remote_agent_port, }
+                remote_agent = {
+                    u'hostname': remote_agent_hostname,
+                    u'hostaddr': remote_agent_hostaddr,
+                    u'port': remote_agent_port, }
 
                 try:
                     if x2gobroker.agent.ping(remote_agent=remote_agent):
@@ -1397,6 +1401,7 @@ class X2GoBroker(object):
         if profile.has_key(u'sshproxyhost') and profile[u'sshproxyhost']:
             remote_sshproxy_agent = {
                 u'hostname': profile[u'sshproxyhost'],
+                u'hostaddr': profile[u'sshproxyhost'],
                 u'port': "22"
             }
             if profile.has_key(u'sshproxyport') and profile[u'sshproxyport']:
@@ -1410,7 +1415,8 @@ class X2GoBroker(object):
             # let's use the chosen server_name if remote_agent is reachable via SSH
             if type(remote_agent) is types.DictType:
                 remote_agent = {
-                    u'hostname': selected_session[u'server'],
+                    u'hostname': server_name,
+                    u'hostaddr': server_addr,
                     u'port': selected_session[u'port'],
                 }
 
diff --git a/x2gobroker/tests/test_broker_agent.py b/x2gobroker/tests/test_broker_agent.py
index a7cc26c..e9ead47 100644
--- a/x2gobroker/tests/test_broker_agent.py
+++ b/x2gobroker/tests/test_broker_agent.py
@@ -206,7 +206,7 @@ broker-agent-query-mode = SSH
         i = 0
         while i < 10:
             _remoteagent5 = inifile_backend.get_remote_agent('testprofile5')
-            self.assertTrue( _remoteagent5 == {u'hostname': '10.0.2.4', u'port': 22} or _remoteagent5 == {u'hostname': '10.0.2.5', u'port': 22} )
+            self.assertTrue( _remoteagent5 == {u'hostname': 'host1.mydomain', u'hostaddr': '10.0.2.4', u'port': 22} or _remoteagent5 == {u'hostname': 'host2.mydomain', u'hostaddr': '10.0.2.5', u'port': 22} )
             _session5 = inifile_backend.select_session('testprofile5', 'foo5N')
             self.assertTrue( _session5 == {'port': 22, 'server': '10.0.2.4', } or _session5 == {'port': 22, 'server': '10.0.2.5', } )
             i += 1
@@ -220,7 +220,7 @@ broker-agent-query-mode = SSH
         self.assertTrue( _profile6['host'][0] in ('host1.mydomain', 'host2.mydomain') )
         self.assertTrue( not _profile6.has_key('status') )
         _remoteagent6 = inifile_backend.get_remote_agent('testprofile6')
-        self.assertTrue( _remoteagent6 == {u'hostname': '10.0.2.4', u'port': 23467} or _remoteagent6 == {u'hostname': '10.0.2.5', u'port': 23467} )
+        self.assertTrue( _remoteagent6 == {u'hostname': 'host1.mydomain', u'hostaddr': '10.0.2.4', u'port': 23467} or _remoteagent6 == {u'hostname': 'host2.mydomain', u'hostaddr': '10.0.2.5', u'port': 23467} )
         _session6 = inifile_backend.select_session('testprofile6', 'foo6N')
         self.assertTrue( _session6 == {'port': 23467, 'server': '10.0.2.4', } or _session6 == {'port': 23467, 'server': '10.0.2.5', } )
 
@@ -232,7 +232,7 @@ broker-agent-query-mode = SSH
         i = 0
         while i < 10:
             _remoteagent7 = inifile_backend.get_remote_agent('testprofile7')
-            self.assertTrue( _remoteagent7 == {u'hostname': 'docker-server', u'port': 22001} or _remoteagent7 == {u'hostname': 'docker-server', u'port': 22002} )
+            self.assertTrue( _remoteagent7 == {u'hostname': 'docker-vm-1', u'hostaddr': 'docker-server', u'port': 22001} or _remoteagent7 == {u'hostname': 'docker-vm-2', u'hostaddr': 'docker-server', u'port': 22002} )
             _session7 = inifile_backend.select_session('testprofile7', 'foo7N')
             self.assertTrue( _session7 == {'port': 22001, 'server': 'docker-server', } or _session7 == {'port': 22001, 'server': 'docker-server', } )
             i += 1
@@ -245,7 +245,7 @@ broker-agent-query-mode = SSH
         i = 0
         while i < 10:
             _remoteagent8 = inifile_backend.get_remote_agent('testprofile8')
-            self.assertTrue( _remoteagent8 == {u'hostname': 'docker-server', u'port': 22000} or _remoteagent8 == {u'hostname': 'docker-server', u'port': 22001} or _remoteagent8 == {u'hostname': 'docker-server', u'port': 22002} )
+            self.assertTrue( _remoteagent8 == {u'hostname': 'docker-vm-0', u'hostaddr': 'docker-server', u'port': 22000} or _remoteagent8 == {u'hostname': 'docker-vm-1', u'hostaddr': 'docker-server', u'port': 22001} or _remoteagent8 == {u'hostname': 'docker-vm-2', u'hostaddr': 'docker-server', u'port': 22002} )
             _session8 = inifile_backend.select_session('testprofile8', 'foo8N')
             self.assertTrue( _session8 == {'port': 22000, 'server': 'docker-server', } or _session8 == {'port': 22001, 'server': 'docker-server', } or _session8 == {'port': 22001, 'server': 'docker-server', } )
             i += 1
@@ -433,6 +433,57 @@ broker-autologin = true
         x2gobroker.utils.portscan = _save_portscan
         time.sleep = _save_time_sleep
 
+    def test_get_remote_agent_with_offline_servers(self):
+
+        _save_local_broker_agent_call = x2gobroker.agent._call_local_broker_agent
+        _save_remote_broker_agent_call = x2gobroker.agent._call_remote_broker_agent
+        _save_portscan = x2gobroker.utils.portscan
+
+        def _call_testsuite_broker_agent(username, task, cmdline_args=[], remote_agent=None):
+
+            if task == 'ping':
+                return True, []
+
+            return False, []
+
+        def _fake_portscan(addr, port=22):
+            if addr == 'host3.internal':
+                return False
+            if addr.startswith('downhost'):
+                return False
+            return True
+
+        def _fake_time_sleep(sec):
+            pass
+
+        x2gobroker.agent._call_local_broker_agent = _call_testsuite_broker_agent
+        x2gobroker.agent._call_remote_broker_agent = _call_testsuite_broker_agent
+        x2gobroker.utils.portscan = _fake_portscan
+        time.sleep = _fake_time_sleep
+
+        _session_profiles = """
+[DEFAULT]
+command = MATE
+user = foo
+broker-agent-query-mode = NONE
+
+[testprofile1]
+name = testprofile1
+host = downhost1.internal (10.0.2.11), host2.internal (10.0.2.12), host3.internal (10.0.2.13)
+broker-agent-query-mode = SSH
+broker-portscan-x2goservers = true
+
+"""
+        tf = tempfile.NamedTemporaryFile()
+        print >> tf, _session_profiles
+        tf.seek(0)
+        inifile_backend = inifile.X2GoBroker(profile_config_file=tf.name)
+
+        i = 0
+        while i < 50:
+            remote_agent = inifile_backend.get_remote_agent('testprofile1')
+            self.assertTrue ( remote_agent['hostaddr'] != '10.0.2.11')
+            i += 1
 
 def test_suite():
     from unittest import TestSuite, makeSuite

--
Alioth's /srv/git/_hooks_/post-receive-email on /srv/git/code.x2go.org/x2gobroker.git


More information about the x2go-commits mailing list