From 87f32f0def2fad201675f385c22c47b6e14dd7f2 Mon Sep 17 00:00:00 2001 From: Alessio Del Conte Date: Wed, 21 Feb 2024 10:03:15 +0100 Subject: [PATCH] New logo, color header admin when debug and verbose names --- docker/deploy | 2 +- drmaatic/admin.py | 47 ++++++++++++++++-- drmaatic/job/admin.py | 2 +- drmaatic/job/models.py | 4 ++ drmaatic/models.py | 14 +++--- drmaatic/static/css/admin-when-debug.css | 15 ++++++ .../{mymodel_list.css => job-list-admin.css} | 0 drmaatic/static/favicon/favicon.png | Bin 0 -> 1295 bytes drmaatic/static/favicon/favicon.svg | 9 ++++ drmaatic/static/img/icon.svg | 9 ++++ drmaatic/static/img/logo-dark.svg | 31 ++++++++++++ drmaatic/static/img/logo-white.svg | 31 ++++++++++++ drmaatic/static/swagger.yml | 4 +- server/settings.py | 4 ++ server/utils.py | 23 +++++++++ templates/admin/base_site.html | 9 +++- templates/rest_framework/api.html | 2 +- templates/swagger-ui.html | 2 +- 18 files changed, 189 insertions(+), 19 deletions(-) create mode 100644 drmaatic/static/css/admin-when-debug.css rename drmaatic/static/css/{mymodel_list.css => job-list-admin.css} (100%) create mode 100644 drmaatic/static/favicon/favicon.png create mode 100644 drmaatic/static/favicon/favicon.svg create mode 100644 drmaatic/static/img/icon.svg create mode 100644 drmaatic/static/img/logo-dark.svg create mode 100644 drmaatic/static/img/logo-white.svg create mode 100644 server/utils.py diff --git a/docker/deploy b/docker/deploy index a7e77e1..8254174 160000 --- a/docker/deploy +++ b/docker/deploy @@ -1 +1 @@ -Subproject commit a7e77e1528a843aa9de51c65b783fc5d06f9545b +Subproject commit 825417451090ec7c5269eececccd228a6a0cfbfd diff --git a/drmaatic/admin.py b/drmaatic/admin.py index c8b733a..6725b04 100644 --- a/drmaatic/admin.py +++ b/drmaatic/admin.py @@ -1,10 +1,9 @@ -import uuid - import jwt from django.contrib.admin import display -from django.contrib.admin.widgets import AdminDateWidget, AdminSplitDateTime +from django.contrib.admin.widgets import AdminSplitDateTime from django.contrib.auth import admin as auth from django.utils import timezone +from django.core.cache import cache from drmaatic.models import * # noinspection PyUnresolvedReferences @@ -15,6 +14,7 @@ from drmaatic.queue.admin import * # noinspection PyUnresolvedReferences from drmaatic.task.admin import * +from drmaatic.throttles import TokenBucketThrottle # Register user in the admin web interface, using the default interface admin.site.register(Admin, auth.UserAdmin) @@ -77,9 +77,46 @@ class UserAdmin(admin.ModelAdmin): class GroupForm(forms.ModelForm): - def clean(self): + def clean_token_renewal_time(self): if timeparse(self.cleaned_data["token_renewal_time"]) is None: - raise forms.ValidationError({'token_renewal_time': "Invalid time"}) + raise forms.ValidationError("Invalid time") + return self.cleaned_data["token_renewal_time"] + + def clean_throttling_rate_burst(self): + def parse_rate(rate): + num, period = rate.split('/') + num_requests = int(num) + duration = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}[period[0]] + return num_requests, duration + + try: + parse_rate(self.cleaned_data["throttling_rate_burst"]) + except: + raise forms.ValidationError("Invalid rate, expected format: /") + return self.cleaned_data["throttling_rate_burst"] + + def clean__cpu_credit_regen_time(self): + if timeparse(self.cleaned_data["_cpu_credit_regen_time"]) is None: + raise forms.ValidationError("Invalid time") + return self.cleaned_data["_cpu_credit_regen_time"] + + def clean_cpu_credit_max_amount(self): + if self.cleaned_data["cpu_credit_max_amount"] < 0: + raise forms.ValidationError("Invalid amount") + return self.cleaned_data["cpu_credit_max_amount"] + + def clean_cpu_credit_regen_amount(self): + if self.cleaned_data["cpu_credit_regen_amount"] < 0: + raise forms.ValidationError("Invalid amount") + return self.cleaned_data["cpu_credit_regen_amount"] + + def save(self, commit=True): + super().save(commit=commit) + # If the cpu_credit_max_amount is changed, invalidate the cache + if 'cpu_credit_max_amount' in self.changed_data: + cache_keys_to_invalidate = [key.split(':')[-1] for key in cache._cache.keys() if TokenBucketThrottle.TOKENS_CACHE_PREFIX in key] + cache.delete_many(cache_keys_to_invalidate) + return self.instance @admin.register(Group) diff --git a/drmaatic/job/admin.py b/drmaatic/job/admin.py index 420caa0..dd832b4 100644 --- a/drmaatic/job/admin.py +++ b/drmaatic/job/admin.py @@ -19,7 +19,7 @@ def delete_jobs_from_file_system(jobs): @admin.register(Job) class JobAdmin(admin.ModelAdmin): class Media: - css = {'all': ('css/mymodel_list.css',)} + css = {'all': ('css/job-list-admin.css',)} readonly_fields = ('uuid', 'task', 'creation_date', '_sender_ip_addr', '_drm_job_id', 'parent_job', 'dependencies', 'dependency_type', '_files_name') diff --git a/drmaatic/job/models.py b/drmaatic/job/models.py index 9037b23..1c1dd14 100644 --- a/drmaatic/job/models.py +++ b/drmaatic/job/models.py @@ -75,6 +75,10 @@ def delete_from_user(self): self.deleted = True self.save() + def delete(self, using=None, keep_parents=False): + self.delete_from_file_system() + super().delete(using, keep_parents) + def get_first_ancestor(self): current_job = self while current_job.parent_job is not None: diff --git a/drmaatic/models.py b/drmaatic/models.py index 2c21abd..c15f6c1 100644 --- a/drmaatic/models.py +++ b/drmaatic/models.py @@ -43,10 +43,10 @@ class Group(models.Model): name = models.CharField(max_length=50) has_full_access = models.BooleanField(default=False, blank=False, null=False) throttling_rate_burst = models.CharField(max_length=30, default="10/s", null=False, blank=False) - token_renewal_time = models.CharField(default="1 day", null=False, blank=False, max_length=40) - cpu_credit_max_amount = models.IntegerField(default=100, blank=False, null=False) - _cpu_credit_regen_time = models.CharField(default="30 seconds", null=False, blank=False, max_length=40) - cpu_credit_regen_amount = models.IntegerField(default=1, blank=False, null=False) + token_renewal_time = models.CharField(default="1 day", null=False, blank=False, max_length=40, verbose_name="JWT renewal time") + cpu_credit_max_amount = models.IntegerField(default=100, blank=False, null=False, verbose_name="CPU credit max amount") + _cpu_credit_regen_time = models.CharField(default="30 seconds", null=False, blank=False, max_length=40, verbose_name="CPU credit regen time") + cpu_credit_regen_amount = models.IntegerField(default=1, blank=False, null=False, verbose_name="CPU credit regen amount") @property def cpu_credit_regen_time(self): @@ -54,11 +54,11 @@ def cpu_credit_regen_time(self): @classproperty def anonymous(self): - if table_exists('drmaatic_group', 'default'): + try: return self.objects.get_or_create(name='anonymous', defaults={'throttling_rate_burst': '20/s', 'token_renewal_time': '3 days', 'cpu_credit_max_amount': 100})[0] - else: + except OperationalError: return Group(name='anonymous', throttling_rate_burst='20/s', token_renewal_time='3 days', cpu_credit_max_amount=100) @@ -102,7 +102,7 @@ class User(models.Model): # Defines whether the user is enabled active = models.BooleanField(default=True, blank=False, null=False) - token_renewal_time = models.CharField(max_length=40, blank=True, null=True) + token_renewal_time = models.CharField(max_length=40, blank=True, null=True, verbose_name="JWT renewal time") group = models.ForeignKey('Group', on_delete=models.SET_DEFAULT, null=False, default=Group.registered.id) diff --git a/drmaatic/static/css/admin-when-debug.css b/drmaatic/static/css/admin-when-debug.css new file mode 100644 index 0000000..3ec6b4a --- /dev/null +++ b/drmaatic/static/css/admin-when-debug.css @@ -0,0 +1,15 @@ +#header { + background-color: #ab3434; +} + +.theme-toggle svg.theme-icon-when-auto, .theme-toggle svg.theme-icon-when-dark, .theme-toggle svg.theme-icon-when-light { + color: #ab3434 !important; +} + +div.breadcrumbs { + background-color: #792424; +} + +#site-name > a:after { + content: " DEBUG"; +} diff --git a/drmaatic/static/css/mymodel_list.css b/drmaatic/static/css/job-list-admin.css similarity index 100% rename from drmaatic/static/css/mymodel_list.css rename to drmaatic/static/css/job-list-admin.css diff --git a/drmaatic/static/favicon/favicon.png b/drmaatic/static/favicon/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..9ec30b2bb6735d7ed0990a732c4f9a27e0cce563 GIT binary patch literal 1295 zcmV+q1@QWbP)FV00009a7bBm000{o z000{o0fe6ZJS8>6X64K_`pl`2ZD8Z{IfwNWD?Ra8V#B1owUt@>a^>jx-O zm0E)jQmkO9h!3?=zp+qM1Z%5>YP6*U6~857t;B0;s>b|%n6qTP-QByhcW*BF!*KTQ zoO9-!*_ktEW^O?eHNp|V?ZC~z$v}Mu9h#b_MILAXwgMMasHadX2iD?@-w&(=-UUXo zC@R!o2sHt}08?>Jd{~LHx;!lMLeZal=fBF;6s0;1)&%id|V_?{Hp9P!;EHs`Xunc&)obrOC zTNs~MVHANzU@>r`@vH*Yco^S?i}iEN@P~m7z-SErIlx1}5?n_;2t1b9f}}L%COHgC zYDy_HOVWVJePqAWwzpE!sLA#w@upRXq<&L)MN0nHL&i6Fv=fxuOnyYt+&Dg;DD*jS z2G9+(0P}!9fkEJH;M)-I#lV%gG2Ux@zIfK!x*k}K8^(vjqeos+GImPpHr`k5-RcZI zA1>{Z{*g2$sWplxjgl#no(vf}C~1SFRg&(O^qjquHPk2RklYwPXSp61h(@gGAi$^$&!F80m=&RNc8p7r5-uJ$^;r9h_D=BU%{{yNn_b)(RRlWcK002ovPDHLk FV1h%SRXP9w literal 0 HcmV?d00001 diff --git a/drmaatic/static/favicon/favicon.svg b/drmaatic/static/favicon/favicon.svg new file mode 100644 index 0000000..bd3b2f3 --- /dev/null +++ b/drmaatic/static/favicon/favicon.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/drmaatic/static/img/icon.svg b/drmaatic/static/img/icon.svg new file mode 100644 index 0000000..bd3b2f3 --- /dev/null +++ b/drmaatic/static/img/icon.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/drmaatic/static/img/logo-dark.svg b/drmaatic/static/img/logo-dark.svg new file mode 100644 index 0000000..2f6b557 --- /dev/null +++ b/drmaatic/static/img/logo-dark.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/drmaatic/static/img/logo-white.svg b/drmaatic/static/img/logo-white.svg new file mode 100644 index 0000000..8df6f5b --- /dev/null +++ b/drmaatic/static/img/logo-white.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/drmaatic/static/swagger.yml b/drmaatic/static/swagger.yml index 90f1203..de9c97a 100644 --- a/drmaatic/static/swagger.yml +++ b/drmaatic/static/swagger.yml @@ -4,7 +4,7 @@ info: DRMAAtic version: 1.0.0 description: | - drmaatic logo     + drmaatic logo     slurm logo ### Introduction to DRMAAtic API @@ -38,7 +38,7 @@ info: - **Retrieve Internal JWT**: Allows users to obtain JWT tokens for authenticating with DRMAAtic, using access tokens from external providers. - - **Amount of CPU credit**: Provides the count of available CPU credit for the user. + - **Amount of CPU credit**: Provides the amount of available CPU credit for the user. - **Create a New Job**: Enables users to create new jobs, defining job parameters based on specific tasks. diff --git a/server/settings.py b/server/settings.py index 2cadd5f..09a342c 100644 --- a/server/settings.py +++ b/server/settings.py @@ -6,6 +6,8 @@ from environs import Env +from server.utils import IpNetworks + logger = logging.getLogger(__name__) env = Env() @@ -131,6 +133,8 @@ def load_env(environ): ROOT_URLCONF = 'server.urls' +INTERNAL_IPS = IpNetworks(env.list('INTERNAL_IPS', default=['0.0.0.0/0'])) + TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', diff --git a/server/utils.py b/server/utils.py new file mode 100644 index 0000000..8e13387 --- /dev/null +++ b/server/utils.py @@ -0,0 +1,23 @@ +import ipaddress + + +class IpNetworks: + """ + A Class that contains a list of IPvXNetwork objects. + + Credits to https://www.fomfus.com/articles/how-to-use-ip-ranges-for-django-s-internal_ips-setting/ + """ + + networks = [] + + def __init__(self, addresses): + """Create a new IpNetwork object for each address provided.""" + for address in addresses: + self.networks.append(ipaddress.ip_network(address)) + + def __contains__(self, address): + """Check if the given address is contained in any of our Networks.""" + for network in self.networks: + if ipaddress.ip_address(address) in network: + return True + return False diff --git a/templates/admin/base_site.html b/templates/admin/base_site.html index b353827..d6ca0fb 100644 --- a/templates/admin/base_site.html +++ b/templates/admin/base_site.html @@ -3,5 +3,12 @@ {% load static %} {% block extrahead %} - + +{% endblock %} + +{% block extrastyle %} + {{ block.super }} + {% if debug %} + + {% endif %} {% endblock %} diff --git a/templates/rest_framework/api.html b/templates/rest_framework/api.html index a13b6a1..45cc47f 100644 --- a/templates/rest_framework/api.html +++ b/templates/rest_framework/api.html @@ -2,5 +2,5 @@ {% load static %} {% block style %} {{ block.super }} - + {% endblock %} diff --git a/templates/swagger-ui.html b/templates/swagger-ui.html index ffc4c5f..a4caf5a 100644 --- a/templates/swagger-ui.html +++ b/templates/swagger-ui.html @@ -1,6 +1,6 @@ {% load static %} {% block style %} - + {% endblock %}