Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Lagerregal/settings/template_production.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@

DATA_PROVIDERS = {
'opsi': 'devicedata.providers.opsi.OpsiProvider',
'puppet': 'devicedata.providers.puppet.PuppetProvide',
'puppet': 'devicedata.providers.puppet.PuppetProvider',
'baramundi': 'devicedata.providers.baramundi.BaramundiProvider',
}

PUPPETDB_SETTINGS = {
Expand All @@ -124,6 +125,13 @@
"port": "4447",
}

BARAMUNDI_SETTINGS = {
"host": "https://baramundi.mpib-berlin.mpg.de",
"port": "443",
"ignore_ssl": True,
"authorization": ""
}

HOST_BASE_DOMAIN = "mpib-berlin.mpg.de"

# sample logger
Expand Down
5 changes: 4 additions & 1 deletion Lagerregal/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
from django.contrib.auth.decorators import login_required
from django.urls import include
from django.urls import path
from django.urls import re_path
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.generic import RedirectView
from django.views.i18n import JavaScriptCatalog
from django.views.static import serve

from favicon import conf
from rest_framework.urlpatterns import format_suffix_patterns

from api import views as api_views
Expand Down Expand Up @@ -163,7 +166,7 @@

path('oauth2/', include('oauth2_provider.urls', namespace='oauth2_provider')),

path('', include('favicon.urls')),
re_path(r'^favicon\.ico$', RedirectView.as_view(url=conf.FAVICON_PATH, permanent=True), name='favicon'),

path('devices_ajax/add_widget/', login_required(main_ajax.WidgetAdd.as_view()), name="widget_add"),
path('devices_ajax/remove_widget/', login_required(main_ajax.WidgetRemove.as_view()), name="widget_remove"),
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Features
+ Generates and prints Dymo labels from templates for inventory stickers
+ Manage static IP addresses for legacy network environments
+ Semi-Automatic e-mail delivery (on lending, trashing etc)
+ Optional query and listing for puppet facts or opsi details of a device
+ Optional query and listing of device data from puppet, opsi or baramundi
+ Permission system for users and public device lists
+ Themable with bootswatch

Expand Down
2 changes: 1 addition & 1 deletion api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.contrib.auth.models import Group
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

import rest_framework.reverse
from rest_framework import generics
Expand Down
9 changes: 6 additions & 3 deletions devicedata/ajax.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.shortcuts import get_object_or_404
from django.shortcuts import render
from django.utils.timesince import timesince
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.views.generic.base import View

from devicedata.generic import _get_provider
Expand Down Expand Up @@ -45,7 +45,7 @@ def get(request, device):
raw_entries = [{"name": entry.name,
"type": entry.type,
"raw_value": as_nested_list(entry.raw_value)} for entry in device_info.raw_entries]
new_entries = _update_provided_data(device, device_info)
new_entries = _update_provided_data(device, device_info, True)
formatted_entries = [{"name": entry.name,
"value": entry.formatted_value,
"stored_at": timesince(entry.stored_at)} for entry in new_entries]
Expand All @@ -58,8 +58,11 @@ class DeviceSoftware(View):
@staticmethod
def get(request, device):
device = get_object_or_404(Device, pk=device)
provider = _get_provider(device)
if provider is None:
return JsonResponse({})
try:
software_info = _get_provider(device).get_software_info(device)
software_info = provider.get_software_info(device)
except Exception as e:
logger.error(e)
return HttpResponse(_("Could not load data."))
Expand Down
4 changes: 2 additions & 2 deletions devicedata/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ def _get_provider(device):


def _update_provided_data(device, data, force=False):
old_data = device.provided_data.all()
if not force:
old_data = device.provided_data.all()
if len(old_data) > 0:
if (timezone.now() - old_data[0].stored_at).days < 7:
return old_data
device.provided_data.all().delete()
old_data.delete()
for entry in data.formatted_entries:
pd = ProvidedData()
pd.device = device
Expand Down
132 changes: 132 additions & 0 deletions devicedata/providers/baramundi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import base64
from unicodedata import name

from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import gettext_lazy as _

import requests

from devicedata.providers.base_provider import BaseDeviceInfo
from devicedata.providers.base_provider import BaseProvider
from devicedata.providers.base_provider import DeviceInfoEntry
from devicedata.providers.base_provider import FormattedDeviceInfoEntry
from devicedata.providers.helpers import format_bytes


class BaramundiDeviceInfo(BaseDeviceInfo):
def format_serialnumber(self):
self.simple_format('SerialNumber', _('Serial Number'))

def format_hostname(self):
self.simple_format('HostName', _('Hostname'))

def format_type(self):
self.simple_format('ModelName', _('Type'))

def format_lastseen(self):
self.simple_format('LastSeen', _('Last Seen'))

def format_processor(self):
self.simple_format('CPUDescription', _('Processor'))

def format_memory(self):
entries = self.find_entries("TotalMemory")
if len(entries) > 0:
self.formatted_entries.append(
FormattedDeviceInfoEntry(_("Memory"), format_bytes(entries[0].raw_value * 1024 * 1024)))

def format_storage(self):
entries = self.find_entries("StorageMedia")
drives = []
for entry in entries:
for disk in entry.raw_value:
if "ByteSize" in disk and disk["ByteSize"] < 1000000000:
# Smaller than 10gb. This most likely is not a hard drive.
continue
drives.append(disk)
formatted_capacities = "<br />".join(
["{0}: {1}".format(drive["Name"], format_bytes(drive["ByteSize"])) for drive in drives])
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Storage"), formatted_capacities))

def format_entries(self):
self.format_serialnumber()
self.format_hostname()
self.format_lastseen()
self.format_processor()
self.format_memory()
self.format_storage()

class BaramundiProvider(BaseProvider):
name = "baramundi"

@staticmethod
def __run_query(url):
if not hasattr(settings, "BARAMUNDI_SETTINGS"):
return

host = settings.BARAMUNDI_SETTINGS['host'] + ":" + str(settings.BARAMUNDI_SETTINGS['port'])
full_url = url %host
if 'authorization' in settings.BARAMUNDI_SETTINGS:
authorization = settings.BARAMUNDI_SETTINGS['authorization']
else:
authorization = ('{}:{}'.format(settings.BARAMUNDI_SETTINGS['user_name'], settings.BARAMUNDI_SETTINGS['password'])).encode('ascii')
authorization = base64.b64encode(authorization).decode('ascii')
session = requests.Session()
session.headers.update({'Authorization': 'Basic {}'.format(authorization), 'content-type': "application/json; charset=utf-8"})

print(full_url, settings.BARAMUNDI_SETTINGS['ignore_ssl'] is not True)
result = session.get(full_url, verify=settings.BARAMUNDI_SETTINGS['ignore_ssl'] is not True)
body = result.json()
if len(body) == 0:
raise ObjectDoesNotExist()
return body

def _get_device_id(self, device):
if len(device.hostname) > 0:
term = device.hostname
else:
term = '{:06d}'.format(device.id)
try:
data = self.__run_query('https://%s/bConnect/v1.0/search.json?type=endpoint&term=' + term)
print(data)
return data[0]['Id']
except ObjectDoesNotExist:
print("no object")
return None
except KeyError as e:
print(e)
return None

def get_device_info(self, device):
if not hasattr(settings, "BARAMUNDI_SETTINGS"):
return
id = self._get_device_id(device)
if id is None:
return
info = self.__run_query('https://%s/bConnect/v1.0/endpoints.json?id=' + id)
device_entries = []
for key in info:
device_entries.append(DeviceInfoEntry(key, None, info[key]))
return BaramundiDeviceInfo(device, device_entries)

def get_software_info(self, device):
return
if not hasattr(settings, "BARAMUNDI_SETTINGS"):
return
id = self._get_device_id(device)
if id is None:
return
info = self.__run_query('https://%s/bConnect/v1.0/softwarescanrules.json?id=' + id)
print(info)
return super().get_software_info(device)

def has_device(self, device):
if not hasattr(settings, "BARAMUNDI_SETTINGS"):
return False
try:
id = self._get_device_id(device)
print(id)
return id is not None and len(id) > 0
except ObjectDoesNotExist:
return False
5 changes: 5 additions & 0 deletions devicedata/providers/base_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ class BaseDeviceInfo(ABC):
def find_entries(self, entry_type):
return [entry for entry in self.raw_entries if entry.type == entry_type]

def simple_format(self, entry_type, name):
entries = self.find_entries(entry_type)
if len(entries) > 0:
self.formatted_entries.append((FormattedDeviceInfoEntry(name, entries[0].raw_value)))

def __init__(self, device, raw_entries):
self.device = device
self.formatted_entries = []
Expand Down
2 changes: 1 addition & 1 deletion devicedata/providers/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ def format_bytes(size, power=2**10):
while size > power:
size /= power
n += 1
return "{0:g}{1}".format(size, power_labels[n] + "B")
return "{0:.2f}{1}".format(size, power_labels[n] + "B")
2 changes: 1 addition & 1 deletion devicedata/providers/opsi.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

from devicedata.providers.base_provider import BaseDeviceInfo
from devicedata.providers.base_provider import BaseProvider
Expand Down
10 changes: 3 additions & 7 deletions devicedata/providers/puppet.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

import requests

Expand All @@ -28,9 +28,7 @@ def format_serialnumber(self):
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Serial Number"), entries[0].raw_value))

def format_type(self):
entries = self.find_entries("sp_machine_name")
if len(entries) > 0:
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Type"), entries[0].raw_value))
self.simple_format('sp_machine_name', _('Type'))

def format_hostname(self):
entries = self.find_entries("fqdn")
Expand All @@ -43,9 +41,7 @@ def format_hostname(self):
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Hostname"), entries[0].raw_value))

def format_lastseen(self):
entries = self.find_entries("timestamp")
if len(entries) > 0:
self.formatted_entries.append(FormattedDeviceInfoEntry(_("Last Seen"), entries[0].raw_value))
self.simple_format('timestamp', _('Last Seen'))

def format_processor(self):
entries = self.find_entries("processors")
Expand Down
2 changes: 1 addition & 1 deletion devicegroups/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.db import models
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

from reversion import revisions as reversion

Expand Down
2 changes: 1 addition & 1 deletion devicegroups/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django.db.models import Q
from django.urls import reverse
from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView
from django.views.generic import DeleteView
from django.views.generic import DetailView
Expand Down
2 changes: 1 addition & 1 deletion devices/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from django.db.utils import OperationalError
from django.db.utils import ProgrammingError
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

from django_select2.forms import Select2MultipleWidget
from django_select2.forms import Select2Widget
Expand Down
2 changes: 1 addition & 1 deletion devices/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.db.models import Q
from django.urls import reverse
from django.utils.timezone import utc
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

import reversion

Expand Down
10 changes: 5 additions & 5 deletions devices/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from django.urls import reverse_lazy
from django.utils import timezone
from django.utils.timesince import timesince
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView
from django.views.generic import DeleteView
from django.views.generic import DetailView
Expand Down Expand Up @@ -725,14 +725,14 @@ def form_valid(self, form):
try:
templates.append(MailTemplate.objects.get(usage="lent"))
except:
messages.error(self.request, _('MAIL NOT SENT - Template for lent devices does not exist for your main department'))
messages.error(self.request, _('MAIL NOT SENT - Template for lent devices does not exist'))

if form.cleaned_data["room"]:
device.room = form.cleaned_data["room"]
try:
templates.append(MailTemplate.objects.get(usage="room"))
except:
messages.error(self.request, _('MAIL NOT SENT - Template for room change does not exist for your main department'))
messages.error(self.request, _('MAIL NOT SENT - Template for room change does not exist'))
if templates:
for template in templates:
template.send(self.request, data={"device": device, "user": self.request.user})
Expand Down Expand Up @@ -816,13 +816,13 @@ def form_valid(self, form):
try:
templates.append(MailTemplate.objects.get(usage="returned"))
except:
messages.error(self.request, _('MAIL NOT SENT - Template for returned device does not exist for your main department'))
messages.error(self.request, _('MAIL NOT SENT - Template for returned device does not exist'))
if form.cleaned_data["room"]:
device.room = form.cleaned_data["room"]
try:
templates.append(MailTemplate.objects.get(usage="room"))
except:
messages.error(self.request, _('MAIL NOT SENT - Template for room change does not exist for your main department'))
messages.error(self.request, _('MAIL NOT SENT - Template for room change does not exist'))
if templates:
for template in templates:
template.send(self.request, data={"device": device, "user": self.request.user})
Expand Down
2 changes: 1 addition & 1 deletion devicetags/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.db import models
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

from devices.models import Device

Expand Down
2 changes: 1 addition & 1 deletion devicetags/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.shortcuts import render
from django.urls import reverse
from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView
from django.views.generic import DeleteView
from django.views.generic import FormView
Expand Down
Loading