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
|
return expand
|
||||||
|
|
||||||
|
|
||||||
def get_ssh_props(data, hosts):
|
def get_ssh_props(data):
|
||||||
props = list()
|
props = list()
|
||||||
|
|
||||||
if data.get('template'):
|
|
||||||
props = list(hosts[data.get('template')])
|
|
||||||
|
|
||||||
for k, v in data["ssh_props"].items():
|
for k, v in data["ssh_props"].items():
|
||||||
if isinstance(v, list):
|
if isinstance(v, list):
|
||||||
for x in v:
|
for x in v:
|
||||||
|
@ -82,16 +79,6 @@ def get_ssh_props(data, hosts):
|
||||||
return props
|
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):
|
def stringify_booleans(props):
|
||||||
pattern = re.compile(r"(True|False)$")
|
pattern = re.compile(r"(True|False)$")
|
||||||
|
|
||||||
|
@ -114,7 +101,7 @@ def parse_yaml(data):
|
||||||
|
|
||||||
for host, props in data.items():
|
for host, props in data.items():
|
||||||
parsed = list()
|
parsed = list()
|
||||||
parsed.extend(get_ssh_props(props, expanded))
|
parsed.extend(get_ssh_props(props))
|
||||||
parsed.extend(expand_for_loop(props))
|
parsed.extend(expand_for_loop(props))
|
||||||
|
|
||||||
parsed = stringify_booleans(parsed)
|
parsed = stringify_booleans(parsed)
|
||||||
|
@ -122,7 +109,6 @@ def parse_yaml(data):
|
||||||
|
|
||||||
expanded[host] = sorted(parsed)
|
expanded[host] = sorted(parsed)
|
||||||
|
|
||||||
expanded = remove_templates(expanded, data)
|
|
||||||
return expanded
|
return expanded
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue