convheb/create_list_for_annex.py

168 lines
6.3 KiB
Python

from typing import List, IO
from cocluto.inventory import Inventory
from cocluto.SimpaDbUtil import SqlDatabaseReader, SqlFile
from urllib.parse import urlparse
from abc import ABC, abstractmethod
# from sys import stdout
import re
class Table():
columns_data: List[List[str]]
column_labels: List[str]
def __init__(self):
self.columns_data = []
self.columns_labels = []
class TableRenderer(ABC):
@abstractmethod
def render_table(self, table: Table, file: IO):
pass
class TsvTableRenderer(TableRenderer):
def render_table(self, table: Table, file: IO):
assert len(table.column_labels) == len(table.columns_data)
num_cols = len(table.columns_data)
num_rows = len(table.columns_data[0])
file.write('#%s\n' % '\t'.join(table.column_labels))
for irow in range(num_rows):
row = []
for icol in range(num_cols):
row.append(table.columns_data[icol][irow])
file.write('%s\n' % '\t'.join(row))
class MarkdownTableRenderer(TableRenderer):
@staticmethod
def get_md_table_separator_line(columns_width):
sep_line = '|'
for col_width in columns_width:
sep_line += '-' * col_width
sep_line += '|'
return sep_line
def render_table(self, table: Table, file: IO):
assert len(table.column_labels) == len(table.columns_data)
num_cols = len(table.columns_data)
num_rows = len(table.columns_data[0])
cols_width = [0 for col in range(num_cols)]
for icol in range(num_cols):
cols_width[icol] = max(cols_width[icol], len(table.column_labels[icol]))
for irow in range(num_rows):
cols_width[icol] = max(cols_width[icol], len(table.columns_data[icol][irow]))
sep_line = MarkdownTableRenderer.get_md_table_separator_line([col_width + 2 for col_width in cols_width])
line_format = "|" + ''.join([" %%%ds |" % col_width for col_width in cols_width])
file.write('%s\n' % sep_line)
file.write('%s\n' % (line_format % tuple(table.column_labels)))
file.write('%s\n' % sep_line)
for irow in range(num_rows):
row = []
for icol in range(num_cols):
row.append(table.columns_data[icol][irow])
file.write('%s\n' % (line_format % tuple(row)))
file.write('%s\n' % sep_line)
class WikiTableRenderer(TableRenderer):
def render_table(self, table: Table, file: IO):
assert len(table.column_labels) == len(table.columns_data)
num_cols = len(table.columns_data)
num_rows = len(table.columns_data[0])
cols_width = [0 for col in range(num_cols)]
for icol in range(num_cols):
cols_width[icol] = max(cols_width[icol], len(table.column_labels[icol]))
for irow in range(num_rows):
cols_width[icol] = max(cols_width[icol], len(table.columns_data[icol][irow]))
cols_width = [col_width + 1 for col_width in cols_width]
header_line_format = "^" + ''.join([" %%%ds ^" % col_width for col_width in cols_width])
line_format = "|" + ''.join([" %%%ds |" % col_width for col_width in cols_width])
file.write('%s\n' % (header_line_format % tuple(table.column_labels)))
for irow in range(num_rows):
row = []
for icol in range(num_cols):
row.append(table.columns_data[icol][irow])
file.write('%s\n' % (line_format % tuple(row)))
def print_machine_table(machines_fqdn: List[str], inventory: Inventory, out_file: IO, table_renderer: Table):
table = Table()
machines_name = []
machines_spec_id = []
machines_serial_number = []
for machine_fqdn in machines_fqdn:
machine_name = machine_fqdn.split('.')[0]
machine_spec_id = inventory.machine_name_to_machine_spec_id(machine_name)
serial_number = inventory.get_machine_serial_number(machine_name)
machines_name.append(machine_name)
machines_spec_id.append(machine_spec_id)
machines_serial_number.append(serial_number)
table.column_labels = [
'Nom',
'Modèle',
'Numéro de Série'
]
table.columns_data = [machines_name, machines_spec_id, machines_serial_number]
table_renderer.render_table(table, out_file)
# get the list of machines hosted at the dsi
def get_hosted_machines_fqdn(inventory: Inventory) -> List[str]:
machines_fqdn = []
domain_name = 'ipr.univ-rennes1.fr'
dsi_rack_ids = [
'rack_dsi_h7',
'rack_dsi_i7'
]
conditions = [('rack_id == "%s"' % rack_id) for rack_id in dsi_rack_ids]
sql_query = 'select machine_id from rackable_machine_to_location where %s;' % ' or '.join(conditions)
rows = inventory.query(sql_query)
for (machine_id, ) in rows:
match = re.match(r'(?P<cluster_name>[a-z]+)(?P<from>[0-9]+)_(?P<to>[0-9]+)', machine_id)
if match:
# handle containers such as physix72_75
from_index = int(match['from'])
to_index = int(match['to'])
cluster_name = match['cluster_name']
# print(from_index, to_index)
for machine_index in range(from_index, to_index + 1):
machine_id = '%s%d' % (cluster_name, machine_index)
if machine_id == 'physix75':
machine_id = 'alambix75' # hack because the inventory expects all machines of a container such as physix72_75 to belong to the same cluster, and it's not the case here
machines_fqdn.append('%s.%s' % (machine_id, domain_name))
else:
if re.match('^switch', machine_id) is None: # ignore switches, as they belong to the dsi
machines_fqdn.append('%s.%s' % (machine_id, domain_name))
return sorted(machines_fqdn)
def main():
itinv_db_url = "file:///home/graffy/work/simpaweb/itinv.git/itinv.sql"
url_parts = urlparse(itinv_db_url)
sql_source = SqlFile(url_parts.path)
sql_reader = SqlDatabaseReader(sql_source)
inventory = Inventory(sql_reader)
machines_fqdn = get_hosted_machines_fqdn(inventory)
print('ipr machines hosted at the dsi (%d):' % len(machines_fqdn))
table_renderer = TsvTableRenderer()
with open('ipr-machines-at-dsi.csv', 'wt') as tsv_file:
print_machine_table(machines_fqdn, inventory, tsv_file, table_renderer)
if __name__ == '__main__':
main()