Skip to content

Commit

Permalink
feat: validate server options (#529)
Browse files Browse the repository at this point in the history
* feat: add jsonschema validation for server options in values.yaml

* feat: add specific schemas for server options in notebooks api

* fix: validate server options values are valid when launching notebook

Co-authored-by: Andreas Bleuler <ableuler@users.noreply.github.com>
  • Loading branch information
olevski and ableuler committed Feb 3, 2021
1 parent 77ac02b commit 03d20e2
Show file tree
Hide file tree
Showing 6 changed files with 340 additions and 31 deletions.
208 changes: 208 additions & 0 deletions helm-chart/renku-notebooks/values.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
{
"$schema": "https://json-schema.org/draft-07/schema#",
"definitions": {
"informationAmount": {
"type": "string",
"pattern": "^(?:[1-9][0-9]*|[0-9]\\.[0-9]*)[EPTGMK][i]{0,1}$"
},
"cpuRequest": {
"type": "number",
"exclusiveMinimum": 0.0,
"multipleOf": 0.001
},
"gpuRequest": {
"type": "integer",
"minimum": 0.0
},
"serverOption": {
"type": "object",
"properties": {
"order": {
"type": "integer",
"minimum": 1
},
"displayName": {
"type": "string"
}
},
"required": [
"order",
"displayName"
]
},
"serverOptionEnumStr": {
"allOf": [
{
"$ref": "#/definitions/serverOption"
},
{
"properties": {
"order": true,
"displayName": true,
"type": {
"type": "string",
"pattern": "^enum$"
},
"default": {
"type": "string"
},
"options": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"uniqueItems": true
}
},
"required": [
"type",
"default",
"options"
],
"additionalProperties": false
}
]
},
"serverOptionBool": {
"allOf": [
{
"$ref": "#/definitions/serverOption"
},
{
"properties": {
"order": true,
"displayName": true,
"type": {
"type": "string",
"pattern": "^boolean$"
},
"default": {
"type": "boolean"
}
},
"required": [
"type",
"default"
],
"additionalProperties": false
}
]
},
"serverOptionGpu": {
"allOf": [
{
"$ref": "#/definitions/serverOption"
},
{
"properties": {
"order": true,
"displayName": true,
"type": {
"type": "string",
"pattern": "^enum$"
},
"default": { "$ref": "#/definitions/gpuRequest" },
"options": {
"type": "array",
"items": { "$ref": "#/definitions/gpuRequest" },
"minItems": 1,
"uniqueItems": true
}
},
"required": [
"type",
"default",
"options"
],
"additionalProperties": false
}
]
},
"serverOptionCpu": {
"allOf": [
{
"$ref": "#/definitions/serverOption"
},
{
"properties": {
"order": true,
"displayName": true,
"type": {
"type": "string",
"pattern": "^enum$"
},
"default": { "$ref": "#/definitions/cpuRequest" },
"options": {
"type": "array",
"items": { "$ref": "#/definitions/cpuRequest" },
"minItems": 1,
"uniqueItems": true
}
},
"required": [
"type",
"default",
"options"
],
"additionalProperties": false
}
]
},
"serverOptionMemory": {
"allOf": [
{
"$ref": "#/definitions/serverOptionEnumStr"
},
{
"properties": {
"order": true,
"displayName": true,
"type": {
"type": "string",
"pattern": "^enum$"
},
"default": { "$ref": "#/definitions/informationAmount" },
"options": {
"type": "array",
"items": { "$ref": "#/definitions/informationAmount" },
"minItems": 1,
"uniqueItems": true
}
},
"required": [
"type",
"default",
"options"
],
"additionalProperties": false
}
]
}
},
"properties": {
"serverOptions": {
"description": "Options provided to the user in the UI when launching a server.",
"properties": {
"defaultUrl": { "$ref": "#/definitions/serverOptionEnumStr" },
"cpu_request": { "$ref": "#/definitions/serverOptionCpu" },
"mem_request": { "$ref": "#/definitions/serverOptionMemory" },
"lfs_auto_fetch": { "$ref": "#/definitions/serverOptionBool" },
"gpu_request": { "$ref": "#/definitions/serverOptionGpu" }
},
"required": [
"defaultUrl",
"cpu_request",
"mem_request",
"lfs_auto_fetch"
],
"type": "object",
"additionalProperties": false
}
},
"required": [
"serverOptions"
],
"title": "Values",
"type": "object"
}
11 changes: 11 additions & 0 deletions renku_notebooks/api/custom_fields.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import List, Mapping, Any
from marshmallow import fields
from marshmallow.exceptions import ValidationError
import re


class UnionField(fields.Field):
Expand Down Expand Up @@ -48,3 +49,13 @@ def _deserialize(
errors.append(error.messages)

raise ValidationError(errors)


serverOptionCpuValue = fields.Number(
validate=lambda x: x > 0.0 and (x % 1 >= 0.001 or x % 1 == 0.0), required=True,
)
serverOptionMemoryValue = fields.String(
validate=lambda x: re.match(r"^(?:[1-9][0-9]*|[0-9]\.[0-9]*)[EPTGMK][i]{0,1}$", x)
is not None,
required=True,
)
14 changes: 3 additions & 11 deletions renku_notebooks/api/notebooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
ServerOptions,
FailedParsing,
)
from ..util.misc import read_server_options_file


bp = Blueprint("notebooks_blueprint", __name__, url_prefix=config.SERVICE_PREFIX)
Expand Down Expand Up @@ -140,7 +141,7 @@ def launch_notebook(

# process the server options
# server options from system configuration
server_options_defaults = _read_server_options_file()
server_options_defaults = read_server_options_file()

# process the requested options and set others to defaults from config
server_options.setdefault(
Expand Down Expand Up @@ -351,7 +352,7 @@ def stop_server(user, forced, server_name):
@authenticated
def server_options(user):
"""Return a set of configurable server options."""
server_options = _read_server_options_file()
server_options = read_server_options_file()

# TODO: append image-specific options to the options json
return jsonify(server_options)
Expand Down Expand Up @@ -396,12 +397,3 @@ def server_logs(user, server_name):
jsonify({"messages": {"error": "Cannot find server"}}), 404
)
return response


def _read_server_options_file():
server_options_file = os.getenv(
"NOTEBOOKS_SERVER_OPTIONS_PATH", "/etc/renku-notebooks/server_options.json"
)
with open(server_options_file) as f:
server_options = json.load(f)
return server_options
Loading

0 comments on commit 03d20e2

Please sign in to comment.