def add_ssh_host(*, name, host, port, login, password): storm_ = Storm() try: storm_.delete_entry(name) except ValueError: pass storm_.add_entry( name, host, login, port, id_file='', # With these options there will be no stupid interactive # questions on ssh key uploading. custom_options=[ 'StrictHostKeyChecking=no', 'UserKnownHostsFile=/dev/null', ], ) # TODO can be insecure. Copy the password to a local file # with 0600 permissions and use the file with `-f` option. local(f'sshpass -p {password} ssh-copy-id {name}')
def execute_host(args): if not args.subcommand == 'list' and not args.host: puts(red('--host is required')) return ssh_config = Storm() if args.subcommand == 'list': for entry in ssh_config.list_entries(): puts(green(entry['host'])) elif args.subcommand == 'add': result = parse(args.connection_url) puts(result) ssh_config.add_entry(args.host, host=result[1], user=result[0], port=result[2], id_file=args.id_file) for entry in ssh_config.list_entries(): puts(green(entry['host'])) elif args.subcommand == 'delete': ssh_config.delete_entry(args.host) for entry in ssh_config.list_entries(): puts(green(entry['host']))
class StormTests(unittest.TestCase): def setUp(self): FAKE_SSH_CONFIG = """Host * IdentitiesOnly yes Host netscaler hostname 1.1.1.1 port 3367 """ with open('/tmp/ssh_config', 'w+') as f: f.write(FAKE_SSH_CONFIG) self.storm = Storm('/tmp/ssh_config') def test_config_load(self): self.assertEqual( self.storm.ssh_config.config_data[1]["options"]["identitiesonly"], 'yes') def test_config_dump(self): self.storm.ssh_config.write_to_ssh_config() for search_str in ("hostname 1.1.1.1", "Host netscaler", "Host *"): with open('/tmp/ssh_config') as fd: self.assertIn(search_str, fd.read()) def test_update_host(self): self.storm.ssh_config.update_host("netscaler", {"hostname": "2.2.2.2"}) self.assertEqual( self.storm.ssh_config.config_data[4]["options"]["hostname"], '2.2.2.2') def test_add_host(self): self.storm.add_entry('google', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.add_entry('goog', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() for item in self.storm.ssh_config.config_data: if item.get("host") == 'google' or item.get("host") == 'goog': self.assertEqual(item.get("options").get("port"), '22') self.assertEqual( item.get("options").get("identityfile"), '/tmp/tmp.pub') def test_edit_host(self): self.storm.add_entry('google', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() self.storm.edit_entry('google', 'google.com', 'root', '23', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() for item in self.storm.ssh_config.config_data: if item.get("host") == 'google': self.assertEqual(item.get("options").get("port"), '23') def test_edit_by_hostname_regexp(self): import re self.storm.add_entry('google-01', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.add_entry('google-02', 'google.com', 'root', '23', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() self.storm.update_entry('google-[0-2]', port='24', identityfile='/tmp/tmp.pub1') for item in self.storm.ssh_config.config_data: if re.match(r"google*", item.get("host")): self.assertEqual( item.get("options").get("identityfile"), '/tmp/tmp.pub1') self.assertEqual(item.get("options").get("port"), '24') def test_delete_host(self): self.storm.delete_entry('netscaler') for host in self.storm.ssh_config.config_data: self.assertEqual(False, host.get("host") == 'netscaler') def test99_delete_all(self): self.storm.delete_all_entries() self.assertEqual(len(self.storm.ssh_config.config_data), 0) def test_uri_parser(self): user = getpass.getuser() TEST_STRINGS = [('[email protected]:22', ('root', 'emreyilmaz.me', 22)), ('emreyilmaz.me', (user, 'emreyilmaz.me', 22)), ('emreyilmaz.me:22', (user, 'emreyilmaz.me', 22)), ('*****@*****.**', ('root', 'emreyilmaz.me', 22))] for uri in TEST_STRINGS: self.assertEqual(parse(uri[0]), uri[1]) # false strings self.assertRaises(StormInvalidPortError, parse, '[email protected]:string-port') def test_search_host(self): results = self.storm.ssh_config.search_host("netsca") self.assertEqual(len(results), 1) def test_custom_options(self): custom_options = ( "StrictHostKeyChecking=no", "UserKnownHostsFile=/dev/null", ) self.storm.add_entry('host_with_custom_option', 'emre.io', 'emre', 22, None, custom_options=custom_options) self.storm.ssh_config.write_to_ssh_config() for item in self.storm.ssh_config.config_data: if item.get("host") == 'host_with_custom_option': self.assertEqual( item.get("options").get("StrictHostKeyChecking"), 'no') self.assertEqual( item.get("options").get("UserKnownHostsFile"), '/dev/null') custom_options = ( "StrictHostKeyChecking=yes", "UserKnownHostsFile=/home/emre/foo", ) self.storm.edit_entry('host_with_custom_option', 'emre.io', 'emre', 22, None, custom_options=custom_options) self.storm.ssh_config.write_to_ssh_config() for item in self.storm.ssh_config.config_data: if item.get("host") == 'host_with_custom_option': self.assertEqual( item.get("options").get("StrictHostKeyChecking"), 'yes') self.assertEqual( item.get("options").get("UserKnownHostsFile"), '/home/emre/foo') def tearDown(self): os.unlink('/tmp/ssh_config')
class StormTests(unittest.TestCase): def setUp(self): FAKE_SSH_CONFIG = """Host * IdentitiesOnly yes Host netscaler hostname 1.1.1.1 port 3367 """ f = open('/tmp/ssh_config', 'w+') f.write(FAKE_SSH_CONFIG) f.close() self.storm = Storm('/tmp/ssh_config') def test_config_load(self): self.assertEqual(self.storm.ssh_config.config_data[1]["options"]["identitiesonly"], 'yes') def test_config_dump(self): self.storm.ssh_config.write_to_ssh_config() for search_str in ["hostname 1.1.1.1", "Host netscaler", "Host *"]: self.assertEqual(True, search_str in open('/tmp/ssh_config').read()) def test_update_host(self): self.storm.ssh_config.update_host("netscaler", {"hostname": "2.2.2.2"}) self.assertEqual(self.storm.ssh_config.config_data[4]["options"]["hostname"], '2.2.2.2') def test_add_host(self): self.storm.add_entry('google', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() for item in self.storm.ssh_config.config_data: if item.get("host") == 'google': self.assertEqual(item.get("options").get("port"), '22') self.assertEqual(item.get("options").get("identityfile"), '/tmp/tmp.pub') def test_edit_host(self): self.storm.add_entry('google', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() self.storm.edit_entry('google', 'google.com', 'root', '23', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() for item in self.storm.ssh_config.config_data: if item.get("host") == 'google': self.assertEqual(item.get("options").get("port"), '23') def test_delete_host(self): self.storm.delete_entry('netscaler') for host in self.storm.ssh_config.config_data: self.assertEqual(False, host.get("host") == 'netscaler') def test99_delete_all(self): self.storm.delete_all_entries() self.assertEqual(len(self.storm.ssh_config.config_data), 0) def test_uri_parser(self): user = getpass.getuser() TEST_STRINGS = [ ('[email protected]:22', ('root', 'emreyilmaz.me', 22)), ('emreyilmaz.me', (user, 'emreyilmaz.me', 22)), ('emreyilmaz.me:22', (user, 'emreyilmaz.me', 22)), ('*****@*****.**', ('root', 'emreyilmaz.me', 22)) ] for uri in TEST_STRINGS: self.assertEqual(parse(uri[0]), uri[1]) # false strings self.assertRaises(StormInvalidPortError, parse, '[email protected]:string-port') def test_search_host(self): results = self.storm.ssh_config.search_host("netsca") self.assertEqual(len(results), 1) def tearDown(self): os.unlink('/tmp/ssh_config')
class StormTests(unittest.TestCase): def setUp(self): FAKE_SSH_CONFIG = """Host * IdentitiesOnly yes Host netscaler hostname 1.1.1.1 port 3367 """ with open('/tmp/ssh_config', 'w+') as f: f.write(FAKE_SSH_CONFIG) self.storm = Storm('/tmp/ssh_config') def test_config_load(self): self.assertEqual(self.storm.ssh_config.config_data[1]["options"]["identitiesonly"], 'yes') def test_config_dump(self): self.storm.ssh_config.write_to_ssh_config() for search_str in ("hostname 1.1.1.1", "Host netscaler", "Host *"): with open('/tmp/ssh_config') as fd: self.assertIn(search_str, fd.read()) def test_update_host(self): self.storm.ssh_config.update_host("netscaler", {"hostname": "2.2.2.2"}) self.assertEqual(self.storm.ssh_config.config_data[4]["options"]["hostname"], '2.2.2.2') def test_add_host(self): self.storm.add_entry('google', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.add_entry('goog', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() for item in self.storm.ssh_config.config_data: if item.get("host") == 'google' or item.get("host") == 'goog': self.assertEqual(item.get("options").get("port"), '22') self.assertEqual(item.get("options").get("identityfile"), '/tmp/tmp.pub') def test_edit_host(self): self.storm.add_entry('google', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() self.storm.edit_entry('google', 'google.com', 'root', '23', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() for item in self.storm.ssh_config.config_data: if item.get("host") == 'google': self.assertEqual(item.get("options").get("port"), '23') def test_edit_by_hostname_regexp(self): import re self.storm.add_entry('google-01', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.add_entry('google-02', 'google.com', 'root', '23', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() self.storm.update_entry('google-[0-2]', port='24', identityfile='/tmp/tmp.pub1') for item in self.storm.ssh_config.config_data: if re.match(r"google*", item.get("host")): self.assertEqual(item.get("options").get("identityfile"), '/tmp/tmp.pub1') self.assertEqual(item.get("options").get("port"), '24') def test_delete_host(self): self.storm.delete_entry('netscaler') for host in self.storm.ssh_config.config_data: self.assertEqual(False, host.get("host") == 'netscaler') def test99_delete_all(self): self.storm.delete_all_entries() self.assertEqual(len(self.storm.ssh_config.config_data), 0) def test_uri_parser(self): user = getpass.getuser() TEST_STRINGS = [ ('[email protected]:22', ('root', 'emreyilmaz.me', 22)), ('emreyilmaz.me', (user, 'emreyilmaz.me', 22)), ('emreyilmaz.me:22', (user, 'emreyilmaz.me', 22)), ('*****@*****.**', ('root', 'emreyilmaz.me', 22)) ] for uri in TEST_STRINGS: self.assertEqual(parse(uri[0]), uri[1]) # false strings self.assertRaises(StormInvalidPortError, parse, '[email protected]:string-port') def test_search_host(self): results = self.storm.ssh_config.search_host("netsca") self.assertEqual(len(results), 1) def test_custom_options(self): custom_options = ( "StrictHostKeyChecking=no", "UserKnownHostsFile=/dev/null", ) self.storm.add_entry('host_with_custom_option', 'emre.io', 'emre', 22, None, custom_options=custom_options) self.storm.ssh_config.write_to_ssh_config() for item in self.storm.ssh_config.config_data: if item.get("host") == 'host_with_custom_option': self.assertEqual(item.get("options").get("StrictHostKeyChecking"), 'no') self.assertEqual(item.get("options").get("UserKnownHostsFile"), '/dev/null') custom_options = ( "StrictHostKeyChecking=yes", "UserKnownHostsFile=/home/emre/foo", ) self.storm.edit_entry('host_with_custom_option', 'emre.io', 'emre', 22, None, custom_options=custom_options) self.storm.ssh_config.write_to_ssh_config() for item in self.storm.ssh_config.config_data: if item.get("host") == 'host_with_custom_option': self.assertEqual(item.get("options").get("StrictHostKeyChecking"), 'yes') self.assertEqual(item.get("options").get("UserKnownHostsFile"), '/home/emre/foo') def tearDown(self): os.unlink('/tmp/ssh_config')
class StormTests(unittest.TestCase): def setUp(self): FAKE_SSH_CONFIG = """Host * IdentitiesOnly yes Host netscaler hostname 1.1.1.1 port 3367 """ f = open('/tmp/ssh_config', 'w+') f.write(FAKE_SSH_CONFIG) f.close() self.storm = Storm('/tmp/ssh_config') def test_config_load(self): self.assertEqual(len(self.storm.ssh_config.config_data), 2) self.assertEqual(self.storm.ssh_config.config_data[0]["options"]["identitiesonly"], 'yes') def test_config_dump(self): self.storm.ssh_config.write_to_ssh_config() for search_str in ["hostname 1.1.1.1", "Host netscaler", "Host *"]: self.assertEqual(True, search_str in open('/tmp/ssh_config').read()) def test_update_host(self): self.storm.ssh_config.update_host("netscaler", {"hostname": "2.2.2.2"}) self.assertEqual(self.storm.ssh_config.config_data[1]["options"]["hostname"], '2.2.2.2') def test_add_host(self): self.storm.add_entry('google', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() self.assertEqual(len(self.storm.ssh_config.config_data), 3) self.assertEqual(self.storm.ssh_config.config_data[2]["options"]["hostname"], 'google.com') def test_edit_host(self): self.storm.add_entry('google', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() self.storm.edit_entry('google', 'google.com', 'root', '23', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() self.assertEqual(len(self.storm.ssh_config.config_data), 3) self.assertEqual(self.storm.ssh_config.config_data[2]["options"]["port"], '23') def test_delete_host(self): self.storm.delete_entry('netscaler') for host in self.storm.ssh_config.config_data: self.assertEqual(False, host.get("host") == 'netscaler') def test99_delete_all(self): self.storm.delete_all_entries() self.assertEqual(len(self.storm.ssh_config.config_data), 0) def tearDown(self): os.unlink('/tmp/ssh_config')
class StormTests(unittest.TestCase): def setUp(self): FAKE_SSH_CONFIG = """Host * IdentitiesOnly yes Host netscaler hostname 1.1.1.1 port 3367 """ f = open('/tmp/ssh_config', 'w+') f.write(FAKE_SSH_CONFIG) f.close() self.storm = Storm('/tmp/ssh_config') def test_config_load(self): self.assertEqual( self.storm.ssh_config.config_data[1]["options"]["identitiesonly"], 'yes') def test_config_dump(self): self.storm.ssh_config.write_to_ssh_config() for search_str in ["hostname 1.1.1.1", "Host netscaler", "Host *"]: self.assertEqual(True, search_str in open('/tmp/ssh_config').read()) def test_update_host(self): self.storm.ssh_config.update_host("netscaler", {"hostname": "2.2.2.2"}) self.assertEqual( self.storm.ssh_config.config_data[4]["options"]["hostname"], '2.2.2.2') def test_add_host(self): self.storm.add_entry('google', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() for item in self.storm.ssh_config.config_data: if item.get("host") == 'google': self.assertEqual(item.get("options").get("port"), '22') self.assertEqual( item.get("options").get("identityfile"), '/tmp/tmp.pub') def test_edit_host(self): self.storm.add_entry('google', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() self.storm.edit_entry('google', 'google.com', 'root', '23', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() for item in self.storm.ssh_config.config_data: if item.get("host") == 'google': self.assertEqual(item.get("options").get("port"), '23') def test_delete_host(self): self.storm.delete_entry('netscaler') for host in self.storm.ssh_config.config_data: self.assertEqual(False, host.get("host") == 'netscaler') def test99_delete_all(self): self.storm.delete_all_entries() self.assertEqual(len(self.storm.ssh_config.config_data), 0) def test_uri_parser(self): user = getpass.getuser() TEST_STRINGS = [('[email protected]:22', ('root', 'emreyilmaz.me', 22)), ('emreyilmaz.me', (user, 'emreyilmaz.me', 22)), ('emreyilmaz.me:22', (user, 'emreyilmaz.me', 22)), ('*****@*****.**', ('root', 'emreyilmaz.me', 22))] for uri in TEST_STRINGS: self.assertEqual(parse(uri[0]), uri[1]) # false strings self.assertRaises(StormInvalidPortError, parse, '[email protected]:string-port') def test_search_host(self): results = self.storm.ssh_config.search_host("netsca") self.assertEqual(len(results), 1) def tearDown(self): os.unlink('/tmp/ssh_config')
class StormTests(unittest.TestCase): def setUp(self): FAKE_SSH_CONFIG = """Host * IdentitiesOnly yes Host netscaler hostname 1.1.1.1 port 3367 """ f = open('/tmp/ssh_config', 'w+') f.write(FAKE_SSH_CONFIG) f.close() self.storm = Storm('/tmp/ssh_config') def test_config_load(self): self.assertEqual(len(self.storm.ssh_config.config_data), 2) self.assertEqual( self.storm.ssh_config.config_data[0]["options"]["identitiesonly"], 'yes') def test_config_dump(self): self.storm.ssh_config.write_to_ssh_config() for search_str in ["hostname 1.1.1.1", "Host netscaler", "Host *"]: self.assertEqual(True, search_str in open('/tmp/ssh_config').read()) def test_update_host(self): self.storm.ssh_config.update_host("netscaler", {"hostname": "2.2.2.2"}) self.assertEqual( self.storm.ssh_config.config_data[1]["options"]["hostname"], '2.2.2.2') def test_add_host(self): self.storm.add_entry('google', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() self.assertEqual(len(self.storm.ssh_config.config_data), 3) self.assertEqual( self.storm.ssh_config.config_data[2]["options"]["hostname"], 'google.com') def test_edit_host(self): self.storm.add_entry('google', 'google.com', 'root', '22', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() self.storm.edit_entry('google', 'google.com', 'root', '23', '/tmp/tmp.pub') self.storm.ssh_config.write_to_ssh_config() self.assertEqual(len(self.storm.ssh_config.config_data), 3) self.assertEqual( self.storm.ssh_config.config_data[2]["options"]["port"], '23') def test_delete_host(self): self.storm.delete_entry('netscaler') for host in self.storm.ssh_config.config_data: self.assertEqual(False, host.get("host") == 'netscaler') def test99_delete_all(self): self.storm.delete_all_entries() self.assertEqual(len(self.storm.ssh_config.config_data), 0) def tearDown(self): os.unlink('/tmp/ssh_config')