This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/master by this push:
new 2248a5d Expose option: look_for_keys in ssh_hook via extras (#8793)
2248a5d is described below
commit 2248a5da1d83ca901ec24d5809e718bbbd2c3894
Author: r-richmond <[email protected]>
AuthorDate: Sun Jun 28 15:06:12 2020 -0700
Expose option: look_for_keys in ssh_hook via extras (#8793)
---
airflow/providers/ssh/hooks/ssh.py | 8 +++++++-
docs/howto/connection/ssh.rst | 4 +++-
tests/providers/ssh/hooks/test_ssh.py | 24 +++++++++++++++++++++---
3 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/airflow/providers/ssh/hooks/ssh.py
b/airflow/providers/ssh/hooks/ssh.py
index 261092b..4017b49 100644
--- a/airflow/providers/ssh/hooks/ssh.py
+++ b/airflow/providers/ssh/hooks/ssh.py
@@ -83,6 +83,7 @@ class SSHHook(BaseHook):
self.no_host_key_check = True
self.allow_host_key_change = False
self.host_proxy = None
+ self.look_for_keys = True
# Placeholder for deprecated __enter__
self.client = None
@@ -121,6 +122,10 @@ class SSHHook(BaseHook):
and\
str(extra_options["allow_host_key_change"]).lower() ==
'true':
self.allow_host_key_change = True
+ if "look_for_keys" in extra_options\
+ and\
+ str(extra_options["look_for_keys"]).lower() == 'false':
+ self.look_for_keys = False
if self.pkey and self.key_file:
raise AirflowException(
@@ -178,7 +183,8 @@ class SSHHook(BaseHook):
timeout=self.timeout,
compress=self.compress,
port=self.port,
- sock=self.host_proxy
+ sock=self.host_proxy,
+ look_for_keys=self.look_for_keys
)
if self.password:
diff --git a/docs/howto/connection/ssh.rst b/docs/howto/connection/ssh.rst
index 6f19edc..603151f 100644
--- a/docs/howto/connection/ssh.rst
+++ b/docs/howto/connection/ssh.rst
@@ -48,6 +48,7 @@ Extra (optional)
* ``compress`` - ``true`` to ask the remote client/server to compress
traffic; ``false`` to refuse compression. Default is ``true``.
* ``no_host_key_check`` - Set to ``false`` to restrict connecting to hosts
with no entries in ``~/.ssh/known_hosts`` (Hosts file). This provides maximum
protection against trojan horse attacks, but can be troublesome when the
``/etc/ssh/ssh_known_hosts`` file is poorly maintained or connections to new
hosts are frequently made. This option forces the user to manually add all new
hosts. Default is ``true``, ssh will automatically add new host keys to the
user known hosts files.
* ``allow_host_key_change`` - Set to ``true`` if you want to allow
connecting to hosts that has host key changed or when you get 'REMOTE HOST
IDENTIFICATION HAS CHANGED' error. This wont protect against Man-In-The-Middle
attacks. Other possible solution is to remove the host entry from
``~/.ssh/known_hosts`` file. Default is ``false``.
+ * ``look_for_keys`` - Set to ``false`` if you want to disable searching
for discoverable private key files in ``~/.ssh/``
Example "extras" field:
@@ -58,7 +59,8 @@ Extra (optional)
"timeout": "10",
"compress": "false",
"no_host_key_check": "false",
- "allow_host_key_change": "false"
+ "allow_host_key_change": "false",
+ "look_for_keys": "false"
}
When specifying the connection as URI (in :envvar:`AIRFLOW_CONN_{CONN_ID}`
variable) you should specify it
diff --git a/tests/providers/ssh/hooks/test_ssh.py
b/tests/providers/ssh/hooks/test_ssh.py
index e9f6bd7..828593c 100644
--- a/tests/providers/ssh/hooks/test_ssh.py
+++ b/tests/providers/ssh/hooks/test_ssh.py
@@ -56,6 +56,7 @@ TEST_PRIVATE_KEY = generate_key_string(pkey=TEST_PKEY)
class TestSSHHook(unittest.TestCase):
CONN_SSH_WITH_PRIVATE_KEY_EXTRA = 'ssh_with_private_key_extra'
CONN_SSH_WITH_EXTRA = 'ssh_with_extra'
+ CONN_SSH_WITH_EXTRA_FALSE_LOOK_FOR_KEYS =
'ssh_with_extra_false_look_for_keys'
@classmethod
def tearDownClass(cls) -> None:
@@ -80,6 +81,15 @@ class TestSSHHook(unittest.TestCase):
)
db.merge_conn(
Connection(
+ conn_id=cls.CONN_SSH_WITH_EXTRA_FALSE_LOOK_FOR_KEYS,
+ host='localhost',
+ conn_type='ssh',
+ extra='{"compress" : true, "no_host_key_check" : "true", '
+ '"allow_host_key_change": false, "look_for_keys": false}'
+ )
+ )
+ db.merge_conn(
+ Connection(
conn_id=cls.CONN_SSH_WITH_PRIVATE_KEY_EXTRA,
host='localhost',
conn_type='ssh',
@@ -107,7 +117,8 @@ class TestSSHHook(unittest.TestCase):
timeout=10,
compress=True,
port='port',
- sock=None
+ sock=None,
+ look_for_keys=True
)
@mock.patch('airflow.providers.ssh.hooks.ssh.paramiko.SSHClient')
@@ -126,7 +137,8 @@ class TestSSHHook(unittest.TestCase):
timeout=10,
compress=True,
port='port',
- sock=None
+ sock=None,
+ look_for_keys=True
)
@mock.patch('airflow.providers.ssh.hooks.ssh.SSHTunnelForwarder')
@@ -173,6 +185,11 @@ class TestSSHHook(unittest.TestCase):
self.assertEqual(ssh_hook.compress, True)
self.assertEqual(ssh_hook.no_host_key_check, True)
self.assertEqual(ssh_hook.allow_host_key_change, False)
+ self.assertEqual(ssh_hook.look_for_keys, True)
+
+ def test_conn_with_extra_parameters_false_look_for_keys(self):
+ ssh_hook =
SSHHook(ssh_conn_id=self.CONN_SSH_WITH_EXTRA_FALSE_LOOK_FOR_KEYS)
+ self.assertEqual(ssh_hook.look_for_keys, False)
@mock.patch('airflow.providers.ssh.hooks.ssh.SSHTunnelForwarder')
def test_tunnel_with_private_key(self, ssh_mock):
@@ -247,5 +264,6 @@ class TestSSHHook(unittest.TestCase):
timeout=10,
compress=True,
port='port',
- sock=None
+ sock=None,
+ look_for_keys=True
)