Drawing servers Rack using html/css or any python library

579 views Asked by At

is there any library or template that can help me draw servers rack , based on the server's position in this rack?

example :

  • server_name - start U - End U
  • servers1 - 15 - 17
  • server2 - 20 - 25
  • firewall - 2 - 4
  • NAS - 10 - 15

thank you for your help

1

There are 1 answers

10
furas On BEST ANSWER

I don't know what you need - image PNG/JPG, image SVG, text table, HTML table.

But first it would need to read data and convert to list like this

rows = [
   [1, 'empty']
   [2, 'firewall']
   [3, 'firewall']
   [4, 'firewall']
   [5, 'empty']

   # ... etc... 
]

With this list it could be simpler to calculate positions for text on image, or generate text table, or generate HTML.

You could use it with tabulate to generate text table
which you can display in HTML in <pre></pre> or <code></code>

+------+----------+
|   Nr | Device   |
+======+==========+
|    1 | ?        |
+------+----------+
|    2 | firewall |
+------+----------+
|    3 | firewall |
+------+----------+
|    4 | firewall |
+------+----------+
|    5 | ?        |
+------+----------+
|    6 | ?        |
+------+----------+
|    7 | ?        |
+------+----------+
|    8 | ?        |
+------+----------+
|    9 | ?        |
+------+----------+
|   10 | NAS      |
+------+----------+
|   11 | NAS      |
+------+----------+
|   12 | NAS      |
+------+----------+
|   13 | NAS      |
+------+----------+
|   14 | NAS      |
+------+----------+
|   15 | NAS      |
+------+----------+
|   16 | servers1 |
+------+----------+
|   17 | servers1 |
+------+----------+
|   18 | ?        |
+------+----------+
|   19 | ?        |
+------+----------+
|   20 | server2  |
+------+----------+
|   21 | server2  |
+------+----------+
|   22 | server2  |
+------+----------+
|   23 | server2  |
+------+----------+
|   24 | server2  |
+------+----------+
|   25 | server2  |
+------+----------+

Minimal working code for text table

text = '''servers1 - 15 - 17
server2 - 20 - 25
firewall - 2 - 4
NAS - 10 - 15'''

import io

# --- read to dictionary ---

data = {}
counter = {}

with io.StringIO(text) as fh:
    for line in fh:
        line = line.strip()
        name, start, end = line.split(' - ')
        start = int(start)
        end = int(end)

        # - count -
        counter[name] = end-start+1
        
        for x in range(start, end+1):
            data[x] = name

# - display counter -
#print(counter)
for name, number in counter.items():
    print(f'{name:10}: {number}')
            
# --- convert to list ---

rows = []
last = max(data.keys())

for x in range(1, last+1):
    if x in data:
        name = data[x]
    else:
        name = '?'
    rows.append([x, name])
    
#print(rows)

# --- display table ---

import tabulate

print(tabulate.tabulate(rows, headers=['Nr', 'Device'], tablefmt='grid'))

# - count -
import collections
counter = collections.Counter(data.values())

# - display counter -
#print(counter)
for name, number in counter.items():
    print(f'{name:10}: {number}')

EDIT:

If you put rows in pandas.DataFrame then you can use .to_html() to generate it as <table></table>

But you can use rows also to generate <table> manually

table = "<table>\n"

table += "  <tr>\n    <th>Nr</th>\n    <th>Device</th>\n  </tr>\n"

for number, device in rows:
    table += f"  <tr>\n    <td>{number}</td>\n    <td>{device}</td>\n  </th>\n"

table += "</table>\n"

print(table)

Result:

<table>
  <tr>
    <th>Nr</th>
    <th>Device</th>
  </tr>
  <tr>
    <td>1</td>
    <td>?</td>
  </th>
  <tr>
    <td>2</td>
    <td>firewall</td>
  </th>
  <tr>
    <td>3</td>
    <td>firewall</td>
  </th>
  <tr>
    <td>4</td>
    <td>firewall</td>
  </th>
  <tr>
    <td>5</td>
    <td>?</td>
  </th>
  <tr>
    <td>6</td>
    <td>?</td>
  </th>
  <tr>
    <td>7</td>
    <td>?</td>
  </th>
  <tr>
    <td>8</td>
    <td>?</td>
  </th>
  <tr>
    <td>9</td>
    <td>?</td>
  </th>
  <tr>
    <td>10</td>
    <td>NAS</td>
  </th>
  <tr>
    <td>11</td>
    <td>NAS</td>
  </th>
  <tr>
    <td>12</td>
    <td>NAS</td>
  </th>
  <tr>
    <td>13</td>
    <td>NAS</td>
  </th>
  <tr>
    <td>14</td>
    <td>NAS</td>
  </th>
  <tr>
    <td>15</td>
    <td>NAS</td>
  </th>
  <tr>
    <td>16</td>
    <td>servers1</td>
  </th>
  <tr>
    <td>17</td>
    <td>servers1</td>
  </th>
  <tr>
    <td>18</td>
    <td>?</td>
  </th>
  <tr>
    <td>19</td>
    <td>?</td>
  </th>
  <tr>
    <td>20</td>
    <td>server2</td>
  </th>
  <tr>
    <td>21</td>
    <td>server2</td>
  </th>
  <tr>
    <td>22</td>
    <td>server2</td>
  </th>
  <tr>
    <td>23</td>
    <td>server2</td>
  </th>
  <tr>
    <td>24</td>
    <td>server2</td>
  </th>
  <tr>
    <td>25</td>
    <td>server2</td>
  </th>
</table>

EDIT:

If you use flask then you can send rows to template

return render_template('template.html', rows=rows)

and run loop directly in template

<table>
  <tr>
     <th>Nr</th>
     <th>Device</th>
  </tr>

{% for number, device in rows %}
  <tr>
     <td>{{ number }}</td>
     <td>{{ device }}</td>
  </tr>
{% endfor %}  

</table>