Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: validate server options #529

Merged
merged 10 commits into from
Feb 3, 2021
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(
ableuler marked this conversation as resolved.
Show resolved Hide resolved
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)
ableuler marked this conversation as resolved.
Show resolved Hide resolved
is not None,
required=True,
)
83 changes: 64 additions & 19 deletions renku_notebooks/api/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@
import collections

from .. import config
from .custom_fields import UnionField
from .custom_fields import (
serverOptionCpuValue,
serverOptionMemoryValue,
)


class LaunchNotebookRequestServerOptions(Schema):
defaultUrl = fields.String(required=True)
cpu_request = serverOptionCpuValue
mem_request = serverOptionMemoryValue
lfs_auto_fetch = fields.Bool(required=True)
gpu_request = fields.Integer(strict=True, validate=lambda x: x >= 0)


class LaunchNotebookRequest(Schema):
Expand All @@ -14,8 +25,8 @@ class LaunchNotebookRequest(Schema):
commit_sha = fields.Str(required=True)
notebook = fields.Str(missing=None)
image = fields.Str(missing=None)
server_options = fields.Dict(
keys=fields.Str(), missing={}, data_key="serverOptions"
server_options = fields.Nested(
LaunchNotebookRequestServerOptions(), missing={}, data_key="serverOptions"
)


Expand Down Expand Up @@ -127,20 +138,54 @@ class FailedParsing(Schema):
)


class ServerOptionsOption(Schema):
class ServerOptionBase(Schema):
displayName = fields.Str(required=True)
order = fields.Int(required=True)
type = fields.String(validate=lambda x: x in ["boolean", "enum"], required=True,)


class ServerOptionCpu(ServerOptionBase):
"""The schema used to describe a single option for the server_options endpoint."""

default = serverOptionCpuValue
options = fields.List(
serverOptionCpuValue, validate=lambda x: len(x) >= 1, required=True
)


class ServerOptionMemory(ServerOptionBase):
"""The schema used to describe a single option for the server_options endpoint."""

default = UnionField(
[
fields.Str(required=True),
fields.Number(required=True),
fields.Bool(required=True),
]
default = serverOptionMemoryValue
options = fields.List(
serverOptionMemoryValue, validate=lambda x: len(x) >= 1, required=True
)
displayName = fields.Str(required=True)
order = fields.Int(required=True)
type = fields.Str(required=True)
options = fields.List(UnionField([fields.Str(), fields.Number()]))


class ServerOptionGpu(ServerOptionBase):
"""The schema used to describe a single option for the server_options endpoint."""

default = fields.Integer(strict=True, validate=lambda x: x >= 0, required=True)
options = fields.List(
fields.Integer(strict=True, validate=lambda x: x >= 0),
validate=lambda x: len(x) >= 1,
required=True,
)


class ServerOptionString(ServerOptionBase):
"""The schema used to describe a single option for the server_options endpoint."""

default = fields.String(required=True)
options = fields.List(
fields.String(), validate=lambda x: len(x) >= 1, required=True
)


class ServerOptionBool(ServerOptionBase):
"""The schema used to describe a single option for the server_options endpoint."""

default = fields.Bool(required=True)


class ServerOptions(Schema):
Expand All @@ -149,11 +194,11 @@ class ServerOptions(Schema):
launching a jupyterhub server.
"""

cpu_request = fields.Nested(ServerOptionsOption())
defaultUrl = fields.Nested(ServerOptionsOption())
gpu_request = fields.Nested(ServerOptionsOption())
lfs_auto_fetch = fields.Nested(ServerOptionsOption())
mem_request = fields.Nested(ServerOptionsOption())
cpu_request = fields.Nested(ServerOptionCpu(), required=True)
defaultUrl = fields.Nested(ServerOptionString(), required=True)
gpu_request = fields.Nested(ServerOptionGpu())
lfs_auto_fetch = fields.Nested(ServerOptionBool(), required=True)
mem_request = fields.Nested(ServerOptionMemory(), required=True)


class ServerLogs(Schema):
Expand Down