-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathssh.py
68 lines (53 loc) · 2.22 KB
/
ssh.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import jinja2
from cmd import add_cmd
import os.path
from parse.host import get_sname_dups
from iptables import get_pub_port
def get_patt(host):
return ('%s' if 'ssh_port' not in host.props
else '[%s]:' + str(host.props['ssh_port']))
def get_base_names(host, patt):
rv = [patt % host.name, patt % host.sname, patt % host.addr]
rv.extend(map(lambda alias: patt % alias, host.aliases))
rv.extend(map(lambda alias: patt % alias, host.saliases))
return rv
def get_all_names(state, host):
frontend = state.find(state.defaults.frontend)
names = get_base_names(host, get_patt(host))
if state.is_gray(host) and not state.belongs_to(host).private:
names.extend(get_base_names(
frontend, '[%s]:' + str(get_pub_port(host))))
if 'tcp_fwd' in host.props and 22 in host.props['tcp_fwd']:
names.extend(get_base_names(frontend, '[%s]'))
return names
def get_key(data, host, keytype):
if 'managed' in host.props:
filename = os.path.join(
data, 'ssh', host.name,
'ssh_host_{}_key.pub'.format(keytype))
if os.path.isfile(filename):
with open(filename) as input:
return input.read().strip().split(' ')[1]
elif host.facts:
return host.facts.get('ssh{}key'.format(keytype))
return None
def get_keyname(keytype):
return {'rsa': 'ssh-rsa', 'dsa': 'ssh-dss'}[keytype]
@add_cmd('ssh_known_hosts', False, 2)
def gen(state, facts_path, data):
state.parse_facts(facts_path)
def matches(host): return 'ssh' in host.services
dups = get_sname_dups(filter(matches, state.hosts))
assert len(dups) == 0, ("cannot generate SSH config with duplicate "
+ "short names for hosts %s" % ", ".join(dups))
lines = []
for host in filter(matches, state.hosts):
names = get_all_names(state, host)
if names and host.facts:
for keytype in ['rsa', 'dsa']:
key = get_key(data, host, keytype)
if key is not None:
lines.extend(["{} {} {}".format(name,
get_keyname(keytype), key)
for name in [host.name] + names])
return '\n'.join(lines)