Skip to content

Commit

Permalink
Rename request inputs to session parameters.
Browse files Browse the repository at this point in the history
  • Loading branch information
GrahamDumpleton committed Apr 14, 2023
1 parent 7704e2e commit b7f5ac9
Show file tree
Hide file tree
Showing 14 changed files with 97 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -816,18 +816,7 @@ spec:
type: string
value:
type: string
patches:
type: object
x-kubernetes-preserve-unknown-fields: true
objects:
type: array
items:
type: object
x-kubernetes-preserve-unknown-fields: true
request:
type: object
properties:
inputs:
parameters:
type: array
items:
type: object
Expand All @@ -836,9 +825,20 @@ spec:
properties:
name:
type: string
default:
value:
type: string
default: ""
generate:
type: string
from:
type: string
patches:
type: object
x-kubernetes-preserve-unknown-fields: true
objects:
type: array
items:
type: object
x-kubernetes-preserve-unknown-fields: true
status:
type: object
x-kubernetes-preserve-unknown-fields: true
Expand Down
1 change: 1 addition & 0 deletions training-portal/requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ requests==2.28.1
django-csp==3.7
kopf[full-auth]==1.35.6
pykube-ng==22.9.0
rstr==3.2.0

black==22.3.0
pip-tools==6.6.2
Expand Down
10 changes: 5 additions & 5 deletions training-portal/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# This file is autogenerated by pip-compile with python 3.10
# To update, run:
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile requirements.in
#
Expand Down Expand Up @@ -133,6 +133,8 @@ requests-oauthlib==1.3.1
# via kubernetes
rsa==4.8
# via google-auth
rstr==3.2.0
# via -r requirements.in
six==1.16.0
# via
# google-auth
Expand All @@ -141,9 +143,7 @@ six==1.16.0
sqlparse==0.4.2
# via django
tomli==2.0.1
# via
# black
# pep517
# via pep517
typing-extensions==4.2.0
# via kopf
urllib3==1.26.9
Expand Down
2 changes: 1 addition & 1 deletion training-portal/src/project/apps/workshops/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ class SessionAdmin(admin.ModelAdmin):
"started",
"expires",
"url_link",
"inputs",
"params",
]

def has_add_permission(self, request):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,13 @@ def activate_workshop_environment(resource):
workshop.tags = details.get("spec.tags", []).obj()
workshop.logo = details.get("spec.logo", "")
workshop.url = details.get("spec.url", "")
workshop.inputs = details.get("spec.request.inputs", []).obj()
workshop.params = details.get("spec.session.parameters", []).obj()

content = dict(details.get("spec.content", {}).obj())

image = content.get("image", "")
files = content.get("files", "")
url = details.get("spec.session.applications.workshop.url", "")
inputs = details.get("spec.request.inputs", [])

if url:
content["url"] = url
Expand Down
52 changes: 30 additions & 22 deletions training-portal/src/project/apps/workshops/manager/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from itertools import islice

import pykube
import rstr

from django.conf import settings
from django.contrib.auth import get_user_model
Expand All @@ -28,34 +29,41 @@
api = pykube.HTTPClient(pykube.KubeConfig.from_env())


def resolve_request_inputs(workshop, params):
default_inputs = {}
def resolve_request_params(workshop, params):
default_params = {}

for item in workshop.inputs:
key = item.get("name", "")
value = item.get("default", "")
def default_value(param):
if "value" in param:
return param["value"]
elif "generate" in param and param["generate"] == "expression":
return rstr.xeger(param.get("from", ""))
else:
return ""

for item in workshop.params:
name = item.get("name", "")

if key:
default_inputs[key] = value
if name:
default_params[name] = default_value(item)

final_inputs = dict(default_inputs)
final_params = dict(default_params)

for item in params.get("inputs", []):
key = item.get("name", "")
for item in params:
name = item.get("name", "")
value = item.get("value", "")

if key and key in final_inputs:
final_inputs[key] = value
if name and name in final_params:
final_params[name] = value

return final_inputs
return final_params


def create_inputs_resource(session):
def create_request_resource(session):
secret_body = {
"apiVersion": "v1",
"kind": "Secret",
"metadata": {
"name": f"{session.name}-inputs",
"name": f"{session.name}-params",
"namespace": session.environment.name,
"labels": {
f"training.{settings.OPERATOR_API_GROUP}/component": "environment",
Expand All @@ -77,7 +85,7 @@ def create_inputs_resource(session):
"data": {},
}

for key, value in session.inputs.items():
for key, value in session.params.items():
secret_body["data"][key] = base64.b64encode(value.encode("UTF-8")).decode("UTF-8")

pykube.Secret(api, secret_body).create()
Expand Down Expand Up @@ -230,7 +238,7 @@ def create_workshop_session(name):
if session.token:
session.mark_as_waiting()
else:
create_inputs_resource(session)
create_request_resource(session)
session.mark_as_running()
else:
session.mark_as_waiting()
Expand Down Expand Up @@ -575,7 +583,7 @@ def allocate_session_for_user(environment, user, token, timeout=None, params={})
# confirmation is needed so can reclaim a session which was abandoned
# immediately due to not being accessed.

session.inputs = resolve_request_inputs(session.environment.workshop, params)
session.params = resolve_request_params(session.environment.workshop, params)

if token:
update_session_status(session.name, "Allocating")
Expand All @@ -584,7 +592,7 @@ def allocate_session_for_user(environment, user, token, timeout=None, params={})
else:
update_session_status(session.name, "Allocated")
report_analytics_event(session, "Session/Started")
create_inputs_resource(session)
create_request_resource(session)
session.mark_as_running(user)

# See if we need to create a new reserved session to replace the one which
Expand Down Expand Up @@ -618,7 +626,7 @@ def create_session_for_user(environment, user, token, timeout=None, params={}):
if portal.sessions_maximum == 0:
session = create_new_session(environment)

session.inputs = resolve_request_inputs(session.environment.workshop, params)
session.params = resolve_request_params(session.environment.workshop, params)

if token:
update_session_status(session.name, "Allocating")
Expand Down Expand Up @@ -647,7 +655,7 @@ def create_session_for_user(environment, user, token, timeout=None, params={}):
if portal.active_sessions_count() < portal.sessions_maximum:
session = create_new_session(environment)

session.inputs = resolve_request_inputs(session.environment.workshop, params)
session.params = resolve_request_params(session.environment.workshop, params)

if token:
update_session_status(session.name, "Allocating")
Expand Down Expand Up @@ -683,7 +691,7 @@ def create_session_for_user(environment, user, token, timeout=None, params={}):

session = create_new_session(environment)

session.inputs = resolve_request_inputs(session.environment.workshop, params)
session.params = resolve_request_params(session.environment.workshop, params)

if token:
update_session_status(session.name, "Allocating")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Django 3.2.18 on 2023-04-14 01:38

from django.db import migrations, models
import project.apps.workshops.models


class Migration(migrations.Migration):

dependencies = [
('workshops', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='session',
name='params',
field=project.apps.workshops.models.JSONField(default={}, verbose_name='session params'),
),
migrations.AddField(
model_name='session',
name='uid',
field=models.CharField(default='', max_length=255, verbose_name='resource uid'),
),
migrations.AddField(
model_name='workshop',
name='params',
field=project.apps.workshops.models.JSONField(default=[], verbose_name='session parameters'),
),
migrations.AlterField(
model_name='session',
name='id',
field=models.CharField(max_length=64, verbose_name='session id'),
),
]

This file was deleted.

This file was deleted.

This file was deleted.

4 changes: 2 additions & 2 deletions training-portal/src/project/apps/workshops/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ class Workshop(models.Model):
url = models.CharField(max_length=255)
content = JSONField(default={})
ingresses = JSONField(verbose_name="session ingresses", default=[])
inputs = JSONField(verbose_name="request inputs", default=[])
params = JSONField(verbose_name="session parameters", default=[])


class EnvironmentState(enum.IntEnum):
Expand Down Expand Up @@ -608,7 +608,7 @@ class Session(models.Model):
expires = models.DateTimeField(null=True, blank=True)
token = models.CharField(max_length=256, null=True, blank=True)
url = models.URLField(verbose_name="session url", null=True)
inputs = JSONField(verbose_name="session inputs", default={})
params = JSONField(verbose_name="session params", default={})

def environment_name(self):
return self.environment.name
Expand Down
11 changes: 5 additions & 6 deletions training-portal/src/project/apps/workshops/views/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ def environment_request(request, name):
# Extract any request parameters from the request body for using in late
# binding of workshop session configuration.

params = {}
params = []

if request.body:
try:
Expand All @@ -217,12 +217,12 @@ def environment_request(request, name):
if not isinstance(request_data, dict):
return HttpResponseBadRequest("Malformed JSON request payload")

request_inputs = request_data.get("inputs", [])
request_params = request_data.get("parameters", [])

if not isinstance(request_inputs, list):
if not isinstance(request_params, list):
return HttpResponseBadRequest("Malformed JSON request payload")

for value in request_inputs:
for value in request_params:
key = value.get("name", "")
item = value.get("item", "")

Expand All @@ -233,8 +233,7 @@ def environment_request(request, name):
else:
return HttpResponseBadRequest("Malformed JSON request payload")

if request_inputs:
params["inputs"] = request_inputs
params = request_params

# Check whether a user already has an existing session allocated
# to them, in which case return that rather than create a new one.
Expand Down
Loading

0 comments on commit b7f5ac9

Please sign in to comment.