tum 2 年之前
父節點
當前提交
b53bbc7af2

二進制
app/Output/excel_out_test_excel_formatter_update.xlsx


+ 10 - 0
app/backend/context_processors.py

@@ -0,0 +1,10 @@
1
+from exfo.lib import Exfo
2
+from pprint import pprint
3
+
4
+exfo = Exfo("administrator", "exf0w0rxC@t4dm!n")
5
+exfo.login()
6
+
7
+def network_report(request):
8
+    apis = exfo.list_api()
9
+    return {'apis': apis.json()}
10
+

+ 8 - 0
app/backend/mongodb.py

@@ -0,0 +1,8 @@
1
+import pymongo
2
+
3
+
4
+# Create your views here.
5
+
6
+client = pymongo.MongoClient('mongodb://mongodb')
7
+#Define DB Name
8
+db = client['network_report']

+ 41 - 12
app/backend/templates/backend/index.html

@@ -1,19 +1,48 @@
1 1
 {% extends "base.html" %}
2
+{% load backend_tags %}
2 3
 {% block content %}
3
-      <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
4
-        <h1 class="h2">Dashboard</h1>
5
-        <div class="btn-toolbar mb-2 mb-md-0">
6
-          <div class="btn-group me-2">
7
-            <button type="button" class="btn btn-sm btn-outline-secondary">Share</button>
8
-            <button type="button" class="btn btn-sm btn-outline-secondary">Export</button>
9
-          </div>
10
-          <button type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle">
11
-            <span data-feather="calendar"></span>
12
-            This week
13
-          </button>
14
-        </div>
4
+<h2>APIs</h2>
5
+      <div class='row row-cols-md-5 row-cols-2'>
6
+      {% for r in output.results %}
7
+        <div class='p-3 border text-center'>{{ r.display_name }}</div>
8
+      {% endfor %}
15 9
       </div>
10
+      <pre>
11
+      {{ output | pprint }}
12
+      </pre>
13
+      <h1>SLA</h1>
16 14
 
15
+      {% for x  in sla.result %}
16
+        {% for k,v in x.items %}
17
+
18
+         <!-- <code>
19
+          {{ v|pprint }}
20
+         </code> -->
21
+         <h2>{{ v.sla_name }}</h2>
22
+          <ul>
23
+          {% for k1,v1 in v.items %}
24
+            {% if 'uri' in k1 %}
25
+            <li><a href="/backend/remote?cmd={{v1|urlencode}}">{{ k1|cut:"_uri"|to_label }}</a></li>
26
+            {% endif %}
27
+          {% endfor %}
28
+          </ul>
29
+        {% endfor %}
30
+      {% endfor %}
31
+
32
+<div class='py-3'>
33
+  <p>
34
+    <a class="btn btn-primary" data-bs-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
35
+      Raw JSON
36
+    </a>
37
+  </p>
38
+  <div class="collapse" id="collapseExample">
39
+    <div class="card card-body">
40
+      <pre>
41
+        {{ sla | pprint }}
42
+      </pre>
43
+    </div>
44
+  </div>
45
+</div>
17 46
       <canvas class="my-4 w-100" id="myChart" width="900" height="380"></canvas>
18 47
 
19 48
       <h2>Section title</h2>

+ 26 - 0
app/backend/templates/backend/remote_render.html

@@ -0,0 +1,26 @@
1
+{% extends "base.html" %}
2
+{% load backend_tags %}
3
+{% block content %}
4
+{% with output=res.json %}
5
+<h2>Services</h2>
6
+<ul>
7
+  {% for si in  output.result.service_instances %}
8
+  <li>{{ si.service_name }} <a href="" class='text-decoration-none badge bg-primary'>status</a></li>
9
+  {% endfor %}
10
+</ul>
11
+{% endwith %}
12
+  <p>
13
+    <a class="btn btn-primary" data-bs-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample">
14
+      Raw JSON
15
+    </a>
16
+  </p>
17
+  <div class="collapse" id="collapseExample">
18
+    <div class="card card-body">
19
+      <pre>
20
+        {{ res.json | pprint }}
21
+      </pre>
22
+    </div>
23
+  </div>
24
+
25
+
26
+{% endblock %}

+ 0 - 0
app/backend/templatetags/__init__.py


+ 9 - 0
app/backend/templatetags/backend_tags.py

@@ -0,0 +1,9 @@
1
+from django import template
2
+
3
+register = template.Library()
4
+
5
+
6
+@register.filter
7
+def to_label(value):
8
+    value = value.replace('_', ' ')
9
+    return value.title()

+ 1 - 0
app/backend/urls.py

@@ -6,4 +6,5 @@ app_name = 'backend'
6 6
 
7 7
 urlpatterns = [
8 8
     path('', views.index, name='index'),
9
+    path('remote/', views.remote, name='remote'),
9 10
 ]

+ 108 - 2
app/backend/views.py

@@ -1,6 +1,112 @@
1 1
 from django.shortcuts import render
2
+from backend.mongodb import db
3
+from exfo.lib import Exfo
4
+from pprint import pprint
2 5
 
3
-# Create your views here.
6
+from ttp import ttp
7
+from django.http import JsonResponse
4 8
 
9
+
10
+exfo = Exfo("administrator", "exf0w0rxC@t4dm!n")
11
+exfo.login()
5 12
 def index(request):
6
-    return render(request, 'backend/index.html')
13
+    collection  = db['mascot']
14
+    mascot_details = collection.find({})
15
+
16
+    rapi = exfo.list_api()
17
+    sla = exfo.call_api("sla")
18
+   
19
+    data_to_parse = """
20
+    interface Loopback0
21
+     description Router-id-loopback
22
+     ip address 192.168.0.113/24
23
+    !
24
+    interface Vlan778
25
+     description CPE_Acces_Vlan
26
+     ip address 2002::fd37/124
27
+     ip vrf CPE1
28
+    !
29
+    """
30
+
31
+    ttp_template = """
32
+    interface {{ interface }}
33
+     ip address {{ ip }}/{{ mask }}
34
+     description {{ description }}
35
+     ip vrf {{ vrf }}
36
+    """
37
+
38
+    template = """
39
+<input load="text">
40
+interface Loopback0
41
+ description Router-id-loopback
42
+ ip address 192.168.0.113/24
43
+!
44
+interface Loopback1
45
+ description Router-id-loopback
46
+ ip address 192.168.0.1/24
47
+!
48
+interface Vlan778
49
+ ip address 2002::fd37/124
50
+ ip vrf CPE1
51
+!
52
+interface Vlan779
53
+ ip address 2002::bbcd/124
54
+ ip vrf CPE2
55
+!
56
+</input>
57
+
58
+<group name="loopbacks_new**.{{ interface }}">
59
+interface {{ interface | contains("Loop") }}
60
+ ip address {{ ip }}/{{ mask }}
61
+ description {{ description }}
62
+ ip vrf {{ vrf }}
63
+</group>
64
+
65
+<group name="vlans*">
66
+interface {{ interface | contains("Vlan") }}
67
+ ip address {{ ip }}/{{ mask }}
68
+ description {{ description }}
69
+ ip vrf {{ vrf }}
70
+</group>
71
+    """
72
+
73
+    parser = ttp(template=template)
74
+    parser.parse()
75
+    # form excel table and save in file
76
+    parser.result(
77
+        format="excel",
78
+        filename="excel_out_test_excel_formatter_update.xlsx",
79
+        returner="file",
80
+        update=True,
81
+        url="./Output/",
82
+        table=[
83
+            {
84
+                "headers": ["interface", "ip", "mask", "vrf", "description"],
85
+                "path": "loopbacks_new",
86
+                "key": "interface",
87
+                "tab_name": "loopbacks_new",
88
+            },
89
+            {"path": "vlans"},
90
+        ],
91
+    )
92
+    # create parser object and parse data using template:
93
+    # parser = ttp(data=data_to_parse, template=ttp_template)
94
+    # parser.parse()
95
+
96
+    # # print result in JSON format
97
+    # results = parser.result(format='xlsx')[0]
98
+    # pprint(results)
99
+    return render(request, 'backend/index.html', {'objs': mascot_details, 'output': rapi.json(),\
100
+            'sla': sla.json()})
101
+
102
+
103
+#Define Collection
104
+def remote(request):
105
+    cmd = request.GET.get('cmd', None)
106
+    # exfo = Exfo("administrator", "exf0w0rxC@t4dm!n")
107
+    # exfo.login()
108
+    r = exfo.call_remote_api(cmd)
109
+    pprint(r.json())
110
+    # return JsonResponse(r.json())
111
+    return render(request, 'backend/remote_render.html', {'res': r})
112
+    

+ 122 - 0
app/exfo/lib.py

@@ -0,0 +1,122 @@
1
+import requests
2
+from pprint import pprint
3
+
4
+class Exfo:
5
+    BASE_URL = "https://159.192.8.11/API/REST"
6
+    BASE_IP = "https://159.192.8.11"
7
+    def __init__(self, user, passwd):
8
+        self.user = user
9
+        self.passwd = passwd
10
+        self.cookies = None
11
+        self.session = requests.Session()
12
+
13
+    def login(self):
14
+        pprint("--- login ---")
15
+        payload = f'uname={self.user}&pword={self.passwd}&format=json&encryptpword=0'
16
+        headers = {
17
+                'Content-Type': 'application/x-www-form-urlencoded',
18
+                'Accept': 'application/x-www-form-urlencoded',
19
+                }
20
+        url = self.BASE_URL + "/Login"
21
+        response = self.session.post(url, headers=headers, data=payload, verify=False)
22
+       
23
+        pprint(self.session.cookies.get_dict())
24
+        pprint(response.text)
25
+        pprint(response.cookies)
26
+        #self.cookies = response.cookies
27
+    def list_api(self):
28
+        pprint("---- list_api ---")
29
+        payload = {}
30
+        headers = {
31
+          'Accept': 'application/json'
32
+        }
33
+        url = self.BASE_URL + "/"
34
+        response = self.session.get(url, headers=headers, data=payload, verify=False)
35
+        pprint(response.json())
36
+        return response
37
+
38
+    def call_api(self, service, payload={}):
39
+        
40
+        headers = {
41
+          'Accept': 'application/json'
42
+        }
43
+        if service == "sla":
44
+            ep = "/SLAs/v1/SLA?size=100"
45
+        url = self.BASE_URL + ep
46
+        response = self.session.get(url, headers=headers, data=payload, verify=False)
47
+        pprint(response.json())
48
+        return response
49
+
50
+    def call_remote_api(self, ep, payload={}):
51
+        
52
+        headers = {
53
+          'Accept': 'application/json'
54
+        }
55
+        url = self.BASE_IP + ep
56
+        pprint(url)
57
+        response = self.session.get(url, headers=headers, data=payload, verify=False)
58
+        pprint(response)
59
+        return response
60
+
61
+    def logout(self):
62
+        pprint("---- logout ---")
63
+        pprint(self.session.cookies.get_dict())
64
+        payload = {}
65
+        headers = {
66
+          'Accept': 'application/json',
67
+        }
68
+        url = self.BASE_URL + "/Logoff?action=logoff"
69
+        
70
+        response = self.session.post(url, headers=headers, data=payload,  verify=False)
71
+        pprint(response)
72
+        pprint(response.text)
73
+
74
+    def video_tier(self):
75
+        pprint("------ vdo tier -------")
76
+        url = self.BASE_URL + "/Verifiers/v2/VideoTier"
77
+
78
+        payload = {}
79
+        headers = {
80
+          'Accept': 'application/json'
81
+        }
82
+
83
+        response = self.session.get(url, headers=headers, data=payload, verify=False)
84
+        pprint(response.json())
85
+
86
+    def test_implement(self):
87
+        pprint('------- test_implement -----')
88
+        url = self.BASE_URL + "/Test/v1"
89
+
90
+        payload = {}
91
+        headers = {
92
+          'Accept': 'application/json'
93
+        }
94
+        pprint(self.session.cookies.get_dict()) 
95
+        response = self.session.get(url, headers=headers, data=payload, verify=False)
96
+
97
+        pprint(response.json)
98
+
99
+    def test_avl_test_types(self):
100
+        pprint('------- test_avl_test_types -----')
101
+        url  = self.BASE_URL + "/Test/v1/TypeByName?list_all=true"
102
+
103
+        payload = {}
104
+        headers = {
105
+          'Accept': 'application/json'
106
+        }
107
+        response = self.session.get(url, headers=headers, data=payload, verify=False)
108
+        print(response.json())
109
+
110
+
111
+
112
+
113
+
114
+if __name__ == '__main__':
115
+    e = Exfo("administrator", "exf0w0rxC@t4dm!n")
116
+    e.login()
117
+    e.list_api()
118
+    e.video_tier()
119
+    e.test_implement()
120
+    e.test_avl_test_types()
121
+    e.logout()
122
+

+ 1 - 0
app/network_report/settings.py

@@ -89,6 +89,7 @@ TEMPLATES = [
89 89
                 'django.template.context_processors.request',
90 90
                 'django.contrib.auth.context_processors.auth',
91 91
                 'django.contrib.messages.context_processors.messages',
92
+			    'backend.context_processors.network_report',
92 93
             ],
93 94
         },
94 95
     },

+ 3 - 25
app/templates/_sidemenu.html

@@ -7,36 +7,14 @@
7 7
           Dashboard
8 8
         </a>
9 9
       </li>
10
+      {% for r in  apis.results %}
10 11
       <li class="nav-item">
11 12
         <a class="nav-link" href="#">
12 13
           <span data-feather="file"></span>
13
-          Orders
14
-        </a>
15
-      </li>
16
-      <li class="nav-item">
17
-        <a class="nav-link" href="#">
18
-          <span data-feather="shopping-cart"></span>
19
-          Products
20
-        </a>
21
-      </li>
22
-      <li class="nav-item">
23
-        <a class="nav-link" href="#">
24
-          <span data-feather="users"></span>
25
-          Customers
26
-        </a>
27
-      </li>
28
-      <li class="nav-item">
29
-        <a class="nav-link" href="#">
30
-          <span data-feather="bar-chart-2"></span>
31
-          Reports
32
-        </a>
33
-      </li>
34
-      <li class="nav-item">
35
-        <a class="nav-link" href="#">
36
-          <span data-feather="layers"></span>
37
-          Integrations
14
+          {{ r.display_name  }}
38 15
         </a>
39 16
       </li>
17
+      {% endfor %}
40 18
     </ul>
41 19
 
42 20
     <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">

+ 2 - 2
app/templates/base.html

@@ -59,7 +59,7 @@
59 59
   <div class="row">
60 60
     {% include "_sidemenu.html" %}
61 61
 
62
-    <main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
62
+    <main class="col-md-9 ms-sm-auto col-lg-10 px-md-4 py-3">
63 63
       {% block content %}
64 64
         <h1>Content is Here</h1>
65 65
       {% endblock %}
@@ -68,7 +68,7 @@
68 68
 </div>
69 69
 
70 70
 
71
-    <script src="{% static "bootstrap/dist/js/bootstrap.bundle.min.js" %}" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
71
+    <script src="{% static "bootstrap/dist/js/bootstrap.bundle.min.js" %}"></script>
72 72
 
73 73
       <script src="https://cdn.jsdelivr.net/npm/feather-icons@4.28.0/dist/feather.min.js" integrity="sha384-uO3SXW5IuS1ZpFPKugNNWqTZRRglnUJK6UAZ/gxOX80nxEkN9NcGZTftn6RzhGWE" crossorigin="anonymous"></script>
74 74
       <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js" integrity="sha384-zNy6FEbO50N+Cg5wap8IKA4M/ZnLJgzc6w2NqACZaK0u0FXfOWRRJOnQtpZun8ha" crossorigin="anonymous"></script>

+ 6 - 0
docker-compose.yml

@@ -16,6 +16,12 @@ services:
16 16
       - POSTGRES_DB=postgres
17 17
       - POSTGRES_USER=postgres
18 18
       - POSTGRES_PASSWORD=postgres
19
+  mongodb:
20
+    image: mongo:6-jammy
21
+    ports:
22
+      - '27017:27017'
23
+    volumes:
24
+      - ./mongodb:/data/db
19 25
   web:
20 26
     build: .
21 27
     image: tum/network-report-image

+ 3 - 0
requirements.txt

@@ -88,3 +88,6 @@ django-qr-code
88 88
 python-barcode
89 89
 gunicorn==21.2.0
90 90
 django-autotranslate
91
+pymongo
92
+dnspython
93
+ttp