Diagram as a Code

Znalazłem ostatnio ciekawą bibliotekę języka Python, która w pewien sposób dopełnia ideę Everything as a Code. Biblioteka ta pozwala na stosunkowo proste rysowanie graficznych diagramów za pomocą kodu języka Python. Możemy zatem śmiało mówić już o modelu Diagram as a Code. Biblioteka, o której mówię, nazywa się diagrams, a jej użycie jest bardzo proste.

Diagram as a Code

Myślę że rysowanie diagramów nowych usług, czy uaktualnianie tych znajdujących się w dokumentacji, nie należy do ulubionych zadań inżyniera czy architekta. Szczególnie w środowiskach, które dynamicznie się zmieniają tego typu praca zabiera bardzo dużo czasu. Nic więc dziwnego, że istnieją narzędzia które mają usprawnić i ułatwić ten proces. Jednym z nich jest biblioteka diagrams, za pomocą której graficzne prezentacje rozwiązania możemy tworzyć jako program w Pythonie. A co za tym idzie możemy rozszerzyć działanie naszej dowolnej aplikacji służącej do zarządzanie infrastrukturą o zbieranie odpowiednich danych i generowanie diagramów.

Biblioteka diagrams wymaga do działania języka Python w wersji co najmniej 3.6 oraz biblioteki graphviz. Obie znajdziemy w repozytorium PyPi i zainstalujemy za pomocą narzędzia pip. Obecna wersja pozwala na rysowanie przede wszystkim usług opartych o rozwiązanie znajdujące się w chmurach publicznych. Z jednej strony można by zarzucić brak dostępności nawet tradycyjnych ikon symbolizujących urządzenia sieciowe. Drugiej strony należy pamiętać, że to usługi w chmurze publicznej opisywane są za pomocą struktur danych, które bardzo łatwo można przetwarzać i wydobywać z nich informacje. 

Podstawy tworzenia diagramów

Aby zainstalować bibliotekę diagrams i wszystkie niezbędne biblioteki zależne najwygodniej posłużyć się managerem pip.

pip3 install diagrams

Następnie w kodzie programu importujemy odpowiednie elementy biblioteki. Rozpoczynamy od obiektu samego diagramu. Następnie importujemy obiekty, które chcemy umieścić na naszym diagramie. Pogrupowane są one w odpowiednie biblioteki niższego rzędu. Można zaimportować wszystkie obiekty z danej biblioteki za pomocą operatora *. Jednakże rekomendowaną metodą jest jedynie dodawanie tych obiektów, które będziemy umieszczać na naszym diagramie.

Zaimportowane elementy wykorzystujemy następnie do utworzenia poszczególnych obiektów, które będziemy umieszczali na naszym diagramie. Połączenia pomiędzy obiektami definiujemy za pomocą operatorów przesunięcia bitowego, przez to kod opisujący diagram staje się bardzo przejrzysty.

from diagrams import Diagram, Cluster, Node, Edge

if __name__ == '__main__':
    from diagrams.generic.network import *
    from diagrams.generic.os import Windows

    with Diagram("My Network", show=True):
        fw1 = Firewall("FW1")
        rtr = Router("BGP Router")
        win1 = Windows("Host-1")
        win2 = Windows("Host-2")
        win3 = Windows("Host-3")
        win4 = Windows("Host-4")
        sw1 = Switch("Switch-1")
        sw2 = Switch("Switch-2")

        rtr >> fw1 >> [sw1, sw2]
        sw1 << win1
        sw2 << win2
        sw2 << win3
        sw2 << win4

W nawiasach kwadratowych jako listę umieściłem obiekty, które mają występować ze sobą “w jednej linii”. Wynikiem działania takiego programu jest następujący, nie ukrywajmy dość koślawy, diagram. Jak widać biblioteka posiada pewne generyczne obiekty reprezentujące urządzenia sieciowe, ale są one dość toporne. O wiele bardziej czytelny diagram wygenerujemy dla usługi w chmurze, o czym za chwilę.

Diagram wygenerowany za pomocą bibliotrki diagrams

Grupowanie obiektów

Aby poprawić czytelność naszego diagramu możemy obiekty łączyć w klastry, czyli grupy logiczne. Utworzone klastry możemy zagnieżdżać. Układając siatkę połączeń między obiektami posługujemy się wtedy zmienną reprezentującą klaster. Połączenia, które utworzymy będą odnosiły się do wszystkich elementów składowych klastra. Oznacza to, że dla klastrów z duża liczbą obiektów uzyskamy dość sporo nachodzących na siebie linii. Nie możemy ze sobą połączyć też dwóch klastrów – próba wykonania takiej operacji zwróci błąd.

Poniżej umieściłem przykładowy kod opisujący usługę w AWS oraz diagram, który powstał w wyniku wykonania programu.

from diagrams import Diagram, Cluster, Node, Edge

if __name__ == '__main__':
    with Diagram("Usługa AWS", show=True, curvestyle="curved", direction="TB"):
        from diagrams.aws.network import ELB
        from diagrams.aws.compute import EC2
        from diagrams.aws.database import Aurora
        from diagrams.aws.compute import Lambda

        elb = ELB("Ingress LB")


        with Cluster("Compute cluster"):
            l1 = Lambda("Lambda Functiom")
            with Cluster("Nodes DC-1"):
                nodes_group1 = [EC2("Node1"), EC2("Node2"), EC2("Node3")]

            with Cluster("Nodes DC-2"):
                nodes_group2 = [EC2("Node1"), EC2("Node2"), EC2("Node3")]

        with Cluster("Databases"):
            db1 = Aurora("DB")

        elb >> nodes_group1 >> l1
        elb >> nodes_group2 >> l1
        nodes_group1 >> db1
        nodes_group2 >> db1
Diagram usługi w AWS narysowany z wykorzystaniem biblioteki diagrams

Podsumowanie

Biblioteka diagrams to dość młody, ale obiecujący projekt. Pierwszy kod został na repozytorium projektu na GitHub wgrany 2 lutego 2020 roku. Podoba mi się sama koncepcja Diagram as a Code, choć oczywiście dynamiczne generowanie schematów to nic nowego. Lata temu do dokumentowania kodu aplikacji w C czy Javie korzystałem z oprogramowanie doxygen. Pozwalał on między innymi na wygenerowanie grafu zależności pomiędzy funkcjami czy obiektami. Mam nadzieję, że projekt diagrams będzie się dalej intensywnie rozwijał i że zobaczymy wkrótce wsparcie dla obiektów związanych z tradycyjnymi czy zwirtualizowanymi sieciami.


Subscribe
Powiadom o
guest

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.

0 komentarzy
Inline Feedbacks
View all comments

ZdradziĆ Ci sekretY udanego projektu automatyzacji?

(link otwiera się w nowym oknie)