Compare commits
No commits in common. "fab1f94faa89dbde8f9b57112241a6b6626aa35a" and "866daa51bae0d55b15f5d7655463844319494cde" have entirely different histories.
fab1f94faa
...
866daa51ba
204
README.md
204
README.md
|
@ -1,204 +0,0 @@
|
|||
# SSH config+
|
||||
|
||||
Streamline repetitive ssh config files with trait-style property inheritance!
|
||||
|
||||
ssh_config+ 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
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
The `src/ssh_config_to_yaml.py` script will assist in quickly migrating your
|
||||
existing config.
|
||||
|
||||
#### 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 outside an example
|
||||
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:
|
||||
|
||||
```
|
||||
__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:
|
||||
from: 9026
|
||||
to: 9042
|
||||
template: LocalForward ${port} localhost:${port}
|
||||
- variable: env
|
||||
range: ["FOO=bar", "BAR=foo"]
|
||||
template: SendEnv ${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
|
18
src/main.py
18
src/main.py
|
@ -66,12 +66,9 @@ def expand_for_loop(props):
|
|||
return expand
|
||||
|
||||
|
||||
def get_ssh_props(data, hosts):
|
||||
def get_ssh_props(data):
|
||||
props = list()
|
||||
|
||||
if data.get('template'):
|
||||
props = list(hosts[data.get('template')])
|
||||
|
||||
for k, v in data["ssh_props"].items():
|
||||
if isinstance(v, list):
|
||||
for x in v:
|
||||
|
@ -82,16 +79,6 @@ def get_ssh_props(data, hosts):
|
|||
return props
|
||||
|
||||
|
||||
def remove_templates(expanded, data):
|
||||
hosts = dict(expanded)
|
||||
|
||||
for host, props in data.items():
|
||||
if host.startswith('__'):
|
||||
del hosts[host]
|
||||
|
||||
return hosts
|
||||
|
||||
|
||||
def stringify_booleans(props):
|
||||
pattern = re.compile(r"(True|False)$")
|
||||
|
||||
|
@ -114,7 +101,7 @@ def parse_yaml(data):
|
|||
|
||||
for host, props in data.items():
|
||||
parsed = list()
|
||||
parsed.extend(get_ssh_props(props, expanded))
|
||||
parsed.extend(get_ssh_props(props))
|
||||
parsed.extend(expand_for_loop(props))
|
||||
|
||||
parsed = stringify_booleans(parsed)
|
||||
|
@ -122,7 +109,6 @@ def parse_yaml(data):
|
|||
|
||||
expanded[host] = sorted(parsed)
|
||||
|
||||
expanded = remove_templates(expanded, data)
|
||||
return expanded
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue