Mise à jour pour Stretch.
[ansible.git] / scripts / ansible-debian-versions
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 """Outil d'extraction d'informations système sur les serveurs Debian.
4
5 Copyright ©2016  Agence universitaire de la Francophonie -- www.auf.org
6 Licence : GPL version 3
7 Auteur : Progfou <jean-christophe.andre@auf.org>
8 """
9 import sys
10 import ansible.runner
11 from os import getenv
12 from time import strftime, gmtime
13 import re
14
15 if len(sys.argv) != 2:
16     print (u"Usage : %s <nom-d-ensemble-de-machines>" % sys.argv[0]).encode('utf-8')
17     sys.exit(1)
18 subset = sys.argv[1]
19
20 # constantes
21
22 URL = "http://git.auf.org/?p=ansible.git;a=blob;f=scripts/ansible-debian-versions"
23
24 VERSION = "16.03.21"
25
26 RELEASE_NAME = {
27   u'Debian': {
28     u'9': 'stretch', u'8': 'jessie',
29     u'7': 'wheezy',  u'6': 'squeeze',
30     u'5': 'lenny',   u'4': 'etch',
31   },
32 }
33
34 RELEASE_COLOR = {
35   u'Debian': {
36     u"9": "00ff00", u"8": "00ae00",
37     u"7": "e6ff00", u"6": "ff950e",
38     u"5": "ff420e",
39   },
40   u'FreeBSD': {
41     u"10": "00ae00", u"9": "e6ff00", u"8": "ff950e", u"7": "ff420e",
42   },
43 }
44 DEFAULT_RELEASE_COLOR = "ff0000"
45 UNKNOWN_RELEASE_COLOR = "f0f0f0"
46
47 VIRTUAL_INDEX = {
48   u"inconnue": 0,
49   u"physique": 5,
50   u"openvz / hôte": 10,
51   u"openvz / invité": 15,
52   u"kvm / hôte": 20,
53   u"QEMU / invité": 23,
54   u"kvm / invité": 25,
55 }
56
57 VIRTUAL_COLOR = {
58   u"kvm / hôte": "e0ffe0",
59   u"kvm / invité": "e0ffe0",
60   u"openvz / invité": "ffe0a0", #"e6ff00",
61   u"openvz / hôte": "ffc0c0", #"ff950e",
62   u"physique": "ffffa0", #"ff420e",
63 }
64 UNKNOWN_VIRTUAL_COLOR = "f0f0f0"
65
66 # collecte des données
67
68 pm = ansible.runner.Runner(module_name='setup', timeout=5, subset=subset)
69 out = pm.run()
70
71 # sauvegarde temporaire pour débogage
72
73 import json
74 file('/tmp/out-%s.json' % getenv('USER'), 'w').write(json.dumps(out, sort_keys=True, indent=4, separators=(',', ': ')))
75
76 # traitement des données
77
78 server_list = []
79
80 for server,data in out['contacted'].items():
81     data['name'] = server
82     facts = data['ansible_facts']
83     # famille
84     if 'ansible_os_family' in facts:
85         data['os_family'] = facts['ansible_os_family']
86     else:
87         data['os_family'] = u'inconnue'
88     # distribution
89     if 'ansible_distribution' in facts:
90         major = re.findall(r'[0-9]+', facts['ansible_distribution_version'])
91         if len(major) > 0:
92             data['major_release'] = major[0]
93         else:
94             data['major_release'] = u'0'
95         version = re.findall(r'[0-9\.]+', facts['ansible_distribution_version'])
96         if len(version) > 0:
97             data['version'] = version[0]
98         else:
99             data['version'] = u'0'
100         data['description'] = u'%s %s' % (facts['ansible_distribution'],
101                                                             data['version'])
102         release = facts.get('ansible_distribution_release', u'NA')
103         if release == u'NA' and data['os_family'] in RELEASE_NAME:
104             os_release_name = RELEASE_NAME[data['os_family']]
105             if data['major_release'] in os_release_name:
106                 release = os_release_name[data['major_release']]
107         if release != u'NA':
108             data['description'] += u' (%s)' % release
109     else:
110         data['major_release'] = u'0'
111         data['description'] = u'inconnue (information non disponible)'
112     # virtualisation
113     if 'ansible_virtualization_type' in facts and \
114        'ansible_virtualization_role' in facts:
115         if facts['ansible_virtualization_role'] == u'guest':
116             virtual_info = u'%s / invité' % facts['ansible_virtualization_type']
117         elif facts['ansible_virtualization_role'] == u'host':
118             virtual_info = u'%s / hôte' % facts['ansible_virtualization_type']
119         elif facts['ansible_virtualization_role'] == u'NA':
120             virtual_info = u'physique'
121         else:
122             virtual_info = u'inconnue (%s / %s)' % (
123                 facts['ansible_virtualization_type'],
124                 facts['ansible_virtualization_role'] )
125         data['virtual_info'] = virtual_info
126     elif 'ansible_processor' in facts and facts['ansible_processor'][0].startswith('QEMU'):
127         data['virtual_info'] = u'QEMU / invité'
128     else:
129         data['virtual_info'] = u'inconnue'
130     # architecture
131     if 'ansible_machine' in facts and 'ansible_userspace_bits' in facts:
132         data['architecture'] = u'%s bits / %s' % (
133             facts['ansible_userspace_bits'], facts['ansible_machine'] )
134     else:
135         data['architecture'] = u'inconnue'
136     # ajout à la liste
137     server_list.append({
138         'name': data['name'],
139         'os_family': data['os_family'],
140         'description': data['description'],
141         'major_release': data['major_release'],
142         'architecture': data['architecture'],
143         'virtual_info': data['virtual_info'],
144     })
145
146 for server,data in out['dark'].items():
147     # ajout à la liste
148     server_list.append({
149         'name': server,
150         'os_family': u'inconnue',
151         'description': u'inconnue (échec de connexion)',
152         'major_release': u'0',
153         'architecture': u'inconnue',
154         'virtual_info': u'inconnue',
155     })
156
157 # tri de la liste des serveurs par version de distribution croissante
158
159 def sort_key(x):
160     os_family = u'0' if x['os_family'] == u'inconnue' else x['os_family']
161     virtual_index = VIRTUAL_INDEX.get(x['virtual_info'], 1)
162     reversed_name = '.'.join(reversed(x['name'].split('.')))
163     return u'%s-%03d-%02d-%s' % ( os_family, int(x['major_release']),
164         virtual_index, reversed_name )
165
166 server_list.sort(key=sort_key)
167
168 # affichage du code wiki MoinMoin correspondant
169
170 print u"||<rowstyle=\"background-color: #cccccc;\">'''Serveur'''||'''Version du système'''||'''Architecture'''||'''Virtualisation'''||".encode('utf-8')
171
172 for server in server_list:
173     # couleur pour la version
174     if server['major_release'] == u'0':
175         server['release_color'] = UNKNOWN_RELEASE_COLOR
176     elif server['os_family'] in RELEASE_COLOR:
177         os_release_color = RELEASE_COLOR[server['os_family']]
178         if server['major_release'] in os_release_color:
179             server['release_color'] = os_release_color[server['major_release']]
180         else:
181             server['release_color'] = DEFAULT_RELEASE_COLOR
182     else:
183         server['release_color'] = DEFAULT_RELEASE_COLOR
184     # couleur pour la virtualisation
185     if server['virtual_info'] in VIRTUAL_COLOR:
186         server['virtual_color'] = VIRTUAL_COLOR[server['virtual_info']]
187     else:
188         server['virtual_color'] = UNKNOWN_VIRTUAL_COLOR
189     if u'invité' not in server['virtual_info']:
190         server['virtual_info'] = u"'''%s'''" % server['virtual_info']
191     # affichage
192     print ( (u"||<)>%(name)s||<#%(release_color)s>%(description)s||" +
193         u"%(architecture)s||<#%(virtual_color)s>%(virtual_info)s||") % \
194         server ).encode('utf-8')
195
196 now = gmtime()
197 print ( (
198     u"||<rowstyle=\"background-color: #cccccc; font-size: 75%%;\"-4> ''" +
199     u"Tableau généré le %s à %s UTC avec [[%s|ansible-debian-versions]] %s" +
200     u"'' ||" ) % (strftime('%Y-%m-%d', now), strftime('%H:%M:%S', now),
201     URL, VERSION) ).encode('utf-8')