{"id":24607694,"url":"https://github.com/redhat-scholars/devnation-labs-dashboard","last_synced_at":"2026-04-27T16:33:53.755Z","repository":{"id":46681717,"uuid":"315295275","full_name":"redhat-scholars/devnation-labs-dashboard","owner":"redhat-scholars","description":"Python tiny CRUD application with Flask, SQLAlchemy and Bootstrap to assign clusters for DevNation HOWL Labs.","archived":false,"fork":false,"pushed_at":"2021-09-30T11:15:05.000Z","size":237,"stargazers_count":1,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-04-18T00:28:56.396Z","etag":null,"topics":["container","docker","flask","mariadb","openshift","python","s2i","sqlalchemy"],"latest_commit_sha":null,"homepage":"https://developers.redhat.com/devnation/labs/openshift-howl","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/redhat-scholars.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-11-23T11:35:26.000Z","updated_at":"2021-05-25T14:23:00.000Z","dependencies_parsed_at":"2022-09-03T03:02:55.581Z","dependency_job_id":null,"html_url":"https://github.com/redhat-scholars/devnation-labs-dashboard","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/redhat-scholars/devnation-labs-dashboard","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redhat-scholars%2Fdevnation-labs-dashboard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redhat-scholars%2Fdevnation-labs-dashboard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redhat-scholars%2Fdevnation-labs-dashboard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redhat-scholars%2Fdevnation-labs-dashboard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/redhat-scholars","download_url":"https://codeload.github.com/redhat-scholars/devnation-labs-dashboard/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/redhat-scholars%2Fdevnation-labs-dashboard/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32345806,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"online","status_checked_at":"2026-04-27T02:00:06.769Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["container","docker","flask","mariadb","openshift","python","s2i","sqlalchemy"],"created_at":"2025-01-24T17:39:39.577Z","updated_at":"2026-04-27T16:33:53.739Z","avatar_url":"https://github.com/redhat-scholars.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DevNation Labs (HOWL) Dashboard\n\nPython tiny CRUD application with Flask, SQLAlchemy and Bootstrap to assign clusters for [HOWL](https://developers.redhat.com/devnation/labs/openshift-howl) Labs.\n\nIt uses MariaDB as DB.\n\n![App topology](app.png)\n\n## OpenShift\n\n\n### Create a new project\n\n```\noc new-project devnation-labs\n```\n\n### Get MariaDB\n\n```\noc new-app mariadb-persistent -p DATABASE_SERVICE_NAME=mariadb -p MYSQL_USER=mariadb -p MYSQL_PASSWORD=mariadb -p MYSQL_ROOT_PASSWORD=mariadb -p MYSQL_DATABASE=cluster_booking -l 'app.kubernetes.io/name=mariadb,app.kubernetes.io/part-of=labs-dashboard'\n \n```\n\n### Deploy\n\nOverriding S2I run script at `.s2i/bin/run` to run migrations and start the app.\n\n#### ENV vars as parameters to the Deployment\n\n\nDefault parameters are stored as ENV vars in [config.py](config.py#).\n\nList of variables to use for a deployment:\n\n| ENV | Default value | Description\n| ------------- | ------------- | ------------- |\n| `DB_USER`  | `mariadb`  | MariaDB username\n| `DB_PASS`  | `mariadb`  | MariaDB password\n| `DB_HOST`  | `mariadb`  | MariaDB hostname\n| `DB_NAME`  | `cluster_booking`  | DB name\n| `ADMIN_USER`  | `admin@email.tld`  | Default admin user **CHANGE IT**\n| `ADMIN_PASS`  | `_some_difficult_pass@`  | Default admin pass **CHANGE IT**\n| `SECRET_KEY`  | `2621a03cd4e5881cac070d675dac75d2d973c46f466aa1b5`  | Default secret key **CHANGE IT**\n\n#### Generate Session Secret Key\n\n\nYou should avoid using default `SECRET_KEY` from [config.py](config.py#L6), which defaults to a Dev-only one. For Prod envs, you can generate a new one with this command:\n\n```\nexport SECRET_KEY=`openssl rand -hex 24`\n```\n\n#### Change Admin user\n\nBy default there's only one Admin user, default credentials are stored in [config.py](config.py)\n\nPlease change default credentials before deploying the app in Prod:\n\n```\nexport ADMIN_USER=\u003cYOUR_CHOICE\u003e\nexport ADMIN_PASS=\u003cYOUR_CHOICE\u003e\n```\n\n\n#### Source-2-Image: oc new-app\n\nJust deploy the app in 2 steps.\n\nCreate the app:\n\n```\noc new-app https://github.com/redhat-scholars/devnation-labs-dashboard.git -e DB_USER=mariadb -e DB_PASS=mariadb -e DB_HOST=mariadb -e DB_NAME=cluster_booking -e ADMIN_USER=$ADMIN_USER -e ADMIN_PASS=$ADMIN_PASS -e SECRET_KEY=$SECRET_KEY -l 'app.kubernetes.io/name=python,app.kubernetes.io/part-of=labs-dashboard'\n```\n\nExpose a secure Route:\n\n```\noc create route edge get-cluster --service=devnation-labs-dashboard --insecure-policy=Redirect \n```\n\nHere we go, the Dashboard should be ready in a few seconds!\n\n#### Edit from Eclipse Che\n\nIf you are running on a cluster with [CodeReadyWorkspaces](https://developers.redhat.com/products/codeready-workspaces/overview) like [Developer Sandbox](https://developers.redhat.com/developer-sandbox), you can start editing it directly from there.\n\nJust annotate the Deployment for that:\n\n````\noc annotate deployments devnation-labs-dashboard app.openshift.io/vcs-uri='https://github.com/redhat-scholars/devnation-labs-dashboard.git'\noc annotate deployments devnation-labs-dashboard app.openshift.io/vcs-ref='master'\n````\n\nOr Run it with [Eclipse Che Factories](https://developers.redhat.com/che/creating-factories):\n\nNOTE: Change the address of Factory with your CRW URL\n\n[![Contribute](https://raw.githubusercontent.com/blues-man/nodejs-mongodb-sample/master/factory-contribute.svg)](https://codeready-openshift-workspaces.apps.crc.testing/factory?url=https://github.com/redhat-scholars/devnation-labs-dashboard.git)\n\n\n\n#### (Optional) Source-2-Image: Upload from local working dir\n\nIf you are working locally with the source code, you can upload it to OpenShift and let OpenShift run S2I in this way:\n\n```\noc new-build --name devnation-labs -i python --binary=true\noc start-build devnation-labs --from-dir=.\noc new-app devnation-labs -e DB_USER=mariadb -e DB_PASS=mariadb -e DB_HOST=mariadb -e DB_NAME=cluster_booking -e ADMIN_USER=foo@web.tld -e ADMIN_PASS=foo -e SECRET_KEY=$SECRET_KEY\noc create route edge --service=devnation-labs --insecure-policy=Redirect \n```\n\n#### (Experimental) Source-2-Image: odo\n\nodo should been able to [link services](https://docs.openshift.com/container-platform/latest/cli_reference/developer_cli_odo/creating-instances-of-services-managed-by-operators.html#listing-available-services-from-the-operators-installed-on-the-cluster_creating-instances-of-services-managed-by-operators) like MariaDB, however there's no MariaDB yet inside OCP OperatorHub.\n\n```\nodo project create devnation-labs\nodo create python --s2i\nodo push\nodo url create --port 8080 --secure\nodo push\n```\n\n\n## Local Development\n\n\n### Setup MariaDB\n\nGet MariaDB from Dockerhub:\n\n```\ndocker pull mariadb\n```\n\nRun MariaDB:\n```\ndocker run --rm -d --name mariadb -v /some/local/dir:/var/lib/mysql:z -p 3306:3306 -e MYSQL_ROOT_PASSWORD=foo -ti mariadb\n```\n\n### Setup Python\n\nStart local Python 3 env:\n\n```\nvirtualenv --python=/usr/bin/python3 venv\nsource ./venv/bin/activate\npip3 install -r requirements.txt\n```\n\n### Run locally\n\n#### Run Migrations\n\n```\npython manage.py db init\nDB_USER=user DB_PASS=pass DB_HOST=127.0.0.1 DB_NAME=cluster_booking python manage.py db migrate\nDB_USER=user DB_PASS=pass DB_HOST=127.0.0.1 DB_NAME=cluster_booking python manage.py db upgrade\n```\n\n#### Run the app\n \n```\nDB_USER=user DB_PASS=pass DB_HOST=127.0.0.1 DB_NAME=cluster_booking ADMIN_USER=foo@web.tld ADMIN_PASS=foo python app.py\n```\n\nOpen at your Web browser the following link http://127.0.0.1:8080\n\n\n### Docker/Podman\n\nThe `docker-entrypoint.sh` is not initializating the db by default, you can do it with adding this ENV the first time:\n\n```INIT_DB=yes```\n\n#### Build\n\n```\ndocker build -f Dockerfile.alpine -t devnation-labs:latest\n```\n\n\n#### Run\n\n```\ndocker run -e DB_USER=\"mariadb\" -e DB_PASS=\"mariadb\" -e DB_HOST=\"\u003cSERVICE_OR_LAN_IP\u003e\" -e ADMIN_USER=foo@web.tld -e ADMIN_PASS=foo -p 8080:8080 -ti devnation-labs\n```\n\n\n\n## Paths\n\n### Web\n\n- `/`: Student cluster booking form\n- `/admin/panel`: Administrator panel (Upload clusters and users via CSV, assigning manually clusters)\n- `/admin/login`: Administrator login\n\n### REST (@protected)\n\n| Path | HTTP Method | Description\n| ------------- | ------------- | ------------- |\n| /user/assign  | POST  | Assign a cluster\n| /user/add  | POST  | Add single user\n| /user/upload  | POST  | Add users from a CSV\n| /user/delete  | POST  | Delete single user\n| /cluster/upload  | POST  | Add clusters from a CSV\n| /cluster/update  | POST  | Update assigned cluster\n| /cluster/delete  | POST  | Delete single cluster\n| /admin/data/export  | GET  | Get list of users and assigned cluster as CSV\n| /admin/login  | POST  | Login for admin user\n\n## Usage\n\n- **Students view** : http://127.0.0.1:8080/ or URL from OpenShift Route + path\n- **Admin panel**: http://127.0.0.1:8080/admin/panel or URL from OpenShift Route + path\n\n### Upload Cluster CSV\n\nExpected min format (can contain more columns, but those listed and order is **mandatory**)\n```\nCluster ID,Cluster Name,Username,User Password,Login URL,Workshop URL\n```\n\n### Upload Registration CSV\n\nExpected min format (can contain more columns, but those listed and order is **mandatory**)\n\n```\nname[0],email[1],location[2],GEO[3],Company Name[8],Country[9],What is your job role/title?[10]\n```\n\n### Add User manually\n\nUse the form\n\n### Export CSV\n\nIt will generated a CSV containing all the info like in Registration CSV + cluster assigned info, ordered by cluster name atm.\n\n\n# Reference\n\n- https://flask.palletsprojects.com/en/1.1.x/\n- https://docs.sqlalchemy.org/en/latest/orm/tutorial.html\n- https://github.com/macagua/example.flask.crud-app.git\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredhat-scholars%2Fdevnation-labs-dashboard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fredhat-scholars%2Fdevnation-labs-dashboard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredhat-scholars%2Fdevnation-labs-dashboard/lists"}