notebooks/components/crud-web-apps/common
Kimonas Sotirchos 08542ef8bc jwa: Rework the Storage API of the web app (kubeflow/kubeflow#6321)
* wa(back): Add helper for deserializing JSON obj

In some cases we might need to construct Python k8s lib objects from the
JSONs that are provided by clients. I.e. the UI will be sending a PVC
object in json format, so the backend will need to create the
corresponding client.V1PersistentVolumeClaim object and submit it.

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Ilias Katsakioris <elikatsis@arrikto.com>

* wa(back): Serialization helper

Add helper function for converting a k8s-client object into a dict that
can be sent as an HTTP response.

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Ilias Katsakioris <elikatsis@arrikto.com>

* wa(back): Add dry run to Notebooks and PVCs

The backend will need to be able to create objects with dry-run, in
order to ensure they are valid. The backend will need to check that both
the Notebook and the PVCs can be created beforehand.

This way we avoid the scenario where we create PVCs but the Notebook
fails to be created, and the PVCs are never garbage collected.

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Ilias Katsakioris <elikatsis@arrikto.com>

* wa(back): Update kubernetes to 0.17

In order to support dry-run we must use the 0.17 version of the Python
k8s client.

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Ilias Katsakioris <elikatsis@arrikto.com>

* wa(back): Extend api module to patch pvcs

The backend will need to be able to PATCH PVCs in order to set the
ownerReference to the Notebook that mounts the PVCs.

Ref: arrikto/dev/issues/386#issuecomment-856700392

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Ilias Katsakioris <elikatsis@arrikto.com>

* jwa(back): Work with new Volumes API

The backend API should not add any more layers of abstractions on top of
the K8s API. The backend should expect the client/UI to be sending the
entire PVC spec of a new PVC.

Refs: arrikto/dev/issues/386

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Ilias Katsakioris <elikatsis@arrikto.com>

* jwa(back): Add unittests for new volumes API

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Ilias Katsakioris <elikatsis@arrikto.com>

* jwa(back): Extend the PVC info returned

We want to show both the access mode and size of the existing PVCs, when
a user clicks on the dropdown to select which PVC to mount.

The backend will need to provide this information to the frontend. We
don't want to send the K8s list of PVCs since this will result in a lot
of unnecessary data to be sent.

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Ilias Katsakioris <elikatsis@arrikto.com>

* jwa(front): Add proxy config for Rok

When developing the Rok flavor locally we will need to be able to open
the Rok chooser. This can be done by using Angular/webpack proxy to
bring the exposed rok service and the app under the same domain.

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Tasos Alexiou <tasos@arrikto.com>

* jwa(front): Remove card from form

The form of the app should not be a big card, but a normal form.

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Tasos Alexiou <tasos@arrikto.com>

* jwa(front): Install AceModule for yaml editing

Install AceModule to allow users to edit yamls of objects.

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Tasos Alexiou <tasos@arrikto.com>

* wa(front): Change the styling of form sections

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Tasos Alexiou <tasos@arrikto.com>

* jwa(front): Create common volume components

Component for:
* New PVC and configuring its spec
* Attaching an existing PVC in a Notebook

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Tasos Alexiou <tasos@arrikto.com>

* jwa(front): Update Rok form for new Volume API

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Tasos Alexiou <tasos@arrikto.com>

* jwa(front): Mark inputs as dirty when restoring Lab

When the UI autofills the form with values from a JupyterLab snapshot
then it should mark the touched fields as dirty. This way if a field has
errors the UI will make that input red.

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
Reviewed-by: Tasos Alexiou <tasos@arrikto.com>

* jwa: Update ConfigMap in manifests

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>

* jwa(front): Fix format errors

Signed-off-by: Kimonas Sotirchos <kimwnasptd@arrikto.com>
2022-02-07 16:26:17 +00:00
..
backend jwa: Rework the Storage API of the web app (kubeflow/kubeflow#6321) 2022-02-07 16:26:17 +00:00
frontend/kubeflow-common-lib jwa: Rework the Storage API of the web app (kubeflow/kubeflow#6321) 2022-02-07 16:26:17 +00:00
README.md CRUD web apps: i18n (kubeflow/kubeflow#5880) 2021-06-21 07:26:17 -07:00

README.md

Common code for CRUD web apps

Since our CRUD web apps like the Jupyter, Tensorboards and Volumes UIs are similarly build with Angular and Python/Flask we should factor the common code in to modules and libraries.

This directory will contain:

  1. A Python package with a base backend. Each one of the mentioned apps are supposed to extend this backend.
  2. An Angular library that will contain the common frontend code that these apps will be sharing

Backend

The backend will be exposing a base backend which will be taking care of:

  • Serving the Single Page Application
  • Adding liveness/readiness probes
  • Authentication based on the kubeflow-userid header
  • Authorization using SubjectAccessReviews
  • Uniform logging
  • Exceptions handling
  • Common helper functions for dates, yaml file parsing etc.

Supported ENV Vars

The following is a list of ENV var that can be set for any web app that is using this base app. This is list is incomplete, we will be adding more variables in the future.

ENV Var Description
CSRF_SAMESITE Controls the SameSite value of the CSRF cookie

How to use

In order to use this code during the development process one could use the -e flag with pip install. For example:

# I'm currently in /components/crud-web-apps/volumes/backend
cd ../../common/backend && pip install -e .

This will install all the dependencies of the package and you will now be able to include code from kubeflow.kubeflow.crud_backend in you current Python environment.

In order to build a Docker image and use this code you coud build a wheel and then install it:

### Docker
FROM python:3.7 AS backend-kubeflow-wheel

WORKDIR /src
COPY ./components/crud-web-apps/common/backend .

RUN python3 setup.py bdist_wheel

...
# Web App
FROM python:3.7

WORKDIR /package
COPY --from=backend-kubeflow-wheel /src .
RUN pip3 install .
...

Frontend

The common Angular library contains common code for:

  • Communicating with the Central Dashboard to handle the Namespace selection
  • Making http calls and handing their errors
  • Surfacing errors and warnings
  • Polling mechanisms
  • Universal styling accross the different web apps
  • Handling forms

How to use

# build the common library
cd common/frontend/kubeflow-common-lib
npm i
npm run build

# for development link the created module to the app
cd dist/kubeflow
npm link

# navigate to the corresponding app's frontend
cd crud-web-apps/volumes/frontend
npm i
npm link kubeflow

Common errors

NullInjectorError: StaticInjectorError(AppModule)[ApplicationRef -> NgZone]:
  StaticInjectorError(Platform: core)[ApplicationRef -> NgZone]:
    NullInjectorError: No provider for NgZone!

You also need to add "preserveSymlinks": true to the app's frontend angular.json at projects.frontend.architect.build.options.

Docker

# --- Build the frontend kubeflow library ---
FROM node:12 as frontend-kubeflow-lib

WORKDIR /src

COPY ./components/crud-web-apps/common/frontend/kubeflow-common-lib/package*.json ./
RUN npm install

COPY ./components/crud-web-apps/common/frontend/kubeflow-common-lib/ .
RUN npm run build

...
# --- Build the frontend ---
FROM node:12 as frontend
RUN npm install -g @angular/cli

WORKDIR /src
COPY ./components/crud-web-apps/volumes/frontend/package*.json ./
RUN npm install
COPY --from=frontend-kubeflow-lib /src/dist/kubeflow/ ./node_modules/kubeflow/

COPY ./components/crud-web-apps/volumes/frontend/ .

RUN npm run build -- --output-path=./dist/default --configuration=production

Internationalization

Internationalization was implemented using ngx-translate.

This is based on the browser's language. If the browser detects a language that is not implemented in the application, it will default to English.

The i18n asset files are located under frontend/src/assets/i18n of each application (jupyter, volumes and tensorboard). One file is needed per language. The common project is duplicated in every asset.

The translation asset files are set in the app.module.ts, which should not be needed to modify. The translation default language is set in the app.component.ts.

For each language added, app.component.ts will need to be updated.

When a language is added:

  • Copy the en.json file and rename is to the language you want to add. As it currently is, the culture should not be included.
  • Change the values to the translated ones

When a translation is added or modified:

  • Choose an appropriate key
  • Make sure to add the key in every language file
  • If text is added/modified in the Common Project, it needs to be added/modified in the other applications as well.

Testing

To test the i18n works as expected, simply change your browser's language to whichever language you want to test.