-
Notifications
You must be signed in to change notification settings - Fork 2
Store the list of deb packages. #401
Changes from all commits
26e08b3
1f375a6
2b156df
eba44cc
c8b3e7b
8484534
a0b1a20
adb2263
e08e535
8444970
2393f8f
4282e27
e6e826f
747ea8a
c264acd
c76eece
7d0c78a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Generated by Django 2.1.10 on 2019-09-09 11:28 | ||
|
|
||
| import device_registry.models | ||
| from django.db import migrations, models | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ('device_registry', '0055_remove_deviceinfo_trust_score'), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.CreateModel( | ||
| name='DebPackage', | ||
| fields=[ | ||
| ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
| ('name', models.CharField(max_length=128)), | ||
| ('version', models.CharField(max_length=128)), | ||
| ('arch', models.CharField(choices=[(device_registry.models.DebPackage.Arch('i386'), 'i386'), (device_registry.models.DebPackage.Arch('amd64'), 'amd64'), (device_registry.models.DebPackage.Arch('armhf'), 'armhf'), (device_registry.models.DebPackage.Arch('all'), 'all')], max_length=16)), | ||
| ], | ||
| ), | ||
| migrations.AddField( | ||
| model_name='device', | ||
| name='deb_packages_hash', | ||
| field=models.CharField(blank=True, max_length=32), | ||
| ), | ||
| migrations.AlterUniqueTogether( | ||
| name='debpackage', | ||
| unique_together={('name', 'version', 'arch')}, | ||
| ), | ||
| migrations.AddField( | ||
| model_name='device', | ||
| name='deb_packages', | ||
| field=models.ManyToManyField(to='device_registry.DebPackage'), | ||
| ), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,13 @@ | ||
| from enum import Enum | ||
| import datetime | ||
| from statistics import mean | ||
| import json | ||
| import uuid | ||
|
|
||
| from django.conf import settings | ||
| from django.db import models | ||
| from django.db import models, transaction | ||
| from django.utils import timezone | ||
| from django.contrib.postgres.fields import JSONField | ||
| from django.db import transaction | ||
|
|
||
| import yaml | ||
| import tagulous.models | ||
|
|
@@ -39,6 +39,26 @@ def from_db_value(self, value, expression, connection, context): | |
| return value | ||
|
|
||
|
|
||
| class DebPackage(models.Model): | ||
| class Distro(Enum): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want the field value to be converted to Enum class, this way we can have some type checking later when we work with deb packages in a separate worker which will scan them for CVEs.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you give me some example of such type checking that requires enum?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is self-documented, has less code and will fail quickly (before even getting to the db backend) if we do |
||
| DEBIAN = 'debian' | ||
| RASPBIAN = 'raspbian' | ||
| UBUNTU = 'ubuntu' | ||
|
|
||
| class Arch(Enum): | ||
| i386 = 'i386' | ||
| AMD64 = 'amd64' | ||
| ARMHF = 'armhf' | ||
| ALL = 'all' | ||
|
|
||
| name = models.CharField(max_length=128) | ||
| version = models.CharField(max_length=128) | ||
| arch = models.CharField(max_length=16, choices=[(tag, tag.value) for tag in Arch]) | ||
|
|
||
| class Meta: | ||
| unique_together = ['name', 'version', 'arch'] | ||
|
|
||
|
|
||
| class Device(models.Model): | ||
| device_id = models.CharField( | ||
| max_length=128, | ||
|
|
@@ -65,11 +85,53 @@ class Device(models.Model): | |
| agent_version = models.CharField(max_length=36, blank=True, null=True) | ||
| tags = tagulous.models.TagField(to=Tag, blank=True) | ||
| trust_score = models.FloatField(null=True) | ||
| deb_packages = models.ManyToManyField(DebPackage) | ||
|
a-martynovich marked this conversation as resolved.
Outdated
|
||
| deb_packages_hash = models.CharField(max_length=32, blank=True) | ||
|
|
||
| @property | ||
| def certificate_expired(self): | ||
| return self.certificate_expires < timezone.now() | ||
|
|
||
| INSECURE_SERVICES = [ | ||
| 'fingerd', | ||
| 'tftpd', | ||
| 'telnetd', | ||
| 'snmpd', | ||
| 'xinetd', | ||
| 'nis', | ||
| 'atftpd', | ||
| 'tftpd-hpa', | ||
| 'rsh-server', | ||
| 'rsh-redone-server' | ||
| ] | ||
|
|
||
| @property | ||
| def insecure_services(self): | ||
| """ | ||
| Get a list of deb packages which are marked "insecure", i.e. their names are in INSECURE_SERVICES list. | ||
| :return: list of DebPackage or None if set_deb_packages() wasn't called before. | ||
| """ | ||
| if not self.deb_packages_hash: | ||
| return None | ||
| return self.deb_packages.filter(name__in=self.INSECURE_SERVICES) | ||
|
|
||
| def set_deb_packages(self, packages): | ||
|
a-martynovich marked this conversation as resolved.
Outdated
|
||
| """ | ||
| Assign the list of installed deb packages to this device. | ||
| :param packages: list of dicts with the following values: 'name': str, 'version': str, 'arch': DebPackage.Arch. | ||
| """ | ||
| # Save new packages to DB. | ||
| DebPackage.objects.bulk_create([DebPackage(name=package['name'], version=package['version'], | ||
| arch=package['arch']) for package in packages], | ||
| ignore_conflicts=True) | ||
| # Get packages qs. | ||
| q_objects = models.Q() | ||
| for package in packages: | ||
| q_objects.add(models.Q(name=package['name'], version=package['version'], arch=package['arch']), models.Q.OR) | ||
|
|
||
| # Set deb_packages. | ||
| self.deb_packages.set(DebPackage.objects.filter(q_objects).only('pk')) | ||
|
|
||
| def get_name(self): | ||
| if self.name: | ||
| return self.name | ||
|
|
||

Uh oh!
There was an error while loading. Please reload this page.