├── .gitignore ├── LICENSE ├── README.md ├── changelog ├── cli.py ├── example └── config_sample ├── pyproject.toml ├── sshclick ├── __init__.py ├── cmds │ ├── __init__.py │ ├── cmd_config.py │ ├── cmd_group.py │ ├── cmd_host.py │ ├── config │ │ ├── __init__.py │ │ ├── config_del.py │ │ ├── config_set.py │ │ └── config_show.py │ ├── group │ │ ├── __init__.py │ │ ├── group_create.py │ │ ├── group_delete.py │ │ ├── group_list.py │ │ ├── group_rename.py │ │ ├── group_set.py │ │ └── group_show.py │ └── host │ │ ├── __init__.py │ │ ├── host_create.py │ │ ├── host_delete.py │ │ ├── host_install_key.py │ │ ├── host_list.py │ │ ├── host_rename.py │ │ ├── host_set.py │ │ └── host_show.py ├── globals.py ├── main_cli.py ├── main_tui.py ├── sshc │ ├── __init__.py │ ├── host_styles │ │ ├── __init__.py │ │ ├── card.py │ │ ├── json.py │ │ ├── panels.py │ │ ├── simple.py │ │ ├── table.py │ │ └── table2.py │ ├── ssh_config.py │ ├── ssh_diff.py │ ├── ssh_graph.py │ ├── ssh_group.py │ ├── ssh_host.py │ ├── ssh_parameters.py │ └── ssh_utils.py ├── ssht │ ├── data_view.py │ ├── group_info.py │ ├── host_info.py │ ├── modal_action.py │ ├── modal_delete.py │ ├── node_tree.py │ ├── sshtui.py │ └── utils │ │ ├── __init__.py │ │ └── conn.py └── version.py ├── tapes ├── spash.tape ├── splash.gif ├── sshc_tui_example.svg └── tui_demo.tape ├── tests ├── __init__.py ├── test_1_config_parse_10_optional_equals.py ├── test_1_config_parse_1_empty.py ├── test_1_config_parse_2_host_case_insensitive.py ├── test_1_config_parse_3_host_single.py ├── test_1_config_parse_4_host_multi.py ├── test_1_config_parse_5_pattern.py ├── test_1_config_parse_6_groups_empty.py ├── test_1_config_parse_7_groups_full.py ├── test_1_config_parse_8_config_opts.py ├── test_1_config_parse_9_host_altnames.py ├── test_2_config_get_1_host.py ├── test_2_config_get_2_group.py ├── test_3_config_modify_1_host.py ├── test_3_config_modify_2_group.py ├── test_3_config_modify_3_config_opts.py └── test_4_config_inheritance.py └── tui.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Editor stuff 2 | .vscode 3 | *.swp 4 | *.swo 5 | *~ 6 | 7 | # Python caches... 8 | *.egg-info 9 | __pycache__ 10 | .mypy_cache 11 | .pytest_cache 12 | 13 | # pyenv stuff 14 | .python-version 15 | 16 | # Builds 17 | build 18 | dist 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Karlo Tisaj 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SSH Click Config manager (sshclick) 2 | 3 | ![splash_gif](https://raw.githubusercontent.com/karlot/sshclick/master/tapes/splash.gif) 4 | 5 | ## Links 6 | 7 | - [Intro](https://github.com/karlot/sshclick#intro) 8 | - [Why?](https://github.com/karlot/sshclick#why) 9 | - [What does it do](https://github.com/karlot/sshclick#what-does-it-do) 10 | - [Installation procedure](https://github.com/karlot/sshclick#installation-procedure) 11 | - [Upgrade procedure](https://github.com/karlot/sshclick#upgrade-procedure) 12 | - [Uninstall procedure](https://github.com/karlot/sshclick#uninstall-procedure) 13 | - [SSH Config structure](https://github.com/karlot/sshclick#ssh-config-structure-and-important-note-about-comments) 14 | - [Comment blocks and metadata](https://github.com/karlot/sshclick#comment-blocks-and-metadata-in-ssh-config) 15 | - [Example usage and features](https://github.com/karlot/sshclick#example-usage-and-features) 16 | - [Group commands and options](https://github.com/karlot/sshclick#group-commands-and-options) 17 | - [Host commands and options](https://github.com/karlot/sshclick#host-commands-and-options) 18 | - [Config commands and options](https://github.com/karlot/sshclick#config-commands-and-sshclick-configuration-options) 19 | - [Output styling and user ENV variables](https://github.com/karlot/sshclick#output-styling-and-user-env-variables) 20 | 23 | - [Author](https://github.com/karlot/sshclick#author) 24 | - [License](https://github.com/karlot/sshclick#license) 25 | 26 | ## Intro 27 | 28 | Terminal based assisted management of your SSH config files. 29 | Built out of boredom with managing messy and huge ssh_config files. 30 | 31 | Backup your SSH config files before using! 32 | SSHClick can be used with "show" and "list" commands for hosts, without modifying your SSH Config in any way! 33 | 34 | **Only commands that modify configuration will edit and rewrite/restructure your SSH Config file. In that case, any added comment or infos that are not in form that SSHClick understand will be discarded, and configuration will be re-formatted to match SSHClick style. See below details to understand how SSH Click would keep your config organized**! 35 | 36 | **NEW!** *Now comes with additional TUI that can be accessed via `ssht` command.* 37 | 38 | ![splash_gif](https://raw.githubusercontent.com/karlot/sshclick/master/tapes/sshc_tui_example.svg) 39 | 40 | ## Why? 41 | 42 | - I need something that works fast and great in terminal, and does not require complex setup. 43 | - SSH config is the only config I need to backup. 44 | - SSH config is very feature-full with all options SSH client support, why inventing extra layer? 45 | - I need quick way to search, group and visualize all hosts inside SSH configuration (especially since it can grow huge) 46 | 47 | ## What does it do? 48 | 49 | SSHClick (sshc) is just a tool designed to work with existing SSH configuration files on your Linux/Windows/WSL terminal environment. 50 | It parses your SSH config, and can provide easy commands to list, filter, modify or view specific Host entries. 51 | Trough additional "metadata" comments it can add abstractions such as "groups" and various information that is both readable in the configuration file, and can be parsed and printed while using the tool. 52 | 53 | ### Installation procedure 54 | 55 | 1. **Check preconditions:** 56 | - Currently only tested on Linux (Debian 10,11, Ubuntu 20.04,22.04), but should work on other systems as well 57 | - Minimum python3.7 (tested up to 3.11 beta) & pip installed 58 | - it is preferable to not use system python version, to install "custom" user python on linux, you can try using pyenv ( 59 | - git installed (for installing from source) 60 | 61 | 2. **Install package:** 62 | - from PyPI using pip 63 | 64 | ```console 65 | pip install sshclick 66 | ``` 67 | 68 | - (OR) from source using pip 69 | 70 | ```console 71 | git clone https://github.com/karlot/sshclick 72 | cd sshclick 73 | pip install . 74 | ``` 75 | 76 | 3. Use it as you like, `sshc` command should be available to access SSHClick application, see below chapter for basic [usage](https://github.com/karlot/sshclick#example-usage-and-features) 77 | 78 | 4. Install shell autocompletion (*TAB-TAB auto-completes on commands, options, groups and hosts*) 79 | - **Bash** - Add this line to end of your `~/.profile` file: 80 | 81 | ```sh 82 | eval "$(_SSHC_COMPLETE=bash_source sshc)" 83 | ``` 84 | 85 | - **Zsh** - Add this line to end of your `~/.zshrc` file: 86 | 87 | ```sh 88 | eval "$(_SSHC_COMPLETE=zsh_source sshc)" 89 | ``` 90 | 91 | ### Upgrade procedure 92 | 93 | - Upgrade from new PyPI release: 94 | 95 | ```console 96 | pip install --upgrade sshclick 97 | ``` 98 | 99 | - Upgrade from source: 100 | Assuming installation is already done, and previous version is cloned in some local folder 101 | 102 | ```console 103 | cd sshclick 104 | git pull 105 | pip install --upgrade . 106 | ``` 107 | 108 | ### Uninstall procedure 109 | 110 | Simply run: 111 | 112 | ```console 113 | pip uninstall sshclick 114 | ``` 115 | 116 | In case you have installed from cloned source code, you can delete locally cloned repo. 117 | 118 | ```console 119 | rm -r sshclick 120 | ``` 121 | 122 | --- 123 | 124 | ## SSH Config structure, and important note about comments 125 | 126 | SSHClick when editing and writing to SSH config file must use specific style, and is internally using comments to "organize" configuration itself. This means comments outside of what sshclick is handling are unsupported and will be lost when SSHClick modifies a file.) 127 | 128 | ### Comment blocks and metadata in SSH Config 129 | 130 | SSHClick uses comments to add extra information which it can use to add concept of grouping and extra information to hosts. Special metadata lines start with `#@:` or `# :` followed by some of meta-tags like `group`, `desc`, `info`. This are all considered group meta-tags, as they apply on the group level. Note that line separations above and below group header are added only for visual aid, they are ignored at parsing, but are included when modifying/generating SSH config file. 131 | 132 | This metadata headers can be added manually also in SSH config, or sshclick can add them and move hosts under specific group, using `sshc` cli tool 133 | 134 | Normally start of the "GROUP HEADER" inside SSH Config would look like below. 135 | 136 | - `#@group:` or `# group:` is KEY metadata tag, that during "parsing" defines that all hosts configured below this "tag" belong to this group 137 | - `#@desc:` or `# desc:` is optional tag that adds "description" to defined group, and will display in usual group display commands 138 | - `#@info:` or `# info:` is optional tag that can appear multiple times, adding extra information lines tied to the group. 139 | 140 | Additionally each "host" definition can have optional meta info: 141 | 142 | - `#@host:` or `# host:` is optional tag that can appear multiple times, that can hold some information about the host, this meta info when defined applies to next "host" definition that will appear. If this key is added after "host" config keyword, it will be applied to next host, for that reason, keep this host meta info above the actual host definition. 143 | 144 | Following is sample how group header is rendered by SSHClick: 145 | 146 | ```conf 147 | #------------------------------------------------------------------------------- 148 | #@group: [MANDATORY] <-- This line starts new group 149 | #@desc: [OPTIONAL, SINGLE] 150 | #@info: [OPTIONAL,MULTIPLE] 151 | #------------------------------------------------------------------------------- 152 | Host ... <-- this hosts definitions are part of the defined group 153 | param1 value1 154 | param2 value2 155 | 156 | #@host: [OPTIONAL,MULTIPLE] <-- Adds info to following host 157 | Host ... 158 | 159 | 160 | ``` 161 | 162 | If there are no groups defined, then all hosts are considered to be part of "default" group. SSHClick can be used to move hosts between groups and handle keeping SSH config "tidy" and with consistent format. 163 | 164 | ## Example usage and features 165 | 166 | SSHClick is deploying `sshc` cli tool that allows interacting with your SSH Config file and perform various organization,listing, displaying and modification of SSH Group/Host configuration parameters. 167 | `sshc` comes with pre-built lots of help options so each level of commands provide `--help` options to provide you info what commands and options are available at which command level. 168 | 169 | For example to check version, type: `sshc --version` 170 | *Sample output:* 171 | 172 | ```console 173 | $ sshc --version 174 | SSHClick (sshc) - Version: 0.6.0 175 | ``` 176 | 177 | If you run `sshc` command alone, or adding `-h` or `--help` option, it will show help what else must be added to the command... 178 | *Example:* 179 | 180 | ```console 181 | $ sshc --help 182 | Usage: sshc [OPTIONS] COMMAND [ARGS]... 183 | 184 | SSHClick - SSH Config manager. version 0.6.0 185 | 186 | NOTE: As this will change your SSH config files, make backups before using 187 | this software, as you might accidentally lose some configuration. 188 | 189 | Options: 190 | --sshconfig TEXT Config file (default: ~/.ssh/config) 191 | --stdout Send changed SSH config to STDOUT instead to original 192 | file, can be enabled with setting ENV variable (export 193 | SSHC_STDOUT=1) 194 | --version Show the version and exit. 195 | -h, --help Show this message and exit. 196 | 197 | Commands: 198 | config Modify SSHClick configuration trough SSH Config 199 | group Command group for managing groups 200 | groups Lists all groups 201 | host Command group for managing hosts 202 | hosts List configured hosts 203 | tui TUI Interface (experimental) 204 | ``` 205 | 206 | ### `group` commands and options 207 | 208 | To manage "groups" type `sshc group --help` to see options. 209 | *Example:* 210 | 211 | ```console 212 | $ sshc group --help 213 | Usage: sshc group [OPTIONS] COMMAND [ARGS]... 214 | 215 | Command group for managing groups 216 | 217 | Options: 218 | -h, --help Show this message and exit. 219 | 220 | Commands: 221 | create Create new group 222 | delete Delete group 223 | list Lists all groups 224 | rename Rename existing group 225 | set Change group parameters 226 | show Shows group details 227 | ``` 228 | 229 | ### `host` commands and options 230 | 231 | To manage "groups" type `sshc host --help` to see options. 232 | *Example:* 233 | 234 | ```console 235 | $ sshc host --help 236 | Usage: sshc host [OPTIONS] COMMAND [ARGS]... 237 | 238 | Command group for managing hosts 239 | 240 | Options: 241 | -h, --help Show this message and exit. 242 | 243 | Commands: 244 | create Create new host 245 | delete Delete host(s) 246 | install Install SSH key to hosts (experimental) 247 | list List configured hosts 248 | rename Rename existing host 249 | set Set/Change host configuration 250 | show Show current host configuration 251 | test Test SSH host connection (experimental) 252 | ``` 253 | 254 | ### `config` commands and SSHClick configuration options 255 | 256 | SSHClick does not to have its own configuration files, so most of configuration that it tries to understand, come from commands arguments/options, environment variables, and SSH Config file itself. 257 | 258 | Sometimes when you want to persist some config options, not to repeat it via command, you can use ENV variables, that can be set trough user shell profile. 259 | 260 | Now there is also option to store such config in SSH Config file itself (as metadata comment), so it can be portable and backed up together with SSH Config file. 261 | 262 | Command `config` takes `set` or `del` commands that add or remove specific configuration. 263 | 264 | #### Example 265 | 266 | ```console 267 | $ sshc config --help 268 | Usage: sshc config [OPTIONS] COMMAND [ARGS]... 269 | 270 | Modify SSHClick configuration trough SSH Config 271 | 272 | Options: 273 | -h, --help Show this message and exit. 274 | 275 | Commands: 276 | del Delete config option 277 | set Set config option 278 | ``` 279 | 280 | #### Example: Set host output style to 'card' 281 | 282 | ```console 283 | $ sshc config set --help 284 | Usage: sshc config set [OPTIONS] 285 | 286 | Set config option 287 | 288 | Options: 289 | --host-style TEXT Set how to display hosts in 'show' command. 290 | Available:(panels,card,simple,table,table2,json) 291 | (default: panels) 292 | -h, --help Show this message and exit. 293 | 294 | $ sshc config set --host-style card 295 | ``` 296 | 297 | This will now store config in "currently used" SSH config file as following: 298 | 299 | ```conf 300 | #<<<<< SSH Config file managed by sshclick >>>>> 301 | #@config: host-style=card 302 | ``` 303 | 304 | To delete this config, either remove the line from file manually, or use `sshc` command: 305 | 306 | ```console 307 | sshc config del --host-style 308 | ``` 309 | 310 | ### Output styling and user ENV variables 311 | 312 | `sshc host show` can display host output is several formats, you can specify it with `sshc host show --style