Skip to content

Commit

Permalink
Merge branch 'staging' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
sandstromviktor committed May 23, 2024
2 parents 2b5cadc + d7573bd commit 2d769be
Show file tree
Hide file tree
Showing 47 changed files with 1,012 additions and 1,011 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/pre-commit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.12

- name: Install dependencies
run: |
python -m pip install --upgrade pre-commit==3.3.3
python -m pip install --upgrade pre-commit==3.7.1
- name: Run pre-commit
run: pre-commit run --all-files
3 changes: 2 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ repos:

# static type checking
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.7.0
rev: v1.10.0
hooks:
- id: mypy
args: [--config-file, pyproject.toml]
additional_dependencies: [types-requests==2.25.9]
10 changes: 5 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.8-alpine3.19 as builder
FROM python:3.12.3-alpine3.19 as builder

LABEL maintainer="[email protected]"
WORKDIR /app
Expand Down Expand Up @@ -32,7 +32,7 @@ RUN apk add --update --no-cache \
curl

# Install Poetry, change configs and install packages.
RUN curl -sSL https://install.python-poetry.org | POETRY_VERSION=1.8.0 python3 - \
RUN curl -sSL https://install.python-poetry.org | POETRY_VERSION=1.8.2 python3 - \
&& /root/.local/bin/poetry self add poetry-plugin-export \
&& /root/.local/bin/poetry config virtualenvs.create false \
&& /root/.local/bin/poetry config installer.max-workers 10 \
Expand All @@ -43,7 +43,7 @@ RUN curl -sSL https://install.python-poetry.org | POETRY_VERSION=1.8.0 python3 -

FROM bitnami/kubectl:1.28.6 as kubectl
FROM alpine/helm:3.14.0 as helm
FROM python:3.8-alpine3.19 as runtime
FROM python:3.12.3-alpine3.19 as runtime

ARG DISABLE_EXTRAS=false

Expand All @@ -55,9 +55,9 @@ RUN apk add --update --no-cache \
jpeg-dev \
openjpeg-dev \
libpng-dev \
&& rm -rf /usr/local/lib/python3.8/site-packages/
&& rm -rf /usr/local/lib/python3.12/site-packages/

COPY --from=builder /usr/local/lib/python3.8/site-packages/ /usr/local/lib/python3.8/site-packages/
COPY --from=builder /usr/local/lib/python3.12/site-packages/ /usr/local/lib/python3.12/site-packages/
COPY --from=builder /usr/local/bin/ /usr/local/bin/
COPY --from=kubectl /opt/bitnami/kubectl/bin/kubectl /usr/local/bin/
COPY --from=helm /usr/bin/helm /usr/local/bin/
Expand Down
50 changes: 49 additions & 1 deletion apps/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,59 @@ def deploy(options):
try:
port = int(options["appconfig"]["port"])
except Exception:
logger.error("Userid not a number.", exc_info=True)
logger.error("Port not a number.", exc_info=True)
return json.dumps({"status": "failed", "reason": "Port not an integer."})
if port > 9999 or port < 3000:
logger.info("Port outside of allowed range.")
return json.dumps({"status": "failed", "reason": "Port outside of allowed range."})
# check if valid proxyheartbeatrate
if "proxyheartbeatrate" in options["appconfig"]:
try:
proxyheartbeatrate = int(options["appconfig"]["proxyheartbeatrate"])
except Exception:
logger.error("Proxy heartbeat rate not a number.", exc_info=True)
return json.dumps({"status": "failed", "reason": "Proxyheartbeatrate not an integer."})
if proxyheartbeatrate < 1:
logger.info("Heartbeat rate outside of allowed range, must be at least 1.")
return json.dumps(
{"status": "failed", "reason": "Heartbeat rate outside of allowed range, must be at least 1."}
)
else:
options["appconfig"]["proxyheartbeatrate"] = "10000"
# check if valid proxyheartbeattimeout
if "proxyheartbeattimeout" in options["appconfig"]:
try:
proxyheartbeattimeout = int(options["appconfig"]["proxyheartbeattimeout"])
except Exception:
logger.error("Proxy heartbeat timeout not a number.", exc_info=True)
return json.dumps({"status": "failed", "reason": "Proxyheartbeattimeout not an integer."})
if proxyheartbeattimeout < -1 or proxyheartbeattimeout == 0:
logger.info("Heartbeat timeout outside of allowed range, cannot be lower than 0 except for -1.")
return json.dumps(
{
"status": "failed",
"reason": "Heartbeat timeout outside of allowed range, , cannot be lower than 0 except for -1.",
}
)
else:
options["appconfig"]["proxyheartbeattimeout"] = "60000"
# check if valid proxycontainerwaittime
if "proxycontainerwaittime" in options["appconfig"]:
try:
proxycontainerwaittime = int(options["appconfig"]["proxycontainerwaittime"])
except Exception:
logger.error("Proxy container wait time not a number.", exc_info=True)
return json.dumps({"status": "failed", "reason": "Proxycontainerwaittime not an integer."})
if proxycontainerwaittime < 20000:
logger.info("Proxy container wait time outside of allowed range, must be at least 20000.")
return json.dumps(
{
"status": "failed",
"reason": "Proxycontainerwaittime outside of allowed range, must be at least 20000.",
}
)
else:
options["appconfig"]["proxycontainerwaittime"] = "30000"

# Save helm values file for internal reference
unique_filename = "charts/values/{}-{}.yaml".format(str(uuid.uuid4()), str(options["app_name"]))
Expand Down
6 changes: 6 additions & 0 deletions apps/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ def create_app_instance(user, project, app, app_settings, data=[], wait=False):
)
if "userid" not in app_instance.parameters["appconfig"]:
app_instance.parameters["appconfig"]["userid"] = "1000"
if "proxyheartbeatrate" not in app_instance.parameters["appconfig"]:
app_instance.parameters["appconfig"]["proxyheartbeatrate"] = "10000"
if "proxyheartbeattimeout" not in app_instance.parameters["appconfig"]:
app_instance.parameters["appconfig"]["proxyheartbeattimeout"] = "60000"
if "proxycontainerwaittime" not in app_instance.parameters["appconfig"]:
app_instance.parameters["appconfig"]["proxycontainerwaittime"] = "30000"
app_instance.save()
# Saving ReleaseName, status and setting up dependencies
if rel_name_obj:
Expand Down
11 changes: 10 additions & 1 deletion apps/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,11 @@ def get(self, request, project, ai_id):
existing_userid = None
existing_path = None
existing_source_code_url = appinstance.source_code_url
existing_proxyheartbeatrate = None
existing_proxyheartbeattimeout = None
existing_proxycontainerwaittime = None

# Settings for custom app
# Settings for custom app and shinyproxy
if "appconfig" in appinstance.parameters:
appconfig = appinstance.parameters["appconfig"]
existing_userid = appconfig.get("userid", None)
Expand All @@ -227,6 +230,9 @@ def get(self, request, project, ai_id):

if not created_by_admin:
existing_path = existing_path.replace("/home/", "", 1)
existing_proxyheartbeatrate = appconfig.get("proxyheartbeatrate", None)
existing_proxyheartbeattimeout = appconfig.get("proxyheartbeattimeout", None)
existing_proxycontainerwaittime = appconfig.get("proxycontainerwaittime", None)

app = appinstance.app
do_display_description_field = app.category.name is not None and app.category.name.lower() == "serve"
Expand Down Expand Up @@ -271,6 +277,9 @@ def filter_func():
"existing_app_release_name": existing_app_release_name,
"existing_userid": existing_userid,
"existing_source_code_url": existing_source_code_url,
"existing_proxyheartbeatrate": existing_proxyheartbeatrate,
"existing_proxyheartbeattimeout": existing_proxyheartbeattimeout,
"existing_proxycontainerwaittime": existing_proxycontainerwaittime,
}

return render(request, template, context)
Expand Down
2 changes: 1 addition & 1 deletion collections_module/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Generated by Django 4.2.7 on 2024-03-20 15:02

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
Expand Down
2 changes: 1 addition & 1 deletion common/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
EMAIL_ALLOW_REGEX = re.compile(
(
r"^(?:(?!\b(?:student|stud)\b\.)[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)*?" # Subdomain part
+ f"({('|').join([l[0] for l in UNIVERSITIES if l[0] != 'other'])}"
+ f"({('|').join([u[0] for u in UNIVERSITIES if u[0] != 'other'])}"
+ r")\.se" # End of the domain
),
re.IGNORECASE,
Expand Down
2 changes: 1 addition & 1 deletion common/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Generated by Django 4.2.5 on 2023-11-16 08:07

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
Expand Down
2 changes: 1 addition & 1 deletion common/migrations/0002_emailverificationtable.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Generated by Django 4.2.5 on 2023-11-24 13:27

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
Expand Down
9 changes: 4 additions & 5 deletions common/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@


@app.task
def handle_deleted_users():
def handle_deleted_users() -> None:
"""
Handles deleted user accounts.
Expand Down Expand Up @@ -65,7 +65,7 @@ def handle_deleted_users():


@app.task
def alert_pause_dormant_users():
def alert_pause_dormant_users() -> None:
"""
Handles dormant user accounts.
The term dormant is used rather than inactive because of the overuse of the term inactive.
Expand Down Expand Up @@ -152,8 +152,7 @@ def alert_pause_dormant_users():


@app.task(ignore_result=True)
def send_email_task(subject, message, html_message, recipient_list):
logger.info("Sending email to %s", recipient_list)
def send_email_task(subject: str, message: str, html_message: str | None, recipient_list: list[str]) -> None:
send_mail(
subject,
message,
Expand All @@ -164,7 +163,7 @@ def send_email_task(subject, message, html_message, recipient_list):
)


def send_verification_email_task(email, token):
def send_verification_email_task(email: str, token: str) -> None:
html_message = render_to_string(
"registration/verify_email.html",
{
Expand Down
3 changes: 1 addition & 2 deletions common/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.conf import settings
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
from django.core.mail import send_mail
from django.db import transaction
from django.http.response import HttpResponseRedirect
Expand All @@ -21,8 +22,6 @@ class RegistrationCompleteView(TemplateView):


# Sign Up View


class SignUpView(CreateView):
"""
View for user registration
Expand Down
3 changes: 2 additions & 1 deletion cypress/e2e/ui-tests/test-brute-force-login-attempts.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ describe("Test brute force login attempts are blocked", () => {

// Sign out before logging in again
cy.log("Sign out before logging in again")
cy.visit("accounts/logout/")
cy.get('button.btn-profile').click()
cy.get('li.btn-group').find('button').contains("Sign out").click()
cy.get("title").should("have.text", "Logout | SciLifeLab Serve (beta)")

// Repeatedly perform failing login attempts
Expand Down
2 changes: 0 additions & 2 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: '3'

services:
db:
container_name: db
Expand Down
17 changes: 16 additions & 1 deletion fixtures/apps_fixtures.json
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@
{
"fields": {
"category": "serve",
"chart": "ghcr.io/scilifelabdatacentre/serve-charts/shinyproxy:1.0.0",
"chart": "ghcr.io/scilifelabdatacentre/serve-charts/shinyproxy:1.1.0",
"created_on": "2023-08-25T21:34:37.815Z",
"description": "",
"logo": "shinyapp-logo.svg",
Expand All @@ -708,6 +708,21 @@
"default": "3838",
"title": "Port",
"type": "number"
},
"proxyheartbeatrate": {
"default": "10000",
"title": "Proxy heartbeat rate",
"type": "number"
},
"proxyheartbeattimeout": {
"default": "60000",
"title": "Proxy heartbeat timeout",
"type": "number"
},
"proxycontainerwaittime": {
"default": "30000",
"title": "Proxy container wait time",
"type": "number"
}
},
"default_values": {
Expand Down
2 changes: 1 addition & 1 deletion manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import sys


def main():
def main() -> None:
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "studio.settings")
try:
Expand Down
2 changes: 1 addition & 1 deletion monitor/dash_demo.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
import requests # type: ignore
import requests
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate
from django_plotly_dash import DjangoDash
Expand Down
5 changes: 4 additions & 1 deletion news/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from typing import Any

import markdown
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render

from .models import NewsObject


def news(request):
def news(request: HttpRequest) -> HttpResponse:
news_objects = NewsObject.objects.all().order_by("-created_on")
for news in news_objects:
news.body_html = markdown.markdown(news.body)
Expand Down
Loading

0 comments on commit 2d769be

Please sign in to comment.