Manage your SSH like a boss.

Overview

---

Join the chat at https://gitter.im/emre/storm

Build Status

storm is a command line tool to manage your ssh connections.

features

  • adding, editing, deleting, listing, searching across your SSHConfig.
  • command alias support for your CLI preferences.
  • support for custom SSH directives.
  • scriptable as a python library.
  • user interfaces besides cli. (web ui, wxpython, unity(ubuntu) indicator.)

dependencies

On Debian systems, install header files and a static library for Python (python3.4-dev or python2.7-dev)

On Ubuntu 16.04, you need install libssl-dev and libffi-dev (sudo apt-get install libssl-dev libffi-dev)

installation

$ [sudo] pip install stormssh

or if you like 90s:

$ [sudo] easy_install stormssh

or if you like homebrew:

$ brew install stormssh

or if prefer using a package manager in your distro:

Distro Package
Archlinux python-stormssh
Opensuse python-stormssh
Void Linux python-stormssh

troubleshooting installation

clang: error: unknown argument: '-mno-fused-madd'

error: command 'cc' failed with exit status 1

See #73. If the issue persists, see also #76 .

usage & documentation

http://stormssh.readthedocs.org/en/master/

screens

web ui

Comments
  • Should this project be considered dead?

    Should this project be considered dead?

    No offense, just asking myself if @emre is no longer active.

    If not, does it make sense to pick a community fork as the successor or simply invite interested contributors? They are already a number of forks

    opened by EugenMayer 10
  • added additional plural() check so page is updated with correct data

    added additional plural() check so page is updated with correct data

    (thanks to @axyjo)

    Issue: plural() is called only before servers is populated, so an "s" is never added to "connection" on the Storm web UI Fix: call plural() again once data is fetched

    opened by squircle 9
  • Why there's no password management?

    Why there's no password management?

    First of all, this tool is awesome! Thank you very much! It's a life saver.

    But I couldn't help myself wondering why there's no password management. Remembering all passwords from different connections is a pain and I think it could help a lot if storm could store them.

    I don't know if Windows and Linux have a password management program, but Mac has the Keychain where all passwords, certificates, etc are stored. You could use one of these tools to persist the user's passwords.

    design decision 
    opened by fjcaetano 9
  • Error when using optional arguments

    Error when using optional arguments

    Not storm specific but affects its usage. This happened to me after upgrading.

    $ storm add --id_file test test.com
    Traceback (most recent call last):
      File "/usr/local/bin/storm", line 8, in <module>
        load_entry_point('stormssh==0.6.1', 'console_scripts', 'storm')()
      File "/Library/Python/2.7/site-packages/storm/kommandr.py", line 188, in __call__
        self.execute(sys.argv[1:])
      File "/Library/Python/2.7/site-packages/storm/kommandr.py", line 179, in execute
        arg_map = self.parser.parse_args(arg_list).__dict__
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1688, in parse_args
        args, argv = self.parse_known_args(args, namespace)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1720, in parse_known_args
        namespace, args = self._parse_known_args(args, namespace)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1908, in _parse_known_args
        positionals_end_index = consume_positionals(start_index)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1885, in consume_positionals
        take_action(action, args)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1794, in take_action
        action(self, namespace, argument_values, option_string)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1090, in __call__
        namespace, arg_strings = parser.parse_known_args(arg_strings, namespace)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1720, in parse_known_args
        namespace, args = self._parse_known_args(args, namespace)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1926, in _parse_known_args
        start_index = consume_optional(start_index)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1866, in consume_optional
        take_action(action, args, option_string)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1794, in take_action
        action(self, namespace, argument_values, option_string)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 928, in __call__
        items.append(values)
    AttributeError: 'str' object has no attribute 'append'
    

    Whereas not using optional arguments does not throwout the same error:

    $ storm add google google.com
    success  google added to your ssh config. you can connect it by typing "ssh google".
    

    I can look into this too but I just thought it should be documented.

    bug 
    opened by jeunito 8
  • Enhanced edit feature

    Enhanced edit feature

    Here are some enhancements that I think will be useful.

    1. Multiple edits via regular expression on host
    [email protected]:/vagrant$ python storm/ list
    listing entries:
        google-01 -> [email protected]:22 
        [custom options] identityfile=/home/vagrant/.ssh/test
    
        google-02 -> [email protected]:22 
        [custom options] identityfile=/home/vagrant/.ssh/test
    
    [email protected]:/vagrant$ python storm/ edit google-0[1-2] --o user=test
    success  "google-0[1-2]" updated successfully.
    

    Multiple edit modifies config of hosts who match regular expression

    [email protected]:/vagrant$ python storm/ list
    listing entries:
        google-01 -> [email protected]:22 
        [custom options] identityfile=/home/vagrant/.ssh/test
    
        google-02 -> [email protected]:22 
        [custom options] identityfile=/home/vagrant/.ssh/test
    
    1. Modified usage of edit; id_file and connection_uri are now optional. If they are not passed their values will not change. Saves some typing.
    usage: storm edit [-h] [--connection_uri CONNECTION_URI] [--id_file ID_FILE]
                      [--o O]
                      name
    
    positional arguments:
      name
    
    optional arguments:
      -h, --help            show this help message and exit
      --connection_uri CONNECTION_URI
      --id_file ID_FILE
      --o O
    
    opened by jeunito 8
  • Feature request: The ability to clone host entries

    Feature request: The ability to clone host entries

    Use case:

    storm list
    love -> [email protected]:22 
            [custom options] compressionlevel=6 compression=yes
    

    Say I wanted to create a similar entry as love called hate I can then call:

    storm clone love hate

    Then I will have two entries :

    storm list
    love -> [email protected]:22 
            [custom options] compressionlevel=6 compression=yes
    
    hate -> [email protected]:22 
            [custom options] compressionlevel=6 compression=yes
    
    feature request 
    opened by lowks 7
  • ImportError: cannot import name proxy_re

    ImportError: cannot import name proxy_re

    I've installed storm via pip and I get the above error when I try running it.

    I've checked and paramiko is installed as part of dist-packages

    I'm using: Ubuntu 12.10 Python 2.7.3

    Thanks,

    opened by Braynid 7
  • no module named manage

    no module named manage

    Attempting to run on cygwin (Windows). Installed per readme, returned with error:

    $ storm
    Traceback (most recent call last):
      File "/cygdrive/c/Users/jhertens/storm/storm/bin/storm", line 4, in <module>
        from manage import Manager
    ImportError: No module named manage
    
    opened by JakeHertenstein 7
  • Use port 22 when no port is specified

    Use port 22 when no port is specified

    If no port is specified then storm should use the standard port I think. In general None should not be used in the output.

    example.com -> [email protected]:None

    opened by pxlpnk 6
  • storm wipes ssh config if error is thrown

    storm wipes ssh config if error is thrown

    I have an ssh file configured like so:

    ======= contents of ~/.ssh/config =========
    ServerAliveCountMax 6
    ControlMaster auto
    ControlPath ~/.ssh/ssh_control_%h_%p_%r
    StrictHostKeyChecking no
    UserKnownHostsFile=/dev/null
    User            alex.gray
    IdentityFile    ~/Documents/my_id_rsa
    
    Host github.com
        controlmaster no
    ====================================
    

    And when I run the following command, it completely deletes my ssh config: storm add my_vps [email protected]:22

    Traceback (most recent call last):
      File "/Users/alexgray/.virtualenvs/skippy/bin/storm", line 11, in <module>
        sys.exit(main())
      File "/Users/alexgray/.virtualenvs/skippy/lib/python3.4/site-packages/storm/kommandr.py", line 195, in __call__
        self.execute(sys.argv[1:])
      File "/Users/alexgray/.virtualenvs/skippy/lib/python3.4/site-packages/storm/kommandr.py", line 188, in execute
        return command(**arg_map)
      File "/Users/alexgray/.virtualenvs/skippy/lib/python3.4/site-packages/storm/__main__.py", line 51, in add
        storm_.add_entry(name, host, user, port, id_file, o)
      File "/Users/alexgray/.virtualenvs/skippy/lib/python3.4/site-packages/storm/__init__.py", line 37, in add_entry
        self.ssh_config.write_to_ssh_config()
      File "/Users/alexgray/.virtualenvs/skippy/lib/python3.4/site-packages/storm/parsers/ssh_config_parser.py", line 228, in write_to_ssh_config
        data = self.dump()
      File "/Users/alexgray/.virtualenvs/skippy/lib/python3.4/site-packages/storm/parsers/ssh_config_parser.py", line 203, in dump
        self.config_data = sorted(self.config_data, key=itemgetter("order"))
    TypeError: unorderable types: NoneType() < int()
    

    And now my ssh config is completely deleted :(

    Storm should do one or all of the following:

    1. never wipe the ssh config on a storm failure.
    2. possibly create a backup of the ssh config to see what changed.
    3. when reading the ssh config, strip everything outside a hosts section, modify the file in memory, and add the text that we stripped BACK into the generated ssh config.

    This is using the following version of storm: $ pip list | grep storm stormssh (0.6.7)

    opened by grayaii 5
  • Spaces In 'identityfile' Path

    Spaces In 'identityfile' Path

    Depending on how a user chooses to manage their identities, keys might exist in folders that are named with spaces. In this case, no combination of quoting or escaping the spaces while using storm add results in a quoted identityfile line in ~/.ssh/config. To get such hosts to work, the line must be manually quoted. Would it be possible to ensure that if ' --id_file' is quoted on the command line, those quotes are persisted through to SSH config?

    ╭─[email protected]  ~/dev ‹›
    ╰─$ storm add --id_file "~/keys/folde with spaces/some_key" test_host [email protected]
    success  test_host added to your ssh config. you can connect it by typing "ssh test_host".
    ╭─[email protected]  ~/dev ‹›
    ╰─$ tail ~/.ssh/config
    Host test_host
        identityfile ~/keys/folde with spaces/some_key
        hostname 123.123.123.123
        user ubuntu
        port 22
    ╭─[email protected]  ~/dev ‹›
    ╰─$ ssh test_host
    /Users/max/.ssh/config line 407: garbage at end of line; "with".
    
    opened by maxmanders 5
  • Blowfish is deprecated message

    Blowfish is deprecated message

    On macOS Ventura I am seeing the following message when running storm add:

    /opt/homebrew/Cellar/stormssh/0.7.0_9/libexec/lib/python3.10/site-packages/paramiko/transport.py:236: CryptographyDeprecationWarning: Blowfish has been deprecated
      "class": algorithms.Blowfish,
    
    opened by intrepidsilence 1
  • proxyjump not supported

    proxyjump not supported

    If I try and manage a host entry and change (for example) the hostname, it will update both the designated host in the config file, as well as any reference to that host in a proxyjump key. Proxycommand is an older style of jumping...can we get some love for proxyjump?

    opened by kalsto 0
  • Project dependencies may have API risk issues

    Project dependencies may have API risk issues

    Hi, In storm, inappropriate dependency versioning constraints can cause risks.

    Below are the dependencies and version constraints that the project is using

    paramiko==1.13.0
    termcolor*
    Flask==0.10.1
    six*
    

    The version constraint == will introduce the risk of dependency conflicts because the scope of dependencies is too strict. The version constraint No Upper Bound and * will introduce the risk of the missing API Error because the latest version of the dependencies may remove some APIs.

    After further analysis, in this project, The version constraint of dependency Flask can be changed to >=0.10,<=0.12.5.

    The above modification suggestions can reduce the dependency conflicts as much as possible, and introduce the latest version as much as possible without calling Error in the projects.

    The invocation of the current project includes all the following methods.

    The calling methods from the Flask
    json.dumps
    json.loads
    
    The calling methods from the all methods
    re.compile
    subparser.add_argument
    sys.exit
    get_default
    storm_.delete_all_entries
    key.options.strip
    f.write
    argparse.ArgumentParser
    get_storm_instance
    host_entry.get.get
    self.get_last_index
    self._generate_command
    self.ssh_config_file.open.close
    os.path.abspath
    self.AliasedSubParsersAction.super.add_parser
    host.get
    arg_map.pop
    self.get_options
    arg.startswith
    app.run
    line.rstrip
    self.ssh_config.add_host
    self._config.append
    get_storm_config
    join
    item.get
    sorted
    host_item.update
    self._choices_actions.append
    json.dumps
    index.self.config_data.update
    re.sub
    self.execute
    app.route
    range
    name.split
    kwargs.update
    line.lower
    storm_.delete_entry
    izip_longest
    StormConfig
    Flask
    indexes.append
    line.lower.strip
    _web.run
    self.ssh_config.delete_host
    itemgetter
    storm_.clone_entry
    send_from_directory
    key.strip.lower
    key.strip
    ERRORS.format
    self._AliasedPseudoAction
    self._quote_options
    dirname
    request.args.get
    make_response
    inspect.getargspec
    i.line.lower
    parse
    i.line.lstrip
    self.defaults.update
    host.get.get
    six.iteritems
    line.rstrip.lstrip
    defaults.get
    Exception
    self.ssh_config.delete_all_hosts
    new_config_data.append
    reversed
    host_entry.get
    host_item.get
    list
    subparser.set_defaults
    argopts.get
    render
    ValueError
    config.__dict__.get
    self.parser.parse_args
    response
    fobj.read
    type
    uri.split
    option.split
    colored
    Response
    command
    self.dump
    getpass.getuser
    self.parser.add_subparsers
    storm_.update_entry
    chmod
    makedirs
    value.split
    ConfigParser
    host.update
    line.lower.strip.startswith
    match.group.lower
    self.ssh_config.write_to_ssh_config
    bool
    config.parse
    len
    key.host.append
    storm_.edit_entry
    self.ssh_config.update_host
    copyfile
    line.startswith
    sup.__init__
    int
    self.get_default_ssh_config_file
    key.lower
    super
    setup
    open
    filter
    self.parser.register
    results.append
    i.line.isspace
    options.update
    self.ssh_config.load
    arg
    storm_.add_entry
    max
    value.get
    entry.get
    self.ssh_config.search_host
    getattr
    storm_.list_entries
    self._POSITIONAL
    jsonify
    func.__doc__.strip
    fixed_width
    custom_option.split
    storm_.backup
    format
    Storm
    json.loads
    message.replace
    self.config_data.append
    self.subparsers.add_parser
    print
    os.path.join
    host_.get
    app.get_storm
    self.write_to_ssh_config
    line.split
    options.pop
    formatted_results.append
    main
    storm_config.get
    content.replace
    match.group
    self.parser.add_argument
    storm_.search_host
    enumerate
    exists
    prog
    expanduser
    kwargs.pop
    config_file.open.read
    get_formatted_message
    re.match
    find_packages
    uri.strip
    self._choices_actions.pop
    isinstance
    os.path.dirname
    proxy_re.match
    self.is_host_in
    str
    

    @developer Could please help me check this issue? May I pull a request to fix it? Thank you very much.

    opened by PyDeps 0
Releases(0.7.0)
Dynamic DNS service

About nsupdate.info https://nsupdate.info is a free dynamic DNS service. nsupdate.info is also the name of the software used to implement it. If you l

nsupdate.info development 880 Jan 04, 2023
A lobby boy will create a VPS server when you need one, and destroy it after using it.

Lobbyboy What is a lobby boy? A lobby boy is completely invisible, yet always in sight. A lobby boy remembers what people hate. A lobby boy anticipate

226 Dec 29, 2022
Cado Response Integration with Amazon GuardDuty using AWS Lambda

Cado Response Integration with Amazon GuardDuty using AWS Lambda This repository contains a simple example where: An alert is triggered by GuardDuty T

Cado Security 4 Mar 02, 2022
Deploying a production-ready Django project using Nginx and Gunicorn

django-nginx-gunicorn This project is for deploying a production-ready Django project using Nginx and Gunicorn. Running a local server of Django is no

Arash Sayareh 8 Jul 03, 2022
Dockerized service to backup all running database containers

Docker Database Backup Dockerized service to automatically backup all of your database containers. Docker Image Tags: docker.io/jandi/database-backup

Jan Dittrich 16 Dec 31, 2022
DAMPP (gui) is a Python based program to run simple webservers using MySQL, Php, Apache and PhpMyAdmin inside of Docker containers.

DAMPP (gui) is a Python based program to run simple webservers using MySQL, Php, Apache and PhpMyAdmin inside of Docker containers.

Sehan Weerasekara 1 Feb 19, 2022
IP address management (IPAM) and data center infrastructure management (DCIM) tool.

NetBox is an IP address management (IPAM) and data center infrastructure management (DCIM) tool. Initially conceived by the network engineering team a

NetBox Community 11.8k Jan 07, 2023
Emissary - open source Kubernetes-native API gateway for microservices built on the Envoy Proxy

Emissary-ingress Emissary-Ingress is an open-source Kubernetes-native API Gateway + Layer 7 load balancer + Kubernetes Ingress built on Envoy Proxy. E

Emissary Ingress 4k Dec 31, 2022
Simple ssh overlay for easy, remote server management written in Python GTK with paramiko

Simple "ssh" overlay for easy, remote server management written in Python GTK with paramiko

kłapouch 3 May 01, 2022
Python IMDB Docker - A docker tutorial to containerize a python script.

Python_IMDB_Docker A docker tutorial to containerize a python script. Build the docker in the current directory: docker build -t python-imdb . Run the

Sarthak Babbar 1 Dec 30, 2021
Tiny Git is a simplified version of Git with only the basic functionalities to gain better understanding of git internals.

Tiny Git is a simplified version of Git with only the basic functionalities to gain better understanding of git internals. Implemented Functi

Ahmed Ayman 2 Oct 15, 2021
A collection of beginner-friendly DevOps content

mansion Mansion is just a testing repo for learners to commit into open source project. These are the steps you need to learn: Please do not edit thes

Bryan Lim 62 Nov 30, 2022
Build and Push docker image in Python (luigi + docker-py)

Docker build images workflow in Python Since docker hub stopped building images for free accounts, I've been looking for another way to do it. I could

Fabien D. 2 Dec 15, 2022
Supervisor process control system for UNIX

Supervisor Supervisor is a client/server system that allows its users to control a number of processes on UNIX-like operating systems. Supported Platf

Supervisor 7.6k Dec 31, 2022
Caboto, the Kubernetes semantic analysis tool

Caboto Caboto, the Kubernetes semantic analysis toolkit. It contains a lightweight Python library for semantic analysis of plain Kubernetes manifests

Michael Schilonka 8 Nov 26, 2022
Ingress patch example by Kustomize

Ingress patch example by Kustomize

Jinu 10 Nov 14, 2022
Define and run multi-container applications with Docker

Docker Compose Docker Compose is a tool for running multi-container applications on Docker defined using the Compose file format. A Compose file is us

Docker 28.2k Jan 08, 2023
Push Container Image To Docker Registry In Python

push-container-image-to-docker-registry 概要 push-container-image-to-docker-registry は、エッジコンピューティング環境において、特定のエッジ端末上の Private Docker Registry に特定のコンテナイメー

Latona, Inc. 3 Nov 04, 2021
A charmed operator for running PGbouncer on kubernetes.

operator-template Description TODO: Describe your charm in a few paragraphs of Markdown Usage TODO: Provide high-level usage, such as required config

Canonical 1 Dec 01, 2022
Bash-based Python-venv convenience wrapper

venvrc Bash-based Python-venv convenience wrapper. Demo Install Copy venvrc file to ~/.venvrc, and add the following line to your ~/.bashrc file: # so

1 Dec 29, 2022