from diagrams import Cluster, Diagram

from diagrams.azure.database import SQLDatabases
from diagrams.onprem.inmemory import Redis
from diagrams.onprem.network import Internet
from diagrams.onprem.groupware import Nextcloud
from diagrams.onprem.monitoring import Grafana, Prometheus
from diagrams.onprem.storage import Ceph, CephOsd
from diagrams.onprem.network import Haproxy

from diagrams.digitalocean.network import LoadBalancer

import diagrams.generic.storage as storage_1

from diagrams.azure.identity import Groups
from diagrams.custom import Custom

with Diagram(filename="./assets/dia_nc_improved", show=False, direction="TB"):
    out = Internet("Internet")

    with Cluster("Load Balancing"):
        openstack_lb = Custom("", "../assets/openstack.png")
        lb = [Haproxy("SSL proxy 1"), Haproxy("SSL proxy 2")]

    with Cluster("Web servers"):
        openstack_web = Custom("", "../assets/openstack.png")
        nc_frontend = [ Groups("local LDAP slave") - Nextcloud(),
                        Groups("local LDAP slave") - Nextcloud(),
                        Groups("local LDAP slave") - Nextcloud(),
                        Groups("local LDAP slave") - Nextcloud()]        

    with Cluster("Caching"):
        openstack_cach = Custom("", "../assets/openstack.png")
        redis = [Redis("Redis 1"), Redis("Redis 2")]

    with Cluster("LDAP"):
        openstack_ldap = Custom("", "../assets/openstack.png")
        ldap = Groups()

    with Cluster("Control / Monitor"):
        openstack_ctrl = Custom("", "../assets/openstack.png")
        ctrl = [Prometheus(), Grafana()]

    with Cluster("Database cluster"):

        with Cluster("Load Balancer"):
            openstack_dblb = Custom("", "../assets/openstack.png")
            nc_dblb = LoadBalancer()

        with Cluster("Databases"):
            openstack_db = Custom("", "../assets/openstack.png")
            SQLDatabases("Master") >> [SQLDatabases("Slave 1"),
                      SQLDatabases("Slave 2")]

    with Cluster("Ceph Storage Cluster"):
        ceph_cluster = Ceph()
        ceph_object = CephOsd("Object Gateway")

    nc_frontend >> storage_1.Storage("NFS")
    nc_frontend >> ceph_cluster
    openstack_cach << nc_frontend
    openstack_web >> openstack_dblb    
    openstack_lb >> openstack_web
    openstack_web << ldap
    nc_dblb >> openstack_db
    out >> lb
    openstack_web >> openstack_ctrl << openstack_dblb