]>
gitweb.pimeys.fr Git - scripts-20-100.git/blob - ssh/generate_config.py
4c0aa88c5a8912edc0af2381f6d05196468fb69e
2 # -*- coding: utf-8 -*-
4 """Script de génération automatique de fichier ~/.ssh/config
6 TODO : mettre une option pour append le ssh des bornes
11 sys
.path
.append('/usr/scripts/')
13 import lc_ldap
.shortcuts
16 #: Fichier à inclure au début
17 static_before_file
= "./static_before"
19 #: Fichier à inclure à la fin
20 static_after_file
= "./static_after"
22 #: regexp pour exclure certains "serveurs"
23 black_regex
= re
.compile('^((bigbrother|hugebrother|littlebrother|tinybrother|imprimante|vigile(--?\d[a-z])?|bat[abcghijmopkv]-\d|minigiga|multiprise-v6|chu|pika|kvm|pulsar|nols2?).adm.crans.org|ftp.federez.net|ns1.crans.ens-cachan.fr)$')
25 #: Proxy pour contacter le VLAN adm
26 adm_proxy
= u
"sable.crans.org"
28 #: Login pour se connecter sur les serveurs Cr@ns
29 login_crans
= u
"loginCr@ns"
31 #: À afficher avant les serveurs Cr@ns
33 # +-------------------+
34 # | Serveurs du Cr@ns |
35 # +-------------------+
36 # Accessible aux apprentis
37 # sauf zamok et ssh2, accessibles à tous les adhérents
41 #: À afficher avant les serveurs adm
42 crans_adm_header
= u
"""
43 # +-------------------------+
44 # | Serveurs Cr@ns adm-only |
45 # +-------------------------+
46 # Accessibles aux apprentis, mais ne sont que sur le VLAN adm
47 # d'où la ProxyCommand
51 def blacklisted(key
, aliases
):
52 """Répond True si le serveur ne doit pas apparaître dans le fichier de conf."""
54 if black_regex
.match(a
):
58 def cache_servers(servs
):
60 json
.dump(servs
, open("plouf.json", "w"))
64 return json
.load(open("plouf.json"))
66 def get_servers(help=None):
67 """Récupère la liste des serveurs dans la base LDAP."""
69 c
= lc_ldap
.shortcuts
.lc_ldap_readonly(user
=u
"legallic")
72 l
= [m
for m
in l
if isinstance(m
, lc_ldap
.objets
.machineCrans
)]
78 host
= m
["host"][0].value
79 h
= host
.replace(".crans.org", "")
81 print (u
"Doublon : clé %s had %r and wants %r" % (h
, hosts
[h
], [host
] + [a
.value
for a
in m
["hostAlias"]])).encode("utf-8")
83 hosts
[h
] = [host
] + [a
.value
for a
in m
["hostAlias"]]
86 def output(key
, aliases
, use_adm_proxy
=False):
87 """ Renvoie le block de conf pour un host.
88 Traite particulièrment : ssh2, les ilo, la ferme"""
89 # On teste si le serveur est dans la ferme
90 ferme
= any([a
.endswith(u
".ferme.crans.org") for a
in aliases
])
91 shorts
= list(set([a
.replace(".crans.org", "") for a
in aliases
]))
93 shorts
.append(a
.split(".", 1)[0])
97 out
= u
"Host %s\n" % (u
" ".join([key
] + shorts
+ aliases
))
99 out
+= u
" # Un serveur ssh qui n'est qu'un nat vers 138.231.136.1:22\n"
100 out
+= u
" # pour passer à travers les blocages de ports (443 = https)\n"
101 out
+= u
" HostName 138.231.136.2\n"
102 out
+= u
" Port 443\n"
103 out
+= u
" User %s\n" % login_crans
104 out
+= u
" ForwardAgent yes\n"
107 hostname
= u
"%s.crans.org" % (key
)
108 out
+= u
" HostName %s\n" % (hostname
)
109 out
+= u
" User %s\n" % login_crans
110 if not key
in ["apprentis", "batk-0"]:
111 out
+= u
" ForwardAgent yes\n"
113 out
+= u
" ProxyCommand ssh %s -W %%h:%%p\n" % (adm_proxy
)
114 if key
.endswith("-ilo.adm"):
115 out
+= u
" HostKeyAlgorithms ssh-rsa\n"
119 def compute_ssh_config(servers
):
120 """Affiche le ssh_config à partir de la liste de serveurs."""
121 # Un serveur "plouf.adm.crans.org" est adm-only si aucune clé "plouf", "plouf.ferme" n'existe
122 keys
= servers
.keys()
123 adm_only
= {k
: aliases
for k
, aliases
in servers
.items() if all([not k
.replace(".adm", zone
) in keys
124 for zone
in [".ferme", ""]])}
125 # On veut pouvoir utiliser babar et pas seulement babar.adm
126 for k
in adm_only
.keys():
127 newk
= k
.replace(".adm", "")
128 if not newk
in adm_only
[k
]:
129 adm_only
[k
] = [k
.replace(".adm", "")] + adm_only
[k
]
130 for a
in adm_only
.keys():
133 keys
= servers
.keys()
136 s
+= output(h
, servers
[h
])
137 s
+= crans_adm_header
138 keys
= adm_only
.keys()
141 s
+= output(h
, adm_only
[h
], use_adm_proxy
=True)
144 if __name__
== '__main__':
146 servers
= load_servers()
148 servers
= get_servers()
149 cache_servers(servers
)
150 servers
= {h
:aliases
for h
, aliases
in servers
.iteritems() if not blacklisted(h
, aliases
)}
151 out
= compute_ssh_config(servers
)
152 before
= open(static_before_file
).read().decode("utf-8")
153 after
= open(static_after_file
).read().decode("utf-8")
154 print (before
+ out
+ after
).encode("utf-8")