Skip to content
Open
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
2 changes: 0 additions & 2 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
**IMPORTANT: Please attach or create an issue after submitting a Pull Request.

<!--start_release_notes-->
### Release notes feature title
... Release notes description / summary
Expand Down
116 changes: 107 additions & 9 deletions .github/workflows/minikube-cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ on:
description: 'If set, pip install ods-tools branch [git ref]'
required: false
type: string
piwind_branch:
description: 'PiWind branch [git ref] (default=main)'
required: false
type: string
workflow_dispatch:
inputs:
oasislmf_branch:
Expand All @@ -21,17 +25,29 @@ on:
description: 'If set, pip install ods-tools branch [git ref]'
required: false
type: string
piwind_branch:
description: 'PiWind branch [git ref] (default=main)'
required: false
type: string

jobs:
minikube:
runs-on: ubuntu-latest
env:
OASIS_MODEL_DATA_DIR: /shared-fs/PIWIND
ACTIONS_STEP_DEBUG: true
oasislmf_branch: ${{ github.event_name != 'workflow_dispatch' && 'main' || inputs.oasislmf_branch }}
ods_branch: ${{ github.event_name != 'workflow_dispatch' && 'main' || inputs.ods_branch }}
piwind_branch: ${{ github.event_name != 'workflow_dispatch' && 'main' || inputs.piwind_branch }}

steps:
- name: Clone OasisPiWind model data
run: |
git clone https://github.com/OasisLMF/OasisPiWind.git /tmp/piwind
if [[ -z "${{ env.piwind_branch }}" ]]; then
git clone https://github.com/OasisLMF/OasisPiWind.git /tmp/piwind
else
git clone -b ${{ env.piwind_branch }} https://github.com/OasisLMF/OasisPiWind.git /tmp/piwind
fi

- name: Set OASIS_MODEL_DATA_DIR env
run: echo "OASIS_MODEL_DATA_DIR=/tmp/piwind" >> $GITHUB_ENV
Expand All @@ -42,12 +58,15 @@ jobs:
- name: Start Minikube
uses: medyagh/setup-minikube@latest

# - name: Enable metrics
# run: minikube addons enable metrics-server

- name: Build Docker images
run: |
eval $(minikube docker-env)

docker build -f Dockerfile.api_server --build-arg ods_tools_branch=${{ inputs.ods_branch }} --build-arg oasislmf_branch=${{ inputs.oasislmf_branch }} -t coreoasis/api_server:dev .
docker build -f Dockerfile.model_worker --build-arg ods_tools_branch=${{ inputs.ods_branch }} --build-arg oasislmf_branch=${{ inputs.oasislmf_branch }} -t coreoasis/model_worker:dev .
docker build -f Dockerfile.api_server --build-arg ods_tools_branch=${{ env.ods_branch }} --build-arg oasislmf_branch=${{ env.oasislmf_branch }} -t coreoasis/api_server:dev .
docker build -f Dockerfile.model_worker --build-arg ods_tools_branch=${{ env.ods_branch }} --build-arg oasislmf_branch=${{ env.oasislmf_branch }} -t coreoasis/model_worker:dev .

pushd kubernetes/worker-controller
docker build -t coreoasis/worker_controller:dev .
Expand Down Expand Up @@ -79,7 +98,7 @@ jobs:
uses: actions/checkout@v3
with:
repository: OasisLMF/OasisPiWind
ref: main
ref: ${{ env.piwind_branch }}
- name: Start Minikube Tunnel
run: |
nohup minikube tunnel > /dev/null 2>&1 &
Expand All @@ -103,12 +122,26 @@ jobs:

- name: Authenticate
run: |
USERNAME_OR_ID=$(kubectl get secret oasis-service-account-credentials -o jsonpath="{.data.username_or_id}" | base64 -d)
PASSWORD_OR_SECRET=$(kubectl get secret oasis-service-account-credentials -o jsonpath="{.data.password_or_secret}" | base64 -d)
USE_OIDC=$(kubectl get secret oasis-service-account-credentials -o jsonpath="{.data.use_oidc}" | base64 -d)

echo "Delay to wait for authentication server to start"
sleep 60
delay=1
for i in {1..8}; do
delay=$((delay * 2))
RESPONSE=$(curl -s -k -X POST https://ui.oasis.local/api/access_token/ \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "password"}')
if [ "$USE_OIDC" = "true" ]; then
echo "Using OIDC authentication"
RESPONSE=$(curl -s -k -X POST https://ui.oasis.local/api/access_token/ \
-H "Content-Type: application/json" \
-d "{\"client_id\": \"$USERNAME_OR_ID\", \"client_secret\": \"$PASSWORD_OR_SECRET\"}")
else
echo "Using Simple JWT authentication"
RESPONSE=$(curl -s -k -X POST https://ui.oasis.local/api/access_token/ \
-H "Content-Type: application/json" \
-d "{\"username\": \"$USERNAME_OR_ID\", \"password\": \"$PASSWORD_OR_SECRET\"}")
fi

if echo "$RESPONSE" | jq -e . > /dev/null 2>&1; then
TOKEN=$(echo "$RESPONSE" | jq -r '.access_token')
Expand Down Expand Up @@ -141,12 +174,17 @@ jobs:
kubectl scale --replicas=1 deployment/worker-oasislmf-piwind-1-v1

- name: Install OasisLMF
run: pip install oasislmf
run: |
pip install --upgrade pip
pip install -v "git+https://git@github.com/OasisLMF/OasisLMF.git@${{ env.oasislmf_branch }}#egg=oasislmf"

- name: Create test settings
run: |
cat <<EOF > test_settings.json
{
"computation_settings": {
"ktools_num_processes": 1
},
"version": "3",
"analysis_tag": "base_example",
"source_tag": "MDK",
Expand All @@ -172,9 +210,24 @@ jobs:
- name: Run analysis
run: |
set -e -o pipefail
USERNAME_OR_ID=$(kubectl get secret oasis-service-account-credentials -o jsonpath="{.data.username_or_id}" | base64 -d)
PASSWORD_OR_SECRET=$(kubectl get secret oasis-service-account-credentials -o jsonpath="{.data.password_or_secret}" | base64 -d)
USE_OIDC=$(kubectl get secret oasis-service-account-credentials -o jsonpath="{.data.use_oidc}" | base64 -d)

CREDENTIALS_FILE="$(mktemp)"
trap 'rm -f "$CREDENTIALS_FILE"' EXIT

if [ "$USE_OIDC" = "true" ]; then
echo "Using OIDC authentication"
printf '{"client_id": "%s", "client_secret": "%s"}' "$USERNAME_OR_ID" "$PASSWORD_OR_SECRET" > "$CREDENTIALS_FILE"
else
echo "Using Simple JWT authentication"
printf '{"username": "%s", "password": "%s"}' "$USERNAME_OR_ID" "$PASSWORD_OR_SECRET" > "$CREDENTIALS_FILE"
fi

{
oasislmf api run \
--server-login-json '{"username": "admin", "password": "password"}' \
--server-login-json "$CREDENTIALS_FILE" \
--server-version 'v1' \
--server-url 'http://ui.oasis.local/api' \
--model-id 1 \
Expand All @@ -184,6 +237,51 @@ jobs:
} 2>&1 | tee logs.txt
echo "exit_code=$?" >> "$GITHUB_ENV"

# - name: Minikube memory usage
# if: always()
# run: |
# # per pod memory data
# kubectl top pods --all-namespaces --no-headers 2>/dev/null || {
# echo "Failed to get metrics. Check metrics server."; exit 1;
# }
# echo
# echo "Memory Usage Summary:"
# echo "===================="
#
# # total memory
# PODS=$(kubectl top pods --all-namespaces --no-headers | wc -l)
# TOTAL=$(kubectl top pods --all-namespaces --no-headers | awk '{
# mem=$4;
# gsub(/[^0-9.]/, "", mem);
# if($4 ~ /Gi/) mem*=1024;
# total+=mem
# } END {printf "%.0f", total}')
#
# echo "Total pods: $PODS"
# echo "Total memory: ${TOTAL}Mi"
# echo "Average: $(echo "scale=0; $TOTAL / $PODS" | bc)Mi per pod"
#
# echo
# echo "By Namespace:"
# echo "-------------"
# kubectl top pods --all-namespaces --no-headers | awk '{
# ns=$1; mem=$4;
# gsub(/[^0-9.]/, "", mem);
# if($4 ~ /Gi/) mem*=1024;
# ns_mem[ns]+=mem; ns_count[ns]++
# } END {
# for(ns in ns_mem)
# printf "%-20s %6.0fMi (%d pods)\n", ns, ns_mem[ns], ns_count[ns]
# }' | sort -k2 -nr
#
# echo
# echo "Top 5 Memory Users:"
# echo "-------------------"
# kubectl top pods --all-namespaces --no-headers | sort -k4 -hr | head -5 | \
# awk '{printf "%-30s %s\n", $1"/"$2, $4}'



- name: Upload Artifact
if: always()
uses: actions/upload-artifact@v4
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,5 @@ out/
# Static web
src/server/static/

# PiWind config
scripts/piwind-path-cfg
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.4.10
2.4.11
5 changes: 3 additions & 2 deletions compose/debug.docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ services:
environment:
<<: *shared-env
STARTUP_RUN_MIGRATIONS: "true"
OASIS_ADMIN_USER: admin
OASIS_ADMIN_PASS: password
OASIS_USE_OIDC: ""
OASIS_SERVICE_USERNAME_OR_ID: admin
OASIS_SERVICE_PASSWORD_OR_SECRET: password
volumes:
- filestore-OasisData:/shared-fs:rw
- ../src/server/oasisapi:/var/www/oasis/src/server/oasisapi
Expand Down
5 changes: 3 additions & 2 deletions compose/mysql.docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ services:
environment:
<<: *shared-env
STARTUP_RUN_MIGRATIONS: "true"
OASIS_ADMIN_USER: admin
OASIS_ADMIN_PASS: password
OASIS_USE_OIDC: ""
OASIS_SERVICE_USERNAME_OR_ID: admin
OASIS_SERVICE_PASSWORD_OR_SECRET: password
volumes:
- filestore-OasisData:/shared-fs:rw
- ../src/server/oasisapi:/var/www/oasis/src/server/oasisapi
Expand Down
5 changes: 3 additions & 2 deletions compose/s3.docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ services:
environment:
<<: *shared-env
STARTUP_RUN_MIGRATIONS: "true"
OASIS_ADMIN_USER: admin
OASIS_ADMIN_PASS: password
OASIS_USE_OIDC: ""
OASIS_SERVICE_USERNAME_OR_ID: admin
OASIS_SERVICE_PASSWORD_OR_SECRET: password
volumes:
- ../src/server/oasisapi:/var/www/oasis/src/server/oasisapi
- ../src:/var/www/oasis/src:rw
Expand Down
5 changes: 3 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ services:
environment:
<<: *shared-env
STARTUP_RUN_MIGRATIONS: "true"
OASIS_ADMIN_USER: admin
OASIS_ADMIN_PASS: password
OASIS_USE_OIDC: ""
OASIS_SERVICE_USERNAME_OR_ID: admin
OASIS_SERVICE_PASSWORD_OR_SECRET: password
volumes:
- filestore-OasisData:/shared-fs:rw
server-websocket:
Expand Down
71 changes: 61 additions & 10 deletions kubernetes/charts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ Now you should be able to access the following pages:

- Oasis API - [https://ui.oasis.local/api/](https://api.oasis.local/api/)
- Oasis UI - [https://ui.oasis.local](https://ui.oasis.local)
- Keycloak - [https://ui.oasis.local/auth/admin](https://ui.oasis.local/admin/auth/)
- Keycloak - [https://ui.oasis.local/auth/admin](https://ui.oasis.local/admin/auth/) (If "keycloak" is set as auth_type in oasis-platform/values.yaml)
- Authentik - [https://ui.oasis.local/authentik/](https://ui.oasis.local/authentik/) (If "authentik" is set as auth_type in oasis-platform/values.yaml)
- Prometheus - [https://ui.oasis.local/prometheus/](https://ui.oasis.local/prometheus/)
- Alert manager - [https://ui.oasis.local/alert-manager/](https://ui.oasis.local/alert-manager/)
- Grafana - [https://ui.oasis.local/grafana/](https://ui.oasis.local/grafana/)
Expand All @@ -213,6 +214,9 @@ kubectl port-forward deployment/oasis-ui 8080:3838
# Access Keycloak UI on http://localhost:8081
kubectl port-forward deployment/keycloak 8081:8080

# Access Authentik UI on http://localhost:9001
kubectl port-forward deployment/authentik 9001:9000

# Access Prometheus on http://localhost:9090
kubectl port-forward statefulset/prometheus-monitoring-kube-prometheus-prometheus 9090

Expand Down Expand Up @@ -283,12 +287,16 @@ only.
cp oasis-montoring/values.yaml monitoring-values.yaml
```
3. Then we need to edit our value files to change the credentials:
1. Edit `platform-values.yaml` and set the `oasisServer.user` and `oasisServer.password` to your new credentials:
1. Edit `platform-values.yaml` and set the `oasisService.user` and `oasisService.password` to your new credentials or `oasisService.serviceClientName` and `oasisService.serviceClientSecret` to your new credentials. These set the credentials for all service authentication (oasis-server, worker-controller, model-registration etc.):

```
oasisServer:
oasisService:
# Modify this if using Simple JWT
user: oasis
password: password123
# Modifying this if using OIDC client_credentials (keycloak, authentik, etc.)
serviceClientName: oasis-service # or whatever your service authentication client_id is called
serviceClientSecret: verySecureSecret # Set secret to whatever the service client_secret is.
```
2. Edit `monitoring-values.yaml` and set your new password for Grafana (we can't change the username):

Expand Down Expand Up @@ -529,7 +537,8 @@ Default credentials are admin/password.
!!! Please note that upgrading this chart might reset changes in Prometheus, Alert manager and Grafana. Always make a
backup of your changes before your upgrade.

# Keycloak
# OIDC
## Keycloak

[Keycloak](https://keycloak.org) is now the default user manager and authentication service (can be disabled by chart
settings). Read more about Keycloak [here](https://www.keycloak.org/docs/latest/getting_started/index.html).
Expand All @@ -546,11 +555,40 @@ oasisServer:
clientSecret: <client secret>
```

## Authentik

[Authentik](https://goauthentik.io/) is an alternative user manager and authentication service (can be disabled by chart
settings). Read more about Authentik [here](https://docs.goauthentik.io/).

You can pick your preferred authentication by changing `oasisServer.apiAuthType` to either `authentik` or `simple` for
the standard simple jwt authentication.

```
oasisServer:
apiAuthType: authentik
oidc:
endpoint: <open connect endpoint url>
clientName: <client name>
clientSecret: <client secret>
```

## Service Authentication

Services must use a different client to authenticate, and this client must be configured to use client_credentials authentication, and must be configured to return `is_service_account=True` in the response.

You must also set the `oasisService.serviceClientName` and `oasisService.serviceClientSecret` to ensure services have the correct credentials to authenticate.

```
oasisService:
serviceClientName: <client name>
serviceClientSecret: <client secret>
```

## Administration console

Read [Accessing user interfaces](#accessing-user-interfaces) on how to access keycloak the administration console or use
the default ingress link:
Read [Accessing user interfaces](#accessing-user-interfaces) on how to access the administration console for your OIDC provideror use the default ingress link:

### Keycloak
[https://ui.oasis.local/auth/admin/](https://ui.oasis.local/auth/admin/)

The keycloak administrator user is defined in your oasis-platform chart values:
Expand All @@ -564,6 +602,20 @@ keycloak:
Full admin console documentation is found
on [keycloak.org](https://www.keycloak.org/docs/latest/server_admin/#admin-console).

### Authentik
[https://ui.oasis.local/authentik/](https://ui.oasis.local/authentik/)

The authentik administrator user is defined in your oasis-platform chart values:

```
authentik:
bootstrapUser: akadmin # Do not change this, this is the default username set by authentik.
bootstrapPassword: password
```

Full admin console documentation is found
on [authentik.org](https://docs.goauthentik.io/).

### Realm Settings

Contains generic settings for the realm. The most interesting one is probably the `Token` tab to set different timeouts.
Expand All @@ -587,13 +639,12 @@ Manage groups from here and then add them to each user in the `Manage / Users` p

## Default settings

The oasis-platform chart creates a default realm (keycloak security context) on the first deployment to manage all
users, credentials, roles etc. for the oasis REST API.
The oasis-platform chart creates a default realm on the first deployment to manage all users, credentials, roles etc. for the oasis REST API. This is the same structure for both keycloak and authentik.

A default REST API user is created on `helm install` and to change the username and password edit the values:

```
keycloak:
<oidc provider>:
oasisRestApi:
users:
# A default user is created at first deployment.
Expand All @@ -606,7 +657,7 @@ Default username is `oasis` with password `password`.

## Groups

Groups are now supported by creating them in Keycloak and assign them to users. A user can then set groups on objects
Groups are now supported by creating them in Keycloak and assign them to users. Authentik has groups by default. A user can then set groups on objects
like portfolio, model and data files. A user can set all or a subset of the groups the user belongs to and if no group
is set it will automatically get all the users groups.

Expand Down
Loading
Loading