This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
logtracker/logtracker/journal/views.py

143 lines
5.0 KiB
Python

import datetime
from functools import wraps
from django.contrib.auth.mixins import LoginRequiredMixin
from django.conf import settings
from django.core import serializers
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic.base import View, TemplateView
from django.views.generic.list import ListView
from django.views.generic.edit import FormMixin
from logtracker.journal.models import Entry
from logtracker.journal.journalstream import get_journal_entries
from logtracker.journal.forms import EntriesForm
class APIEntriesList(LoginRequiredMixin, View):
def get_queryset(self):
tail = self.request.GET.get('tail')
if tail == "on":
lines = 20
else:
lines = None
since = self.request.GET.get('since')
host = self.request.GET.getlist('host')
tenant = self.request.GET.getlist('tenant')
_systemd_unit = self.request.GET.getlist('_systemd_unit')
priority = self.request.GET.get('priority')
return Entry.objects.extract(since=since, host=host, lines=lines, tenant=tenant, _systemd_unit=_systemd_unit, priority=priority)
def get(self, request, *args, **kwargs):
queryset = self.get_queryset()
response = serializers.serialize("json", queryset)
return HttpResponse(response, content_type='application/json')
@method_decorator(csrf_exempt, name='dispatch')
class EntriesList(LoginRequiredMixin, FormMixin, ListView):
template_name = 'journal/entry_list.html'
form_class = EntriesForm
paginate_by = 100
def get_queryset(self, **kwargs):
return APIEntriesList.get_queryset(self)
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
data["count"] = len(data['object_list'])
return data
def get_initial(self):
initials = {k: v for k, v in self.request.GET.items()}
for x in ['host', '_systemd_unit']:
initials.update({x: self.request.GET.getlist(x)})
return initials
class HomeView(LoginRequiredMixin, TemplateView):
template_name = 'home.html'
def post(self, request, *args, **kwargs):
url = '%s?%s' % (reverse('mail-api'), '%s=%s' % (request.POST['field'], request.POST['address']))
return HttpResponseRedirect(url)
def get_chunks(gen, n):
chunk = []
ended = False
while True:
for i in range(n):
try:
chunk.append(next(gen))
except StopIteration:
ended = True
yield chunk
chunk = []
if ended:
break
def ssl_client_verify(view):
@wraps(view)
def wrapper(request, *args, **kwargs):
headers = request.META
if headers.get('HTTP_X_SSL') == "1" and (
headers.get('HTTP_X_SSL_CLIENT_VERIFY') == "0"
or headers.get('HTTP_X_SSL_CLIENT_VERIFY') == "SUCCESS"
):
cn = headers.get('HTTP_X_SSL_CLIENT_CN')
dn = headers.get('HTTP_X_SSL_CLIENT_DN')
if cn:
request.host_verified = cn
else:
request.host_verified = dn.split(',')[0].split('=')[1]
if settings.CA_ISSUER:
ca_issuer = headers.get('HTTP_X_SSL_ISSUER')
if ca_issuer != settings.CA_ISSUER:
raise PermissionDenied
else:
if settings.DEBUG:
request.host_verified = 'test_host'
else:
raise PermissionDenied
return view(request, *args, **kwargs)
return wrapper
@ssl_client_verify
@csrf_exempt
def UploadView(request, debug=False):
if request.method == "POST":
count = 0
data = {}
new_entries = []
now = datetime.datetime.now()
journal_stream = request.META.get('wsgi.input')
for chunk in get_chunks(get_journal_entries(journal_stream), 20):
for el in chunk:
data = {k: v for k, v in el}
timestamp = datetime.datetime.fromtimestamp(int(data['__REALTIME_TIMESTAMP']) / 1000000)
if (now - timestamp).days > settings.LOGTRACKER_HISTORY:
continue
hostname = data.get('_HOSTNAME')
if hostname not in request.host_verified:
request.host_verified += "_%s" % hostname
entry = Entry(timestamp=timestamp, host=request.host_verified, data=data)
new_entries.append(entry)
count += 1
if debug and count % 1000 == 0:
print(count, timestamp)
Entry.objects.bulk_create(new_entries)
new_entries = []
if debug:
elapsed = datetime.datetime.now() - now
print('elapsed: %s' % elapsed)
print('count: %s' % count)
return HttpResponse('added %s' % count)
raise PermissionDenied