Skip to content
Merged
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
3 changes: 2 additions & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ Depends: ${misc:Depends}, python3 (>= 3.11), python3-django (>= 4.2),
python3-requests, python3-colorama, python3-magic, python3-humanize,
python3-yaml, libapache2-mod-wsgi-py3, apache2, sqlite3,
celery, python3-celery, python3-django-celery-beat, redis-server,
python3-redis, python3-git, python3-django-taggit, python3-zstandard
python3-redis, python3-git, python3-django-taggit, python3-zstandard,
python3-django-tables2, python3-django-select2
Suggests: python3-mysqldb, python3-psycopg2, python3-pymemcache, memcached
Description: Django-based patch status monitoring tool for linux systems.
.
Expand Down
4 changes: 2 additions & 2 deletions errata/sources/distros/rocky.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ def process_rocky_erratum(advisory):
def add_rocky_erratum_references(e, advisory):
""" Add Rocky Linux errata references
"""
e.add_reference('Rocky Advisory', 'https://apollo.build.resf.org/{e.name}')
e.add_reference('Rocky Advisory', 'https://errata.rockylinux.org/{e.name}')
e.add_reference('Rocky Advisory', f'https://apollo.build.resf.org/{e.name}')
e.add_reference('Rocky Advisory', f'https://errata.rockylinux.org/{e.name}')
advisory_cves = advisory.get('cves')
for a_cve in advisory_cves:
cve_id = a_cve.get('cve')
Expand Down
111 changes: 111 additions & 0 deletions errata/tables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# This file is part of Patchman.
#
# Patchman is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 only.
#
# Patchman is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Patchman. If not, see <http://www.gnu.org/licenses/>

import django_tables2 as tables

from errata.models import Erratum
from util.tables import BaseTable

ERRATUM_NAME_TEMPLATE = '<a href="{{ record.get_absolute_url }}">{{ record.name }}</a>'
PACKAGES_AFFECTED_TEMPLATE = (
'{% with count=record.affected_packages.count %}'
'{% if count != 0 %}'
'<a href="{% url \'packages:package_list\' %}?erratum_id={{ record.id }}&type=affected">{{ count }}</a>'
'{% else %}{% endif %}{% endwith %}'
)
PACKAGES_FIXED_TEMPLATE = (
'{% with count=record.fixed_packages.count %}'
'{% if count != 0 %}'
'<a href="{% url \'packages:package_list\' %}?erratum_id={{ record.id }}&type=fixed">{{ count }}</a>'
'{% else %}{% endif %}{% endwith %}'
)
OSRELEASES_TEMPLATE = (
'{% with count=record.osreleases.count %}'
'{% if count != 0 %}'
'<a href="{% url \'operatingsystems:osrelease_list\' %}?erratum_id={{ record.id }}">{{ count }}</a>'
'{% else %}{% endif %}{% endwith %}'
)
ERRATUM_CVES_TEMPLATE = (
'{% with count=record.cves.count %}'
'{% if count != 0 %}'
'<a href="{% url \'security:cve_list\' %}?erratum_id={{ record.id }}">{{ count }}</a>'
'{% else %}{% endif %}{% endwith %}'
)
REFERENCES_TEMPLATE = (
'{% with count=record.references.count %}'
'{% if count != 0 %}'
'<a href="{% url \'security:reference_list\' %}?erratum_id={{ record.id }}">{{ count }}</a>'
'{% else %}{% endif %}{% endwith %}'
)


class ErratumTable(BaseTable):
erratum_name = tables.TemplateColumn(
ERRATUM_NAME_TEMPLATE,
order_by='name',
verbose_name='ID',
attrs={'th': {'class': 'col-sm-1'}, 'td': {'class': 'col-sm-1'}},
)
e_type = tables.Column(
order_by='e_type',
verbose_name='Type',
attrs={'th': {'class': 'col-sm-1'}, 'td': {'class': 'col-sm-1'}},
)
issue_date = tables.DateColumn(
order_by='issue_date',
verbose_name='Published Date',
attrs={'th': {'class': 'col-sm-1'}, 'td': {'class': 'col-sm-1 centered'}},
)
synopsis = tables.Column(
orderable=False,
verbose_name='Synopsis',
attrs={'th': {'class': 'col-sm-4'}, 'td': {'class': 'col-sm-4'}},
)
packages_affected = tables.TemplateColumn(
PACKAGES_AFFECTED_TEMPLATE,
orderable=False,
verbose_name='Packages Affected',
attrs={'th': {'class': 'col-sm-1'}, 'td': {'class': 'col-sm-1 centered'}},
)
packages_fixed = tables.TemplateColumn(
PACKAGES_FIXED_TEMPLATE,
orderable=False,
verbose_name='Packages Fixed',
attrs={'th': {'class': 'col-sm-1'}, 'td': {'class': 'col-sm-1 centered'}},
)
osreleases = tables.TemplateColumn(
OSRELEASES_TEMPLATE,
orderable=False,
verbose_name='OS Releases Affected',
attrs={'th': {'class': 'col-sm-1'}, 'td': {'class': 'col-sm-1 centered'}},
)
erratum_cves = tables.TemplateColumn(
ERRATUM_CVES_TEMPLATE,
orderable=False,
verbose_name='CVEs',
attrs={'th': {'class': 'col-sm-1'}, 'td': {'class': 'col-sm-1 centered'}},
)
references = tables.TemplateColumn(
REFERENCES_TEMPLATE,
orderable=False,
verbose_name='References',
attrs={'th': {'class': 'col-sm-1'}, 'td': {'class': 'col-sm-1 centered'}},
)

class Meta(BaseTable.Meta):
model = Erratum
fields = (
'erratum_name', 'e_type', 'issue_date', 'synopsis', 'packages_affected',
'packages_fixed', 'osreleases', 'erratum_cves', 'references',
)
16 changes: 6 additions & 10 deletions errata/templates/errata/erratum_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,24 +61,20 @@
</div>
<div class="tab-pane fade in" id="erratum_affected_packages">
<div class="well well-sm">
<div class="well well-sm">
<ul class="package-list">
{% for package in erratum.affected_packages.all %}
<span class="label label-brick {% cycle 'bg-info' 'bg-success' %}">
<a href="{{ package.get_absolute_url }}"> {{ package }} </a>
</span>
<li><a href="{{ package.get_absolute_url }}">{{ package }}</a></li>
{% endfor %}
</div>
</ul>
</div>
</div>
<div class="tab-pane fade in" id="erratum_fixed_packages">
<div class="well well-sm">
<div class="well well-sm">
<ul class="package-list">
{% for package in erratum.fixed_packages.all %}
<span class="label label-brick {% cycle 'bg-info' 'bg-success' %}">
<a href="{{ package.get_absolute_url }}"> {{ package }} </a>
</span>
<li><a href="{{ package.get_absolute_url }}">{{ package }}</a></li>
{% endfor %}
</div>
</ul>
</div>
</div>
</div>
Expand Down
31 changes: 0 additions & 31 deletions errata/templates/errata/erratum_table.html

This file was deleted.

18 changes: 6 additions & 12 deletions errata/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
# along with Patchman. If not, see <http://www.gnu.org/licenses/>

from django.contrib.auth.decorators import login_required
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.db.models import Q
from django.shortcuts import get_object_or_404, render
from django_tables2 import RequestConfig
from rest_framework import viewsets

from errata.models import Erratum
from errata.serializers import ErratumSerializer
from errata.tables import ErratumTable
from operatingsystems.models import OSRelease
from util.filterspecs import Filter, FilterBar

Expand Down Expand Up @@ -61,26 +62,19 @@ def erratum_list(request):
else:
terms = ''

page_no = request.GET.get('page')
paginator = Paginator(errata, 50)

try:
page = paginator.page(page_no)
except PageNotAnInteger:
page = paginator.page(1)
except EmptyPage:
page = paginator.page(paginator.num_pages)

filter_list = []
filter_list.append(Filter(request, 'Erratum Type', 'e_type',
Erratum.objects.values_list('e_type', flat=True).distinct()))
filter_list.append(Filter(request, 'OS Release', 'osrelease_id',
OSRelease.objects.filter(erratum__in=errata)))
filter_bar = FilterBar(request, filter_list)

table = ErratumTable(errata)
RequestConfig(request, paginate={'per_page': 50}).configure(table)

return render(request,
'errata/erratum_list.html',
{'page': page,
{'table': table,
'filter_bar': filter_bar,
'terms': terms})

Expand Down
120 changes: 120 additions & 0 deletions hosts/tables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# This file is part of Patchman.
#
# Patchman is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 only.
#
# Patchman is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Patchman. If not, see <http://www.gnu.org/licenses/>

import django_tables2 as tables

from hosts.models import Host
from util.tables import BaseTable

CHECKBOX_TEMPLATE = '<input type="checkbox" name="selected_ids" value="{{ record.id }}" class="bulk-checkbox">'
SELECT_ALL_CHECKBOX = '<input type="checkbox" id="select-all-page" title="Select all on this page">'
HOSTNAME_TEMPLATE = '<a href="{{ record.get_absolute_url }}">{{ record.hostname }}</a>'
SEC_UPDATES_TEMPLATE = (
'{% with count=record.get_num_security_updates %}'
'{% if count != 0 %}<span style="color:red">{{ count }}</span>{% else %}{% endif %}'
'{% endwith %}'
)
BUG_UPDATES_TEMPLATE = (
'{% with count=record.get_num_bugfix_updates %}'
'{% if count != 0 %}<span style="color:orange">{{ count }}</span>{% else %}{% endif %}'
'{% endwith %}'
)
AFFECTED_ERRATA_TEMPLATE = (
'{% with count=record.errata.count %}'
'{% if count != 0 %}'
'<a href="{% url \'errata:erratum_list\' %}?host={{ record.hostname }}">{{ count }}</a>'
'{% else %}{% endif %}{% endwith %}'
)
OSVARIANT_TEMPLATE = (
'{% if record.osvariant %}'
'<a href="{{ record.osvariant.get_absolute_url }}">{{ record.osvariant }}</a>'
'{% endif %}'
)
PACKAGES_TEMPLATE = (
'<a href="{% url \'packages:package_list\' %}?host={{ record.hostname }}">'
'{{ record.packages_count }}</a>'
)
LASTREPORT_TEMPLATE = (
'{% load report_alert %}'
'{{ record.lastreport }} {% report_alert record.lastreport %}'
)
REBOOT_TEMPLATE = '{% load common %}{% no_yes_img record.reboot_required %}'


class HostTable(BaseTable):
selection = tables.TemplateColumn(
CHECKBOX_TEMPLATE,
orderable=False,
verbose_name=SELECT_ALL_CHECKBOX,
attrs={'th': {'class': 'min-width-col centered'}, 'td': {'class': 'min-width-col centered'}},
)
hostname = tables.TemplateColumn(
HOSTNAME_TEMPLATE,
order_by='hostname',
verbose_name='Hostname',
attrs={'th': {'class': 'col-sm-2'}, 'td': {'class': 'col-sm-2'}},
)
sec_updates = tables.TemplateColumn(
SEC_UPDATES_TEMPLATE,
order_by='sec_updates_count',
verbose_name='Security Updates',
attrs={'th': {'class': 'min-width-col'}, 'td': {'class': 'min-width-col centered'}},
)
bug_updates = tables.TemplateColumn(
BUG_UPDATES_TEMPLATE,
order_by='bug_updates_count',
verbose_name='Bugfix Updates',
attrs={'th': {'class': 'min-width-col'}, 'td': {'class': 'min-width-col centered'}},
)
affected_errata = tables.TemplateColumn(
AFFECTED_ERRATA_TEMPLATE,
order_by='errata_count',
verbose_name='Affected by Errata',
attrs={'th': {'class': 'min-width-col'}, 'td': {'class': 'min-width-col centered'}},
)
kernel = tables.Column(
verbose_name='Running Kernel',
attrs={'th': {'class': 'col-sm-2'}, 'td': {'class': 'col-sm-2'}},
)
osvariant = tables.TemplateColumn(
OSVARIANT_TEMPLATE,
order_by='osvariant__name',
verbose_name='OS Variant',
attrs={'th': {'class': 'col-sm-2'}, 'td': {'class': 'col-sm-2'}},
)
packages_installed = tables.TemplateColumn(
PACKAGES_TEMPLATE,
order_by='packages_count',
verbose_name='Packages',
attrs={'th': {'class': 'min-width-col'}, 'td': {'class': 'min-width-col centered'}},
)
lastreport = tables.TemplateColumn(
LASTREPORT_TEMPLATE,
order_by='lastreport',
verbose_name='Last Report',
attrs={'th': {'class': 'col-sm-2'}, 'td': {'class': 'col-sm-2'}},
)
reboot_required = tables.TemplateColumn(
REBOOT_TEMPLATE,
order_by='reboot_required',
verbose_name='Reboot Status',
attrs={'th': {'class': 'min-width-col'}, 'td': {'class': 'min-width-col centered'}},
)

class Meta(BaseTable.Meta):
model = Host
fields = (
'selection', 'hostname', 'packages_installed', 'sec_updates', 'bug_updates',
'affected_errata', 'kernel', 'osvariant', 'lastreport', 'reboot_required',
)
15 changes: 8 additions & 7 deletions hosts/templates/hosts/host_delete.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,19 @@
</tr>
<tr><th>Updated</th><td> {{ host.updated_at }} </td></tr>
<tr><th>Last Report</th><td> {{ host.lastreport }} </td></tr>
<tr><th>Updates Available</th><td> <a data-toggle="tab" href="{{ host.get_absolute_url }}#host_updates">{{ host.updates.count }}</a> </td></tr>
<tr><th>Packages Installed</th><td> <a href="{% url 'packages:package_list' %}?host={{ host }}">{{ host.packages.count}}</a> </td></tr>
<tr><th>Updates Available</th><td> {{ host.updates.count }} </td></tr>
<tr><th>Errata</th><td><a href="{% url 'errata:erratum_list' %}?host={{ host.hostname }}">{{ host.errata.count }}<a/></td>
<tr><th>Reboot Required</th><td> {{ host.reboot_required }} </td></tr>
<tr><th>Packages Installed</th><td> <a data-toggle="tab" href="{{ host.get_absolute_url }}#host_packages">{{ host.packages.count}}</a> </td></tr>
<tr><th>Repos In Use</th><td>{% if host.host_repos_only %}Host Repos{% else %}Host and OS Release Repos{% endif %}</td></tr>
<tr>
<th>Last 3 reports</th>
<td>
{% for report in reports %}
<span class="label label-brick {% cycle 'bg-info' 'bg-success' %}">
<a href="{{ report.get_absolute_url}}">{{ report.created }} </a>
</span>
{% endfor %}
<ul class="package-list">
{% for report in reports %}
<li><a href="{{ report.get_absolute_url}}">{{ report.created }}</a></li>
{% endfor %}
</ul>
</td>
</tr>
</table>
Expand Down
Loading
Loading