Skip to content
This repository was archived by the owner on Dec 21, 2022. It is now read-only.

Commit 41ec1aa

Browse files
committed
Merge pull request #103 from emre/issue-99
Add clone and backup commands
2 parents de34cbc + 8e280f3 commit 41ec1aa

File tree

4 files changed

+80
-4
lines changed

4 files changed

+80
-4
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
setup(
66
name='stormssh',
7-
version='0.6.5',
7+
version='0.6.6',
88
packages=find_packages(),
99
package_data={'storm': ['templates/*.html', 'static/css/*.css',
1010
'static/css/themes/storm/*.css', 'static/css/themes/storm/img/*.png',

storm/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from operator import itemgetter
66
import re
7+
from shutil import copyfile
78

89
from .parsers.ssh_config_parser import ConfigParser
910
from .defaults import get_default
@@ -36,8 +37,7 @@ def add_entry(self, name, host, user, port, id_file, custom_options=[]):
3637

3738
return True
3839

39-
40-
def clone_entry(self, name, clone_name):
40+
def clone_entry(self, name, clone_name, keep_original=True):
4141
host = self.is_host_in(name, return_match=True)
4242
if not host:
4343
raise ValueError(ERRORS["not_found"].format(name))
@@ -47,6 +47,8 @@ def clone_entry(self, name, clone_name):
4747
raise ValueError(ERRORS["already_in"].format(clone_name))
4848

4949
self.ssh_config.add_host(clone_name, host.get('options'))
50+
if not keep_original:
51+
self.ssh_config.delete_host(name)
5052
self.ssh_config.write_to_ssh_config()
5153

5254
return True
@@ -140,3 +142,6 @@ def is_host_in(self, host, return_match = False, regexp_match=False):
140142
if host_.get("host") == host or (regexp_match and re.match(host, host_.get("host"))):
141143
return True if not return_match else host_
142144
return False if not return_match else None
145+
146+
def backup(self, target_file):
147+
return copyfile(self.ssh_config.ssh_config_file, target_file)

storm/__main__.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,33 @@ def clone(name, clone_name, config=None):
8181
except ValueError as error:
8282
print(get_formatted_message(error, 'error'), file=sys.stderr)
8383

84+
@command('move')
85+
def move(name, entry_name, config=None):
86+
"""
87+
Move an entry to the sshconfig.
88+
"""
89+
storm_ = get_storm_instance(config)
90+
91+
try:
92+
93+
# validate name
94+
if '@' in name:
95+
raise ValueError('invalid value: "@" cannot be used in name.')
96+
97+
storm_.clone_entry(name, entry_name, keep_original=False)
98+
99+
print(
100+
get_formatted_message(
101+
'{0} moved in ssh config. you can '
102+
'connect it by typing "ssh {0}".'.format(
103+
entry_name
104+
),
105+
'success')
106+
)
107+
108+
except ValueError as error:
109+
print(get_formatted_message(error, 'error'), file=sys.stderr)
110+
84111

85112
@command('edit')
86113
def edit(name, connection_uri, id_file="", o=[], config=None):
@@ -234,6 +261,16 @@ def delete_all(config=None):
234261
except Exception as error:
235262
print(get_formatted_message(str(error), 'error'), file=sys.stderr)
236263

264+
@command('backup')
265+
def backup(target_file, config=None):
266+
"""
267+
Backups the main ssh configuration into target file.
268+
"""
269+
storm_ = get_storm_instance(config)
270+
try:
271+
storm_.backup(target_file)
272+
except Exception as error:
273+
print(get_formatted_message(str(error), 'error'), file=sys.stderr)
237274

238275
@command('web')
239276
@arg('port', nargs='?', default=9002, type=int)

tests.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,12 @@ def test_search(self):
272272
self.assertTrue(out.startswith(b'Listing results for aws:'))
273273
self.assertIn(b'aws.apache', out)
274274

275+
def test_backup(self):
276+
out, err, rc = self.run_cmd("backup /tmp/ssh_backup {0}".format(
277+
self.config_arg))
278+
279+
self.assertEqual(True, os.path.exists("/tmp/ssh_backup"))
280+
275281
def test_invalid_search(self):
276282

277283
out, err, rc = self.run_cmd("search THEREISNOTHINGRELATEDWITHME {0}".format(self.config_arg))
@@ -283,7 +289,6 @@ def test_delete_all(self):
283289

284290
self.assertIn(b'all entries deleted', out)
285291

286-
287292
def tearDown(self):
288293
os.unlink('/tmp/ssh_config_cli_tests')
289294

@@ -344,6 +349,35 @@ def test_clone_host(self):
344349
self.assertEqual(item.get("options").get("identityfile"), '/tmp/tmp.pub')
345350
self.assertEqual(item.get("options").get("user"), 'ops')
346351

352+
def test_move_host(self):
353+
self.storm.add_entry('google', 'google.com', 'ops', '24', '/tmp/tmp.pub')
354+
self.storm.clone_entry('google', 'yahoo', keep_original=False)
355+
356+
has_yahoo = False
357+
for item in self.storm.ssh_config.config_data:
358+
if item.get("host") == 'yahoo':
359+
has_yahoo = True
360+
break
361+
362+
has_google = False
363+
for item in self.storm.ssh_config.config_data:
364+
if item.get("host") == 'google':
365+
has_google = True
366+
break
367+
368+
self.assertEqual(True, has_yahoo)
369+
self.assertEqual(False, has_google)
370+
self.assertEqual(item.get("options").get("port"), '24')
371+
self.assertEqual(item.get("options").get("identityfile"), '/tmp/tmp.pub')
372+
self.assertEqual(item.get("options").get("user"), 'ops')
373+
374+
def test_backup(self):
375+
self.storm.backup("/tmp/storm_ssh_config_backup_file")
376+
self.assertEqual(
377+
True,
378+
os.path.exists("/tmp/storm_ssh_config_backup_file")
379+
)
380+
347381
def test_double_clone_exception(self):
348382
self.storm.add_entry('google', 'google.com', 'ops', '24', '/tmp/tmp.pub')
349383
self.storm.clone_entry('google', 'yahoo')

0 commit comments

Comments
 (0)