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

Feature/638 #642

Merged
merged 14 commits into from
Nov 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions applications/jupyterhub/deploy/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ harness:
- accounts
build:
- cloudharness-base
quotas:
# sets the maximum number of (included named) servers open concurrently (int)
quota-ws-open: 3
# sets the cpu guaranteed on a single workspace in CPU units (float)
quota-ws-guaranteecpu: 0.05
# sets the cpu limit on a single workspace in CPU units (float)
quota-ws-maxcpu: 0.4
# sets the memory guaranteed on a single workspace in Gb units (float)
quota-ws-guaranteemem: 0.1
# sets the memory limit on a single workspace in Gb units (float)
quota-ws-maxmem: 0.5
# sets the storage dedicated to the user data in Gb units (float)
quota-storage-max: 1.25

# fullnameOverride and nameOverride distinguishes blank strings, null values,
# and non-blank strings. For more details, see the configuration reference.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
handler.setLevel(logging.DEBUG)
logging.getLogger().addHandler(handler)

from cloudharness.applications import get_configuration
from cloudharness.auth.quota import get_user_quotas


class PodSpawnException(Exception):
pass

Expand All @@ -16,13 +20,22 @@ def harness_hub():
"""Wraps the method to change spawner configuration"""
KubeSpawner.get_pod_manifest_base = KubeSpawner.get_pod_manifest
KubeSpawner.get_pod_manifest = spawner_pod_manifest
KubeSpawner.get_pvc_manifest_base = KubeSpawner.get_pvc_manifest
KubeSpawner.get_pvc_manifest = spawner_pvc_manifest


def spawner_pod_manifest(self: KubeSpawner):
print("Cloudharness: changing pod manifest")
change_pod_manifest(self)

return KubeSpawner.get_pod_manifest_base(self)


def spawner_pvc_manifest(self: KubeSpawner):
print("Cloudharness: changing pvc manifest")
change_pvc_manifest(self)
return KubeSpawner.get_pvc_manifest_base(self)


def affinity_spec(key, value):
return {

Expand All @@ -39,6 +52,7 @@ def affinity_spec(key, value):
'topologyKey': 'kubernetes.io/hostname'
}


def set_user_volume_affinity(self: KubeSpawner):
# Add labels to use for affinity
labels = {
Expand All @@ -50,8 +64,47 @@ def set_user_volume_affinity(self: KubeSpawner):

for key, value in labels.items():
self.pod_affinity_required.append(affinity_spec(key, value))


def set_key_value(self, key, value, unit=None):
if value:
if unit:
print(f"setting key {key} to {value}{unit}")
setattr(self, key, f"{value}{unit}")
else:
print(f"setting key {key} to {value}")
setattr(self, key, value)


def change_pvc_manifest(self: KubeSpawner):
try:
# check user quotas
application_config = get_configuration("jupyterhub")
user_quotas = get_user_quotas(
application_config=application_config,
user_id=self.user.name)
set_key_value(self, key="storage_capacity", value=user_quotas.get("quota-storage-max"), unit="Gi")
except Exception as e:
logging.error("Harness error changing pvc manifest", exc_info=True)

def change_pod_manifest(self: KubeSpawner):
# check user quotas
application_config = get_configuration("jupyterhub")
user_quotas = get_user_quotas(
application_config=application_config,
user_id=self.user.name)

quota_ws_open = user_quotas.get("quota-ws-open")
if quota_ws_open:
# get user number of pods running
num_of_pods = len(list(self.user.all_spawners(include_default=True)))
if num_of_pods > int(quota_ws_open):
raise PodSpawnException(
"User {} already has the maximum of {} servers."
" One must be deleted before a new server can be started".format(
self.user.name, quota_ws_open
),
)

try:
subdomain = self.handler.request.host.split(str(self.config['domain']))[0][0:-1]
Expand Down Expand Up @@ -116,6 +169,13 @@ def change_pod_manifest(self: KubeSpawner):
raise ValueError("Unrecognized value for matchNodePurpose: %r" % match_node_purpose)
except:
logging.error("Error loading Spawner extra configuration", exc_info=True)

# set user quota cpu/mem usage if value has a "value" else don't change the value
set_key_value(self, key="cpu_guarantee", value=user_quotas.get("quota-ws-guaranteecpu"))
set_key_value(self, key="cpu_limit", value=user_quotas.get("quota-ws-maxcpu"))
set_key_value(self, key="mem_guarantee", value=user_quotas.get("quota-ws-guaranteemem"), unit="G")
set_key_value(self, key="mem_limit", value=user_quotas.get("quota-ws-maxmem"), unit="G")

# check if there is an applicationHook defined in the values.yaml
# if so then execute the applicationHook function with "self" as parameter
#
Expand All @@ -131,7 +191,7 @@ def change_pod_manifest(self: KubeSpawner):
f(self=self)
break

except TooManyPodsException as e:
except PodSpawnException as e:
raise e
except Exception as e:
logging.error("Harness error changing manifest", exc_info=True)
49 changes: 40 additions & 9 deletions docs/model/ApiTestsConfig.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,46 @@
# ApiTestsConfig
# cloudharness_model.model.api_tests_config.ApiTestsConfig

## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
dict, frozendict.frozendict, | frozendict.frozendict, | |

### Dictionary Keys
Key | Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | ------------- | -------------
**[checks](#checks)** | list, tuple, | tuple, | One of the Schemathesis checks: - not_a_server_error. The response has 5xx HTTP status; - status_code_conformance. The response status is not defined in the API schema; - content_type_conformance. The response content type is not defined in the API schema; - response_schema_conformance. The response content does not conform to the schema defined for this specific response; - response_headers_conformance. The response headers does not contain all defined headers. |
**autotest** | bool, | BoolClass, | Specify whether to run the common smoke tests |
**enabled** | bool, | BoolClass, | Enables api tests for this application (default: false) |
**[runParams](#runParams)** | list, tuple, | tuple, | Additional schemathesis parameters | [optional]
**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional]

# checks

One of the Schemathesis checks: - not_a_server_error. The response has 5xx HTTP status; - status_code_conformance. The response status is not defined in the API schema; - content_type_conformance. The response content type is not defined in the API schema; - response_schema_conformance. The response content does not conform to the schema defined for this specific response; - response_headers_conformance. The response headers does not contain all defined headers.

## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
list, tuple, | tuple, | One of the Schemathesis checks: - not_a_server_error. The response has 5xx HTTP status; - status_code_conformance. The response status is not defined in the API schema; - content_type_conformance. The response content type is not defined in the API schema; - response_schema_conformance. The response content does not conform to the schema defined for this specific response; - response_headers_conformance. The response headers does not contain all defined headers. |

### Tuple Items
Class Name | Input Type | Accessed Type | Description | Notes
------------- | ------------- | ------------- | ------------- | -------------
items | str, | str, | |

# runParams

Additional schemathesis parameters

## Properties
Name | Type | Description | Notes
## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
**enabled** | **bool** | Enables api tests for this application (default: false) |
**autotest** | **bool** | Specify whether to run the common smoke tests |
**checks** | **[str]** | One of the Schemathesis checks: - not_a_server_error. The response has 5xx HTTP status; - status_code_conformance. The response status is not defined in the API schema; - content_type_conformance. The response content type is not defined in the API schema; - response_schema_conformance. The response content does not conform to the schema defined for this specific response; - response_headers_conformance. The response headers does not contain all defined headers. |
**run_params** | **[str]** | Additional schemathesis parameters | [optional]
**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional]
list, tuple, | tuple, | Additional schemathesis parameters |

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
### Tuple Items
Class Name | Input Type | Accessed Type | Description | Notes
------------- | ------------- | ------------- | ------------- | -------------
items | str, | str, | |

[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md)

45 changes: 38 additions & 7 deletions docs/model/ApplicationAccountsConfig.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,44 @@
# ApplicationAccountsConfig
# cloudharness_model.model.application_accounts_config.ApplicationAccountsConfig

## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
dict, frozendict.frozendict, | frozendict.frozendict, | |

### Dictionary Keys
Key | Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | ------------- | -------------
**[roles](#roles)** | list, tuple, | tuple, | Specify roles to be created in this deployment specific for this application | [optional]
**[users](#users)** | list, tuple, | tuple, | Defines test users to be added to the deployment, specific for this application | [optional]
**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional]

# roles

Specify roles to be created in this deployment specific for this application

## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
list, tuple, | tuple, | Specify roles to be created in this deployment specific for this application |

### Tuple Items
Class Name | Input Type | Accessed Type | Description | Notes
------------- | ------------- | ------------- | ------------- | -------------
items | str, | str, | |

# users

Defines test users to be added to the deployment, specific for this application

## Properties
Name | Type | Description | Notes
## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
**roles** | **[str]** | Specify roles to be created in this deployment specific for this application | [optional]
**users** | [**[ApplicationUser]**](ApplicationUser.md) | Defines test users to be added to the deployment, specific for this application | [optional]
**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional]
list, tuple, | tuple, | Defines test users to be added to the deployment, specific for this application |

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
### Tuple Items
Class Name | Input Type | Accessed Type | Description | Notes
------------- | ------------- | ------------- | ------------- | -------------
[**ApplicationUser**](ApplicationUser.md) | [**ApplicationUser**](ApplicationUser.md) | [**ApplicationUser**](ApplicationUser.md) | |

[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md)

16 changes: 10 additions & 6 deletions docs/model/ApplicationConfig.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# ApplicationConfig
# cloudharness_model.model.application_config.ApplicationConfig

Place here the values to configure your application helm templates.

## Properties
Name | Type | Description | Notes
## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
**harness** | [**ApplicationHarnessConfig**](ApplicationHarnessConfig.md) | |
**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional]
dict, frozendict.frozendict, | frozendict.frozendict, | Place here the values to configure your application helm templates. |

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
### Dictionary Keys
Key | Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | ------------- | -------------
**harness** | [**ApplicationHarnessConfig**](ApplicationHarnessConfig.md) | [**ApplicationHarnessConfig**](ApplicationHarnessConfig.md) | |
**any_string_name** | dict, frozendict.frozendict, str, date, datetime, uuid.UUID, int, float, decimal.Decimal, bool, None, list, tuple, bytes, io.FileIO, io.BufferedReader, | frozendict.frozendict, str, decimal.Decimal, BoolClass, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional]

[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md)

61 changes: 53 additions & 8 deletions docs/model/ApplicationDependenciesConfig.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,59 @@
# ApplicationDependenciesConfig
# cloudharness_model.model.application_dependencies_config.ApplicationDependenciesConfig

## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
dict, frozendict.frozendict, | frozendict.frozendict, | |

### Dictionary Keys
Key | Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | ------------- | -------------
**[hard](#hard)** | list, tuple, | tuple, | Hard dependencies indicate that the application may not start without these other applications. | [optional]
**[soft](#soft)** | list, tuple, | tuple, | Soft dependencies indicate that the application will work partially without these other applications. | [optional]
**[build](#build)** | list, tuple, | tuple, | Hard dependencies indicate that the application Docker image build requires these base/common images | [optional]
**any_string_name** | dict, frozendict.frozendict, str, date, datetime, int, float, bool, decimal.Decimal, None, list, tuple, bytes, io.FileIO, io.BufferedReader | frozendict.frozendict, str, BoolClass, decimal.Decimal, NoneClass, tuple, bytes, FileIO | any string name can be used but the value must be the correct type | [optional]

# hard

Hard dependencies indicate that the application may not start without these other applications.

## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
list, tuple, | tuple, | Hard dependencies indicate that the application may not start without these other applications. |

### Tuple Items
Class Name | Input Type | Accessed Type | Description | Notes
------------- | ------------- | ------------- | ------------- | -------------
items | str, | str, | |

# soft

Soft dependencies indicate that the application will work partially without these other applications.

## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
list, tuple, | tuple, | Soft dependencies indicate that the application will work partially without these other applications. |

### Tuple Items
Class Name | Input Type | Accessed Type | Description | Notes
------------- | ------------- | ------------- | ------------- | -------------
items | str, | str, | |

# build

Hard dependencies indicate that the application Docker image build requires these base/common images

## Properties
Name | Type | Description | Notes
## Model Type Info
Input Type | Accessed Type | Description | Notes
------------ | ------------- | ------------- | -------------
**hard** | **[str]** | Hard dependencies indicate that the application may not start without these other applications. | [optional]
**soft** | **[str]** | Soft dependencies indicate that the application will work partially without these other applications. | [optional]
**build** | **[str]** | Hard dependencies indicate that the application Docker image build requires these base/common images | [optional]
**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional]
list, tuple, | tuple, | Hard dependencies indicate that the application Docker image build requires these base/common images |

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
### Tuple Items
Class Name | Input Type | Accessed Type | Description | Notes
------------- | ------------- | ------------- | ------------- | -------------
items | str, | str, | |

[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md)

Loading