# SSH Compose Pro Streamline repetitive ssh config files with trait-style property inheritance! ssh_compose_pro is meant for users with very large and repetitive ssh configs. This includes templating, an inheretence-style way of copying fields, and for loops to reduce repetitive lines. See the `example/` directory for an idea of capabilities, but here's a snippet: ```yaml __preamble: ssh_props: Port: 22 IdentitiesOnly: yes ForwardX11: no __uni_template: template: __preamble ssh_props: IdentityFile: ~/.ssh/computer_labs_key User: emiliko undergrad: template: __uni_template ssh_props: Hostname: ug22.cs.ualberta.ca ohaton: template: __uni_template ssh_props: Hostname: ohaton.cs.ualberta.ca coronation: template: __uni_template ssh_props: Hostname: coronation.cs.ualberta.ca ``` # Quick Start Convert your `~/.ssh/config` into an `~/.ssh/config.yaml` by following the rules below. Eventually we hope to have a conversion script, but not yet... Run `src/main.py` on your `~/.ssh/config.yaml` to convert it! ## Systemd Integration You can have systemd automatically run ssh_compose_pro when your yaml file changes! Move the files under `systemd/` to `~/.config/systemd/user` and update the paths to match your system. Next: ```bash systemctl --user enable --now ssh-compose-pro.path journalctl --user -fu ssh-compose-pro.service ``` Make a change to your yaml file, and you should see the output appear in the terminal running `journalctl`. You can ^C the `journalctl` command, it'll still update on change. # Rules ## SSH Properties Standard SSH config properties go under the `ssh_props` heading for every host. For example: ```sshconfig Host github.com Hostname github.com IdentityFile ~/.ssh/github_main LocalForward 3306 localhost:3306 LocalForward 3302 localhost:3302 LocalForward 3000 localhost:3000 ``` Becomes: ```yaml github.com: ssh_props: Hostname: github.com IdentityFile: ~/.ssh/github_main LocalForward: - 3306 localhost:3306 - 3302 localhost:3302 - 3000 localhost:3000 ``` Note that yaml does not support duplicate keys, so keys can take a list of properties instead to mimic repeated keys, as seen above. ## Templates Templates are "default" properties inherited from another host. Templates must be declared above the host that uses it. You can make a template-only host by declaring it with `__` at the start of the name. You can also use another host as a template. ```yaml __preamble: ssh_props: Port: 22 IdentitiesOnly: yes ForwardX11: no ############################################################################# # Uni Computers ############################################################################# __uni_template: template: __preamble ssh_props: IdentityFile: ~/.ssh/id_ed25519 User: emiliko ohaton: template: __uni_template ssh_props: Hostname: ohaton.cs.ualberta.ca coronation: # Using __uni_template here would make more sense, but ohaton works too template: ohaton ssh_props: Hostname: coronation.cs.ualberta.ca ``` Will generate: ```sshconfig Host ohaton: ForwardX11 no Hostname ohaton.cs.ualberta.ca IdentitiesOnly yes IdentityFile ~/.ssh/id_ed25519 Port 22 User emiliko Host coronation: ForwardX11 no Hostname coronation.cs.ualberta.ca IdentitiesOnly yes IdentityFile ~/.ssh/id_ed25519 Port: 22 User emiliko ``` As a note, properties inherited from templates will be overwritten entirely, even if they're multi-valued. For example: ```yaml __uni: ssh_props: LocalForward: - 3306 localhost:3306 - 3302 localhost:3302 - 3000 localhost:3000 ohaton: template: __uni ssh_props: LocalForward: - 9000 localhost:9000 ``` Will overwrite all the `LocalForward` properties provided by the `__uni` template, generating: ```sshconfig Host ohaton LocalForward 9000 localhost:9000 ``` ## For loops For loops allow simple substitution of a single variable over a range or set of values. Ranges must be numerical, but sets can be any arbitrary string. Multiple different for loops can be declared under the `for` section. ```yaml orca: ssh_props: Hostname: 10.42.43.1 User: emiliko for: - variable: port range: [9026, 9042, 1] property: LocalForward template: ${port} localhost:${port} - variable: env iter: ["FOO=bar", "BAR=foo"] property: SendEnv template: ${env} ``` Expands to: ```sshconfig Host orca Hostname 10.42.43.1 LocalForward 9026 localhost:9026 LocalForward 9027 localhost:9027 LocalForward 9028 localhost:9028 LocalForward 9029 localhost:9029 LocalForward 9030 localhost:9030 LocalForward 9031 localhost:9031 LocalForward 9032 localhost:9032 LocalForward 9033 localhost:9033 LocalForward 9034 localhost:9034 LocalForward 9035 localhost:9035 LocalForward 9036 localhost:9036 LocalForward 9037 localhost:9037 LocalForward 9038 localhost:9038 LocalForward 9039 localhost:9039 LocalForward 9040 localhost:9040 LocalForward 9041 localhost:9041 SendEnv FOO=bar SendEnv BAR=foo User emiliko ``` For loops can be part of templates