Browse Source
Multiple changes:
Multiple changes:
1) Makes mixin for API views. 2) Makes device monitoring notification. And little bit fixesdevel
16 changed files with 332 additions and 60 deletions
-
68agent/monitoring_agent.py
-
7chatbot/telebot.py
-
2devapp/forms.py
-
44devapp/locale/ru/LC_MESSAGES/django.po
-
34devapp/migrations/0006_auto_20180129_1625.py
-
17devapp/models.py
-
6devapp/templates/devapp/add_dev.html
-
2devapp/templates/devapp/dev.html
-
20devapp/templates/devapp/devices.html
-
6devapp/urls.py
-
112devapp/views.py
-
57djing/global_base_views.py
-
6djing/settings.py
-
4djing/views.py
-
1requirements.txt
-
6taskapp/handle.py
@ -0,0 +1,68 @@ |
|||||
|
#!/usr/bin/env python3 |
||||
|
import sys |
||||
|
import re |
||||
|
from hashlib import sha256 |
||||
|
import requests |
||||
|
|
||||
|
API_AUTH_SECRET = 'asihdfaoisydoiayosidyaoisydoiasydaisydasd' |
||||
|
|
||||
|
SERVER_DOMAIN = 'http://localhost:8000' |
||||
|
|
||||
|
|
||||
|
IP_REGEXP = r'^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \ |
||||
|
r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \ |
||||
|
r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.' \ |
||||
|
r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$' |
||||
|
|
||||
|
|
||||
|
def calc_hash(data): |
||||
|
if type(data) is str: |
||||
|
result_data = data.encode('utf-8') |
||||
|
else: |
||||
|
result_data = bytes(data) |
||||
|
return sha256(result_data).hexdigest() |
||||
|
|
||||
|
|
||||
|
def check_sign(get_list, sign): |
||||
|
hashed = '_'.join(get_list) |
||||
|
my_sign = calc_hash(hashed) |
||||
|
return sign == my_sign |
||||
|
|
||||
|
|
||||
|
def validate(regexp, string): |
||||
|
if not bool(re.match(regexp, string)): |
||||
|
raise ValueError |
||||
|
return string |
||||
|
|
||||
|
|
||||
|
def validate_status(text): |
||||
|
if not text in ('UP', 'DOWN', 'UNREACHABLE'): |
||||
|
raise ValueError |
||||
|
return text |
||||
|
|
||||
|
|
||||
|
def send_request(ip, status, sign): |
||||
|
r = requests.get( |
||||
|
"%(domain)s/dev/on_device_down/" % {'domain': SERVER_DOMAIN}, |
||||
|
params={ |
||||
|
'ip': ip, |
||||
|
'status': status, |
||||
|
'sign': sign |
||||
|
}) |
||||
|
if r.status_code == 200: |
||||
|
print(r.json()) |
||||
|
else: |
||||
|
print('Status:', r.status_code, r.text) |
||||
|
|
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
if len(sys.argv) < 3: |
||||
|
print('You forget parameters, example of usage:\n' |
||||
|
'$ python3 ./monitoring_agent.py 192.168.0.100 DOWN|UP|UNREACHABLE') |
||||
|
exit(0) |
||||
|
dev_ip = validate(IP_REGEXP, sys.argv[1]) |
||||
|
status = validate_status(sys.argv[2]) |
||||
|
|
||||
|
sign = calc_hash('_'.join((dev_ip, status, API_AUTH_SECRET))) |
||||
|
|
||||
|
send_request(dev_ip, status, sign) |
||||
@ -0,0 +1,34 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.11 on 2018-01-29 16:25 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('devapp', '0005_device_snmp_item_num'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterModelOptions( |
||||
|
name='device', |
||||
|
options={'ordering': ['comment'], 'permissions': (('can_view_device', 'Can view device'),), 'verbose_name': 'Device', 'verbose_name_plural': 'Devices'}, |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='device', |
||||
|
name='is_noticeable', |
||||
|
field=models.BooleanField(default=False, verbose_name='Send notify when monitoring state changed'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='device', |
||||
|
name='status', |
||||
|
field=models.CharField(choices=[('und', 'Undefined'), ('up', 'Up'), ('unr', 'Unreachable'), ('dwn', 'Down')], default='und', max_length=3, verbose_name='Status'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='device', |
||||
|
name='snmp_item_num', |
||||
|
field=models.PositiveSmallIntegerField(blank=True, default=0, verbose_name='SNMP Number'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,57 @@ |
|||||
|
from hashlib import sha256 |
||||
|
from django.views.generic.base import View |
||||
|
from django.http.response import HttpResponseForbidden |
||||
|
from django.conf import settings |
||||
|
from netaddr import IPNetwork, IPAddress |
||||
|
|
||||
|
|
||||
|
API_AUTH_SECRET = getattr(settings, 'API_AUTH_SECRET') |
||||
|
API_AUTH_SUBNET = getattr(settings, 'API_AUTH_SUBNET') |
||||
|
|
||||
|
|
||||
|
class HashAuthView(View): |
||||
|
|
||||
|
@staticmethod |
||||
|
def calc_hash(data): |
||||
|
if type(data) is str: |
||||
|
result_data = data.encode('utf-8') |
||||
|
else: |
||||
|
result_data = bytes(data) |
||||
|
return sha256(result_data).hexdigest() |
||||
|
|
||||
|
@staticmethod |
||||
|
def check_sign(get_list, sign): |
||||
|
hashed = '_'.join(get_list) |
||||
|
my_sign = HashAuthView.calc_hash(hashed) |
||||
|
return sign == my_sign |
||||
|
|
||||
|
def __init__(self, *args, **kwargs): |
||||
|
if API_AUTH_SECRET is None: |
||||
|
raise ImportError('You must specified API_AUTH_SECRET is settings') |
||||
|
else: |
||||
|
super(HashAuthView, self).__init__(*args, **kwargs) |
||||
|
|
||||
|
def dispatch(self, request, *args, **kwargs): |
||||
|
sign = request.GET.get('sign') |
||||
|
|
||||
|
# Transmittent get list without sign |
||||
|
get_values = request.GET.copy() |
||||
|
del get_values['sign'] |
||||
|
if HashAuthView.check_sign(list(get_values.values()) + [API_AUTH_SECRET], sign): |
||||
|
return super(HashAuthView, self).dispatch(request, *args, **kwargs) |
||||
|
else: |
||||
|
return HttpResponseForbidden('Access Denied') |
||||
|
|
||||
|
|
||||
|
class AllowedSubnetMixin(object): |
||||
|
|
||||
|
def dispatch(self, request, *args, **kwargs): |
||||
|
""" |
||||
|
Check if user ip in allowed subnet. |
||||
|
Return 403 denied otherwise. |
||||
|
""" |
||||
|
ip = IPAddress(request.META.get('REMOTE_ADDR')) |
||||
|
if ip in IPNetwork(API_AUTH_SUBNET): |
||||
|
return super(AllowedSubnetMixin, self).dispatch(request, *args, **kwargs) |
||||
|
else: |
||||
|
return HttpResponseForbidden('Access Denied') |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue