├── sprint2023.md ├── history.md ├── img ├── solo-code.JPG ├── team-code.JPG └── scrum-to-improvement.png ├── staging └── README.md ├── misc ├── ohtu-sopimus-v6.pdf └── ohtu-sopimus-v2-en.pdf ├── openshift ├── images │ ├── k1.png │ ├── k10.png │ ├── k12.png │ ├── k2.png │ ├── k3.png │ ├── k4.png │ ├── k5.png │ ├── k6.png │ ├── k8.png │ ├── k9.png │ ├── conf1.png │ └── conf2.png ├── old_kirjautuminen.md ├── OLD_README.md ├── django_openid.md ├── kirjautuminen.md └── README.md ├── sopimukset ├── sopimus-muut.pdf └── sopimus-yritys.pdf ├── history ├── summer2025.md ├── autumn2017.md ├── autumn2025.md ├── autumn2024.md ├── summer2017.md ├── summer2019.md ├── spring2025.md ├── autumn2020.md ├── summer2024.md ├── summer2020.md ├── autumn2023.md ├── summer2023.md ├── summer2018.md ├── autumn2021.md ├── spring2021.md ├── summer2021.md ├── spring2024.md ├── summer2022.md ├── spring2019.md ├── autumn2019.md ├── spring2023.md ├── autumn2022.md ├── spring2020.md ├── autumn2018.md ├── spring2018.md └── spring2022.md ├── tiimin_kaytanteet.md ├── demovideoita.md ├── roolit.md ├── LICENSE ├── itseisarvioinnin_kysymykset.md ├── best-practices.md ├── ohjeita-asiakaspalaveriin.md ├── learning-goals-of-software-engineering-lab.md ├── ohje-hyväksymiskriteerit.md └── README.md /sprint2023.md: -------------------------------------------------------------------------------- 1 | a 2 | -------------------------------------------------------------------------------- /history.md: -------------------------------------------------------------------------------- 1 | # Vanhat projektit 2 | 3 | [Täältä](history) löydät aiempien vuosien ryhmien repot, projektit, ym 4 | -------------------------------------------------------------------------------- /img/solo-code.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/img/solo-code.JPG -------------------------------------------------------------------------------- /img/team-code.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/img/team-code.JPG -------------------------------------------------------------------------------- /staging/README.md: -------------------------------------------------------------------------------- 1 | Moved to https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/tree/master/openshift -------------------------------------------------------------------------------- /misc/ohtu-sopimus-v6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/misc/ohtu-sopimus-v6.pdf -------------------------------------------------------------------------------- /openshift/images/k1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/openshift/images/k1.png -------------------------------------------------------------------------------- /openshift/images/k10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/openshift/images/k10.png -------------------------------------------------------------------------------- /openshift/images/k12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/openshift/images/k12.png -------------------------------------------------------------------------------- /openshift/images/k2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/openshift/images/k2.png -------------------------------------------------------------------------------- /openshift/images/k3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/openshift/images/k3.png -------------------------------------------------------------------------------- /openshift/images/k4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/openshift/images/k4.png -------------------------------------------------------------------------------- /openshift/images/k5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/openshift/images/k5.png -------------------------------------------------------------------------------- /openshift/images/k6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/openshift/images/k6.png -------------------------------------------------------------------------------- /openshift/images/k8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/openshift/images/k8.png -------------------------------------------------------------------------------- /openshift/images/k9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/openshift/images/k9.png -------------------------------------------------------------------------------- /misc/ohtu-sopimus-v2-en.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/misc/ohtu-sopimus-v2-en.pdf -------------------------------------------------------------------------------- /openshift/images/conf1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/openshift/images/conf1.png -------------------------------------------------------------------------------- /openshift/images/conf2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/openshift/images/conf2.png -------------------------------------------------------------------------------- /sopimukset/sopimus-muut.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/sopimukset/sopimus-muut.pdf -------------------------------------------------------------------------------- /img/scrum-to-improvement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/img/scrum-to-improvement.png -------------------------------------------------------------------------------- /sopimukset/sopimus-yritys.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/HEAD/sopimukset/sopimus-yritys.pdf -------------------------------------------------------------------------------- /history/summer2025.md: -------------------------------------------------------------------------------- 1 | # Kesän 2025 ohjelmistotuotantoprojektit 2 | 3 | ### Ryhmien repot 4 | 5 | - [fossiili](https://github.com/nowcommunity/nowdatabase) 6 | - [condus](https://github.com/amazing-race-condus/amazing-race-app) 7 | - [OSRM](https://github.com/HY-OHTUPROJ-OSRM) 8 | - [Finlex](https://github.com/ohjelmistotuotantoprojekti/SEB-yhteensopiva_finlex-lukija) 9 | -------------------------------------------------------------------------------- /history/autumn2017.md: -------------------------------------------------------------------------------- 1 | ## Autumn 2017 long 2 | 3 | * [R Language Support for TMC](https://github.com/RTMC/tmc-r) 4 | * [TMC Plugin for Qt Creator](https://github.com/TestMyQt/Qt-CreatorTMC) 5 | * [Grappa 2.0](https://github.com/OhtuGrappa2/front-grappa2) 6 | * [Serverless Coaching Chatbot](https://github.com/kehitysto/coaching-chatbot) 7 | * [QR-Code Skannerz](https://bitbucket.org/luomus/skannerz) 8 | * [Olga Verkkokauppa](https://github.com/Team-Olga/Olga-Verkkokauppa) 9 | * [REMU](https://github.com/RemuTeam/Remu) 10 | -------------------------------------------------------------------------------- /tiimin_kaytanteet.md: -------------------------------------------------------------------------------- 1 | ### Mitkä on ryhmän sisäiset käytännöt? 2 | 3 | Käytännöt ovat yhteisiä sopimuksia. Sovitaan 0-sprintin aikana ja tarkennetaan projektin edetessä. 4 | 5 | Esimerkki 6 | - käytäntö: definition of done (on testit, on vertaisarvioitu, on tungettu repoon, kaikki toimii) 7 | - käytäntö: aikataulut (yhteisiä työpäiviä jolloin tiimi läsnä TKTL:llä, erityisesti planningit ym) 8 | - käytäntö: maksimimäärä asioita työn alla per henkilö 9 | - käytäntö: coding conventions, koodin laatu 10 | - käytäntö: palavereissa käyttäytyminen, kännyt kiinni, ei myöhässä paikalle 11 | -------------------------------------------------------------------------------- /demovideoita.md: -------------------------------------------------------------------------------- 1 | ## Muutamia demovideoita 2 | 3 | - [Pienryhmien optimointi, kesä 2023](https://www.youtube.com/watch?v=MJJqFB_mtdY) 4 | - [Improved tools for data scientists, kesä 2023](https://www.youtube.com/watch?v=Cn3LLCGRMLc) 5 | - [Weather based recommender, kesä 2023](https://www.youtube.com/watch?v=uWbicdil9OU) 6 | - [Superadmin, syksy 2022](https://www.youtube.com/watch?v=KxC5wu00eLY) 7 | - [Logomotion, syksy 2022](https://www.youtube.com/watch?v=468MQ3-3-qw) 8 | - [Farmasian VR-peli, kevät 2022](https://youtu.be/pQND6_6zA-k) 9 | - [Lintuasemasovellus, kevät 2021](https://youtu.be/Pvl-Dhjz0dk) 10 | -------------------------------------------------------------------------------- /history/autumn2025.md: -------------------------------------------------------------------------------- 1 | - [MuViCo](https://github.com/MuViCo/MuViCo) 2 | - [German Grammar Interactive Learning and Exercising Website](https://github.com/OHTU-German-learning-website/OHTU-German-learning-website) 3 | - [Infopiste](https://github.com/Infopisteprojekti/infopiste) 4 | - [Kahden chatbotin keskustelun automaatiotyökalu opetukselliseen roolipeliin](https://github.com/doubleAgent-ohtu/doubleAgent) 5 | - [DTwin](https://github.com/DTwin-HY/DTwin) 6 | - [Jakaja](https://github.com/piryopt/pienryhmien-optimointi) 7 | - [EcoPaths](https://github.com/OhtuProjektiSyksy25/EcoPaths) 8 | - [WalkAMile](https://github.com/WalkAMileGame/WalkAMileGame) 9 | -------------------------------------------------------------------------------- /history/autumn2024.md: -------------------------------------------------------------------------------- 1 | # Syksy 2024 ohjelmistotuotantoprojektit 2 | 3 | ### Ryhmien repot 4 | 5 | - [Työturvallisuussovellus vaarojen tunnistamiseen työmaalla](https://github.com/Ohtu-Tyoturvallisuus/TTS-backend) 6 | - [MuViCo](https://github.com/MuViCo/MuViCo) 7 | - [Elisa eSport](https://github.com/NikiPOU/elisaohtuprojekti) 8 | - [Slow flower](https://github.com/Slowers-Team/Slowers-App) 9 | - [Human bias](https://github.com/top1-ohjelmistoprojektiryhma/HumanBiasProject) 10 | - [Farmasia VR](https://github.com/FarmasiaVR/farmasia-vr) 11 | - [Pyörävarkauksien estämisyhteisö](https://github.com/Bicyclesafe/bikesafe) 12 | - [fossiili](https://github.com/nowcommunity/nowdatabase) 13 | -------------------------------------------------------------------------------- /history/summer2017.md: -------------------------------------------------------------------------------- 1 | ## Summer 2017 first intensive period 2 | 3 | - [Clustering and Visualization Web Application for Speech](https://github.com/SSGL-SEP/speech_explorer) 4 | - [Xoliba AI](https://github.com/xoliba/xoliba) 5 | - [Adaptive exercises for NetBeans](https://github.com/sakuolin/skillifier) 6 | 7 | ## Summer 2017 long 8 | 9 | - [Biotalous Browser Game](https://github.com/tkt-biopeli/Biopeli) 10 | - [EKSY Mobile App](https://github.com/EksyApp/eksy) 11 | - [Interactive Web Repository for Physiological Computing](https://github.com/Mahtis/fysio2) 12 | - [MIK System](https://github.com/Owlaukka/MIK-System) 13 | 14 | ## Summer 2017 second intensive period 15 | 16 | - [Students Dashboard Widget](https://github.com/opiskelija-dashboard/dashboard) 17 | - [TDD Table Tennis](https://github.com/tdd-pingis/tdd-pingpong) 18 | -------------------------------------------------------------------------------- /history/summer2019.md: -------------------------------------------------------------------------------- 1 | 2 | ## Kesän 2019 ohjelmistotuotantoprojektit 3 | 4 | ### parhaat käytänteet 5 | 6 | ota mallia [täältä](https://github.com/ohtu-ohjaajat/OhTuHistory/blob/master/reference.md) 7 | 8 | ### Ryhmien repot 9 | - [Musiikin teorian MOOC-kurssijärjestelmä](https://github.com/rage/musiikin-teoria-material) 10 | - [Massage Booking System](https://github.com/karoliinaemilia/massage-booking-system) 11 | - [Bluetooth-positioning system for Ubikampus](https://github.com/ubikampus/Bluetooth-location-server) 12 | - [Emulator of data problems in use (and training) of machine learning systems](https://github.com/dpEmu/dpEmu) 13 | - Aikavälikertaus 14 | - [frontend](https://github.com/ohtu-aikavali2/aikavali2-front) 15 | - [backend](https://github.com/ohtu-aikavali2/aikavali2-back) 16 | 17 | ### Dokumentaatio 18 | 19 | ### Tuotantosovellukset 20 | -------------------------------------------------------------------------------- /history/spring2025.md: -------------------------------------------------------------------------------- 1 | # Kevään 2025 ohjelmistotuotantoprojektit 2 | 3 | ### Ryhmien repot 4 | 5 | - [MuViCo](https://github.com/MuViCo/MuViCo) 6 | - [Slow flower](https://github.com/Slowers-Team/Slowers-App) 7 | - [Farmasia VR](https://github.com/FarmasiaVR/farmasia-vr) 8 | - [Elisa-ohtuprojekti](https://github.com/ohtuprojekti-Elisa) 9 | - [Library App for Eficode](https://github.com/tuulestatemmattu/libraryapp) 10 | - [Ruokavälitys (RV) management frontend](https://github.com/Ruokavalitys/rv-management-update-frontend) 11 | - [German Grammar Interactive Learning and Exercising Website](https://github.com/OHTU-German-learning-website/OHTU-German-learning-website) 12 | - [AI CTO](https://github.com/AI-CTO/AI-CTO) 13 | - [Megasense ERP](https://github.com/ohtu-megasense/erp) 14 | - [Future customer](https://github.com/ohtu-kohtalo/ohjelmistotuotantoprojekti) 15 | -------------------------------------------------------------------------------- /history/autumn2020.md: -------------------------------------------------------------------------------- 1 | ## Syksyn 2020 ohjelmistotuotantoprojektit 2 | 3 | ### parhaat käytänteet 4 | 5 | ota mallia [täältä](https://github.com/ohtu-ohjaajat/OhTuHistory/blob/master/reference.md) 6 | 7 | ### Ryhmien repot 8 | 9 | - [Bakteerien tunnistuspeli](https://github.com/Ohtu-bakteerien-tunnistuspeli/Bakteerien-tunnistuspeli) 10 | - [Lintuasemasovellus](https://github.com/Lintuasemasovellus/lintuasemasovellus) 11 | - [Web editor & version control](https://github.com/ohtuprojekti-eficode/WEVC) 12 | - [Sukeltaja-App](https://github.com/Sukeltaja-Appi) 13 | - [Projektiryhmäytymistyökalu](https://github.com/UniversityOfHelsinkiCS/prkl) 14 | 15 | ### Dokumentaatio 16 | [Bakteerien tunnistuspeli](https://github.com/Ohtu-bakteerien-tunnistuspeli/Bakteerien-tunnistuspeli/blob/master/README.md) 17 | 18 | ### Tuotantosovellukset 19 | [Bakteerien tunnistuspeli](https://bakteeripeli.it.helsinki.fi/kirjautuminen) 20 | -------------------------------------------------------------------------------- /history/summer2024.md: -------------------------------------------------------------------------------- 1 | # Kesä 2024 ohjelmistotuotantoprojektit 2 | 3 | ### Ryhmien repot 4 | 5 | - [Food-Waste-Optimization](https://github.com/Food-Waste-Optimization/Food-Waste-Optimization) 6 | - [Ruokalaskuri](https://github.com/ohturuokasovellus/OhtuRuokasovellus) 7 | - [OSRM-reitityksen dynaaminen kulkueste](https://github.com/HY-OHTUPROJ-OSRM) 8 | - [Kurssiesitieto](https://github.com/Kurssiesitieto/kurssiesitieto-ohtuprojekti) 9 | - [Uutiskeräimen kontitus](https://github.com/uh-dcm/news-article-collection-container) 10 | 11 | ### Dokumentaatio 12 | - [Ruokalaskuri](https://github.com/ohturuokasovellus/OhtuRuokasovellus/tree/main/documentation) 13 | - [OSRM-reitityksen dynaaminen kulkueste](https://github.com/HY-OHTUPROJ-OSRM/osrm-project/wiki) 14 | - [Uutiskeräimen kontitus](https://github.com/uh-dcm/news-article-collection-container/tree/main/docs) 15 | 16 | ### Tuotantosovellukset 17 | - [Ruokalaskuri](https://ruokalaskuri.fi) 18 | - [Kurssiesitieto](https://study.cs.helsinki.fi/esitieto/) 19 | -------------------------------------------------------------------------------- /roolit.md: -------------------------------------------------------------------------------- 1 | # Roolit ohtuprojektissa 2 | 3 | ## Asiakas 4 | 5 | - Asiakas sopii ryhmän kanssa ensimmäisessä tapaamisessa työn laajuudesta ja vastaa ryhmän kysymyksiin. Luodaan Product Backlog. 6 | - Joka iteraation jälkeen pitäisi olla jotain demottavaa asiakkaalle 7 | - Asiakas on läsnä sprintin lopuksi pidettävässä demossa ja antaa palautetta / uusia / tarkennettuja itemejä Product Backlogiin. 8 | - Asiakas kertoo toiveistaan/vaatimuksistaan ja määrittää niille tärkeysjärjestyksen, jonka tulee heijastua product backlogissa 9 | 10 | Asiakkaan rooliin EI kuulu: 11 | - Ryhmän työhön sotkeutuminen (esim. työn alla olevien vaatimuksien muuttaminen) kesken sprintin 12 | - Muissa palavereissa kuin sprintinjälkeisessä review/demopalaverissa läsnäolo 13 | - tarkemman sprint planningin hoitaa yheensä RYHMÄ asiakkaan toiveet mielessä pitäen ja asiakkaan läsnäoloa ei edellytetä, tarpeen mukaan asiakaskin toki voi olla paikalle 14 | - Product backlogin ylläpito. Tiimi vastaa asiakkaan toiveiden kirjaamisesta backlogille. 15 | -------------------------------------------------------------------------------- /history/summer2020.md: -------------------------------------------------------------------------------- 1 | ## Kesän 2020 ohjelmistotuotantoprojektit 2 | 3 | ### parhaat käytänteet 4 | 5 | ota mallia [täältä](https://github.com/ohtu-ohjaajat/OhTuHistory/blob/master/reference.md) 6 | 7 | ### Ryhmien repot 8 | 9 | - [HYSQL - opetuskieli tietokantakursseille](https://github.com/hy-sql/project-info) 10 | - [Tools for automated image analysis in social sciences](https://github.com/duck-duck-tag/duck-duck-tag) 11 | - [Remote Society Now - etätyön hyötyjen mittaaminen työntekijä- ja yritysdatalla](https://github.com/RemoteSocietyNow-ohtu/remotesocietynow) 12 | - [Robotin konenäkö mikropalveluna](https://github.com/Konenako/Ohtuprojekti-kesa2020) 13 | - C# and Bash Support for TMC 14 | - [C# Support for TMC](https://github.com/TMC-CSharp/tmc-csharp) 15 | - [Bash Support for TMC](https://github.com/tmc-bash/tmc-bash) 16 | 17 | ### Dokumentaatio 18 | - C# and Bash Support for TMC 19 | - [C# Support for TMC](https://github.com/TMC-CSharp/tmc-csharp) 20 | - [Bash Support for TMC](https://github.com/tmc-bash/tmc-bash) 21 | 22 | ### Tuotantosovellukset 23 | - C# support for TMC 24 | - [TestMyCode](https://tmc.mooc.fi/) 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /history/autumn2023.md: -------------------------------------------------------------------------------- 1 | # Syksy 2023 ohjelmistotuotantoprojektit 2 | 3 | ### Ryhmien repot 4 | 5 | - [Robottikoodieditori](https://github.com/robottikoodieditori) 6 | - [Training Hub](https://github.com/ohtutraininghub/traininghub) 7 | - [Ilmastokompassi](https://github.com/Ilmastokompassi/Ilmastokompassi) 8 | - [ILMOWEB](https://github.com/ILMOWEB/ilmo) 9 | - [SAT-STEP](https://github.com/SAT-STEP/SAT-STEP) 10 | - [Kirjoittamisen itsearviointityökalu](https://github.com/ohturyhma123/tieki-app) 11 | 12 | ### Dokumentaatio 13 | 14 | - [Robottikoodieditori](https://github.com/robottikoodieditori) 15 | - [Training Hub](https://github.com/ohtutraininghub/traininghub) 16 | - [Ilmastokompassi](https://github.com/Ilmastokompassi/Ilmastokompassi/tree/main/docs) 17 | - [ILMOWEB](https://github.com/ILMOWEB/ilmo/tree/main/documentation) 18 | - [SAT-STEP](https://github.com/SAT-STEP/SAT-STEP) 19 | 20 | ### Tuotantosovellukset 21 | 22 | - [Robottikoodieditori](https://github.com/robottikoodieditori) 23 | - [Training Hub](https://github.com/ohtutraininghub/traininghub) 24 | - [ILMOWEB](https://github.com/ILMOWEB/ilmo) 25 | - [Ilmastokompassi](https://ilmastokompassi.helsinki.fi) 26 | -------------------------------------------------------------------------------- /history/summer2023.md: -------------------------------------------------------------------------------- 1 | # Kesä 2023 ohjelmistotuotantoprojektit 2 | 3 | ### Ryhmien repot 4 | 5 | - [Urheiluseura 3.0](https://github.com/Urheiluseura-3-0) 6 | - [Tiny Machine Learning as a Service](https://github.com/orgs/TinyMLaas/repositories) 7 | - [Improved tools for data scientists](https://github.com/Order-Team/bring-order) 8 | - [Weather-based recommendation for outdoor activities in Helsinki](https://github.com/HelsinkiUniCollab/WeatherbasedRecommender) 9 | - [MammalBase](https://github.com/karilint/mammalbase) 10 | - [Pienryhmien Optimointi](https://github.com/piryopt/pienryhmien-optimointi) 11 | 12 | ### Dokumentaatio 13 | 14 | - [Tiny Machine Learning as a Service](https://github.com/TinyMLaas/TinyMLaaS/tree/main/docs) 15 | - [Staging API docs](https://tiny.marenk.fi/api/docs) 16 | - [MammalBase](https://github.com/karilint/mammalbase/tree/main/documentation) 17 | - [Pienryhmien Optimointi](https://github.com/piryopt/pienryhmien-optimointi/tree/main/documentation) 18 | 19 | ### Tuotantosovellukset 20 | 21 | - [Tiny Machine Learning as a Service](https://tiny.marenk.fi/) 22 | - [API](https://tiny.marenk.fi/api/) 23 | - [MammalBase](https://staging.mammalbase.net/) 24 | - [Pienryhmien Optimointi](https://piryopt.ext.ocp-test-0.k8s.it.helsinki.fi/) 25 | -------------------------------------------------------------------------------- /history/summer2018.md: -------------------------------------------------------------------------------- 1 | 2 | ## Kesän 2018 ohjelmistotuotantoprojektit 3 | 4 | ### parhaat käytänteet 5 | 6 | ota mallia [täältä](https://github.com/ohtu-ohjaajat/OhTuHistory/blob/master/reference.md) 7 | 8 | ### Ryhmien repot 9 | - [Labtool](https://github.com/labtool/labtool) 10 | - Kurssikartta 11 | - [front](https://github.com/kurssikartta-ohtuprojekti/kurssikartta-front) 12 | - [back](https://github.com/kurssikartta-ohtuprojekti/kurssikartta-back) 13 | - [Luupeli](https://github.com/luupeli/luupeli) 14 | 15 | ### Dokumentaatio 16 | - Labtool 17 | - [backlog](https://github.com/labtool/labtool/projects/1) 18 | - [muu dokumentaatio](https://drive.google.com/drive/folders/1CkmhZ3rhVPO3Qn_hrFSlWlRKFN-sV-Lw) 19 | - Kurssikartta 20 | - [backlog](https://docs.google.com/spreadsheets/d/1PXgQVgB_MMsUWzie6D0eFcQnCfmKfAFmBePvULNeHoE) 21 | - Luupeli 22 | - [backlog](https://docs.google.com/spreadsheets/d/1b66WPYF05FefrFPH069sPz5Ew2VdkUd1fpNZGQjryEQ/edit?usp=sharing) 23 | - [muu dokumentaatio](https://github.com/luupeli/luupeli/wiki) 24 | 25 | ### Tuotantosovellukset 26 | - Labtool 27 | - [staging](https://svm-61.cs.helsinki.fi/labtool/) toimii vain laitoksen verkossa 28 | - [tuotanto](https://studies.cs.helsinki.fi/labtool/) 29 | - Kurssikartta 30 | - [Kurssikartta](https://kurssikartta.herokuapp.com/) 31 | - Luupeli 32 | - [tuotanto](http://luupeli.herokuapp.com/) 33 | -------------------------------------------------------------------------------- /history/autumn2021.md: -------------------------------------------------------------------------------- 1 | ## Syksyn 2021 ohjelmistotuotantoprojektit 2 | 3 | ### Parhaat käytänteet 4 | 5 | ota mallia [täältä](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/blob/master/best-practices.md) 6 | 7 | ### Ryhmien repot 8 | 9 | - [Amandus](https://github.com/Ohtu-project-Eficode/Amandus) 10 | - [Discord kurssibotti](https://github.com/Ohtuproju2021syksy/Discord-Bot-better) 11 | - [Kierratysavustin](https://github.com/ohtuprojekti-Kierratysavustin/Kierratysavustin) 12 | - [Mielentilatutkimus-thl](https://github.com/ohtuprojekti-mielentilatutkimus-thl/mielentilatutkimus-thl) 13 | - [RNames](https://github.com/karilint/rnames) 14 | - [Taudinpurkauspeli2021](https://github.com/taudinpurkauspeli/taudinpurkauspeli2021) 15 | - [Lintu- ja kasviatlas](https://github.com/ATLAS-ohtuprojekti/ATLAS) 16 | - [Hybridityöskentelyn tukisovellus Slack-integraatiolla](https://github.com/hytuslain/hytuslain) 17 | 18 | ### Dokumentaatio 19 | 20 | - [Discord kurssibotti](https://github.com/Ohtuproju2021syksy/Discord-Bot-better/blob/main/README.md) 21 | - [Kierratysavustin](https://github.com/ohtuprojekti-Kierratysavustin/Kierratysavustin/blob/main/README.md) 22 | - [RNames](https://github.com/sallamarieini/ohtu-project-RNames) 23 | - [Taudinpurkauspeli](https://wiki.helsinki.fi/display/TAUPE/2021+Taudinpurkauspeli) 24 | 25 | ### Tuotantosovellukset 26 | - [Amandus](http://135.181.89.96:4000/) 27 | - [Kierratysavustin](https://kierratysavustin.cs.helsinki.fi/) 28 | -------------------------------------------------------------------------------- /history/spring2021.md: -------------------------------------------------------------------------------- 1 | ## Kevään 2021 ohjelmistotuotantoprojektit 2 | 3 | ### parhaat käytänteet 4 | 5 | ota mallia [täältä](https://github.com/ohtu-ohjaajat/OhTuHistory/blob/master/reference.md) 6 | 7 | ### Ryhmien repot 8 | 9 | - [Lintuasemasovellus](https://github.com/luomus/lintuasemasovellus) 10 | - [DevOps itsearviointikysely](https://github.com/Devops-ohtuprojekti/DevOpsCSAOS) 11 | - [Adminapp Medified](https://github.com/ohtuprojekti-medified/adminapp-medified) 12 | - [Kierrätysavustin](https://github.com/ohtuprojekti-Kierratysavustin/Kierratysavustin) 13 | - [Projektiryhmäytymistyökalu](https://github.com/UniversityOfHelsinkiCS/prkl) 14 | 15 | 16 | ### Dokumentaatio 17 | 18 | - [Lintuasemasovellus](https://github.com/luomus/lintuasemasovellus/blob/master/README.md) 19 | - [DevOps itsearviointikysely](https://github.com/Devops-ohtuprojekti/DevOpsCSAOS/blob/main/documentation/) 20 | - [Adminapp Medified](https://github.com/ohtuprojekti-medified/adminapp-medified/blob/master/README.md) 21 | - [Kierrätysavustin](https://github.com/ohtuprojekti-Kierratysavustin/Kierratysavustin/tree/main/documents) 22 | - [Projektiryhmäytymistyökalu](https://github.com/UniversityOfHelsinkiCS/prkl/tree/master/documentation) 23 | - [ETIE](https://github.com/IELuomus/extractiontool/blob/main/README.md) 24 | 25 | 26 | ### Tuotantosovellukset 27 | 28 | - [DevOps itsearviointikysely](https://ohtu-csaos-staging.herokuapp.com/) 29 | - Adminapp Medified - tulossa 30 | - [Projektiryhmäytymistyökalu](https://study.cs.helsinki.fi/assembler) 31 | -------------------------------------------------------------------------------- /history/summer2021.md: -------------------------------------------------------------------------------- 1 | ## Kesä 2021 ohjelmistotuotantoprojektit 2 | 3 | ### parhaat käytänteet 4 | 5 | ota mallia [täältä](https://github.com/ohtu-ohjaajat/OhTuHistory/blob/master/reference.md) 6 | 7 | ### Ryhmien repot 8 | 9 | - [CSES-järjestelmän komentorivityökalu](https://github.com/csesfi/cses-cli) 10 | - [Kristillisten sinkkujen deitti](https://github.com/Ohtu-KSDeitti/frontend_ksd) 11 | - [LUMA-tiedeluokkien varausjärjestelmä](https://github.com/lumawelhot/luma-varaukset) 12 | - [QuantMark](https://github.com/quantum-ohtu) 13 | - [Discord kurssibotti](https://github.com/CS-DISCORD-BOT/cs-discord-bot) 14 | - [Mobiili-lähiruokasovellus](https://github.com/ohtu2021satoja/SatojaREKO) 15 | - [ChatbotTrolli](https://github.com/sumuh/Trollbot) 16 | 17 | ### Dokumentaatio 18 | 19 | - [CSES-järjestelmän komentorivityökalu](https://github.com/csesfi/cses-cli/blob/main/README.md) 20 | - [Kristillisten sinkkujen deitti](https://github.com/Ohtu-KSDeitti/frontend_ksd/blob/main/README.md) 21 | - [LUMA-tiedeluokkien varausjärjestelmä](https://github.com/lumawelhot/luma-varaukset/blob/main/README.md) 22 | - [QuantMark](https://github.com/quantum-ohtu/QuantMark/wiki) 23 | - [Discord kurssibotti](https://github.com/CS-DISCORD-BOT/project-info) 24 | - [Mobiili-lähiruokasovellus](https://github.com/ohtu2021satoja/SatojaREKO/blob/main/documents/databasedia.png) 25 | 26 | ### Tuotantosovellukset 27 | 28 | - [CSES-järjestelmän komentorivityökalu](https://github.com/csesfi/cses-cli/releases) 29 | - [LUMA-tiedeluokkien varausjärjestelmä](https://ohtup-staging.cs.helsinki.fi/luma-varaukset) 30 | -------------------------------------------------------------------------------- /openshift/old_kirjautuminen.md: -------------------------------------------------------------------------------- 1 | # Yliopiston kirjautuminen 2 | 3 | Jos projekti vaatii yliopiston kirjautumista vaihtoehdot ovat käytännössä SAML-pohjainen Shibboleth kirjautuminen tai modernimpaan OAuth:iin ja OpenID Connect:iin (OIDC) perustuva ratkaisu. 4 | 5 | ## OpenID Connect 6 | 7 | ks [kirjautuminen.md](kirjautuminen.md) 8 | 9 | 10 | ## Shibboleth 11 | 12 | - [Yliopiston Shibboleth ohjeet](https://wiki.helsinki.fi/xwiki/bin/view/IAMasioita/Identiteetin-%20ja%20p%C3%A4%C3%A4synhallinnan%20dokumentaatio/Keskitetyn%20k%C3%A4ytt%C3%A4j%C3%A4tunnistuksen%20vaihtoehdot/1.%20Shibboleth%20%28SAML2%20%20OIDC%29/Ohjeet%20Shibbolointiin) 13 | - [Konttialustan Shibboleth ohjeet](https://wiki.helsinki.fi/xwiki/bin/view/SO/Sovelluskehitt%C3%A4j%C3%A4n%20ohjeet/Alustat/Tiken%20konttialusta/3%20-%20Ohjeet/Shibboleth-kirjautuminen%20sovelluksellesi) 14 | 15 | Shibboleth-kirjautumiseen on mahdollista käyttää valmiiksi OpenShift:iin konfiguroitua instanssia. Riittää, että sovelluksen lisää tähän [Apache-konfiguraatiotiedostoon](https://console-openshift-console.apps.ocp-test-0.k8s.it.helsinki.fi/k8s/ns/ohtuprojekti-staging/configmaps/httpd-config) ja uudelleenkäynnistää Shibbolethin. Tämän jälkeen sovellukseen voi tunnistautua osoitteessa [shibboleth.ext.ocp-test-0.k8s.it.helsinki.fi/osoite](https://shibboleth.ext.ocp-test-0.k8s.it.helsinki.fi/sovellus/). Sovellus sää käyttäjän atribuutit pyyntöjen headereissa. 16 | 17 | Esimerkkitoteutus ks. [shibboleth-postgres-example](https://github.com/UniversityOfHelsinkiCS/shibboleth-postgres-example/blob/main/src/server/middleware/user.ts). 18 | -------------------------------------------------------------------------------- /history/spring2024.md: -------------------------------------------------------------------------------- 1 | # Kevät 2024 ohjelmistotuotantoprojektit 2 | 3 | ### Ryhmien repot 4 | 5 | - [MammalBase](https://github.com/karilint/mammalbase) 6 | - [Klusteri website](https://github.com/matlury/klusteri-website) 7 | - [game-ai-platform-team](https://github.com/game-ai-platform-team/tira-ai-platform) 8 | - [Kurssi-Esitieto](https://github.com/Kurssiesitieto/kurssiesitieto-ohtuprojekti) 9 | - [Kitsain](https://github.com/ohtuprojektiryhma/kitsain) 10 | - [MTK-logistics-optimization](https://github.com/MTK-ohtu/mtk-ohtu) 11 | - [Palkkatietopalvelu](https://github.com/Palkkatietopalvelu/palkkatietopalvelu) 12 | - [Training Hub](https://github.com/ohtutraininghub/traininghub) 13 | - [Ohtuprojektin Ilmoittautumissovellus](https://github.com/Ohtuilmo/ohtuilmo) 14 | 15 | ### Dokumentaatio 16 | 17 | - [MammalBase](https://github.com/karilint/mammalbase/tree/main/documentation) 18 | - [Klusteri website](https://github.com/matlury/klusteri-website) 19 | - [game-ai-platform-team](https://github.com/game-ai-platform-team/tira-ai-platform/tree/main/docs) 20 | - [Kurssi-Esitieto](https://github.com/Kurssiesitieto/kurssiesitieto-ohtuprojekti/tree/main/documentation) 21 | - [Kitsain](https://github.com/ohtuprojektiryhma/kitsain/tree/main/documentation) 22 | - [MTK-logistics-optimization](https://github.com/MTK-ohtu/mtk-ohtu/tree/main/docs) 23 | - [Palkkatietopalvelu](https://github.com/Palkkatietopalvelu/palkkatietopalvelu/tree/main/documents) 24 | - [Training Hub](https://github.com/ohtutraininghub/traininghub/tree/main/docs) 25 | 26 | ### Tuotantosovellukset 27 | 28 | - [MammalBase](https://staging.mammalbase.net/) 29 | - [game-ai-platform-team](PLACEHOLDER) 30 | - [Kitsain](PLACEHOLDER) 31 | -------------------------------------------------------------------------------- /history/summer2022.md: -------------------------------------------------------------------------------- 1 | # Kesä 2022 ohjelmistotuotantoprojektit 2 | 3 | ### Ryhmien repot 4 | 5 | - [Lintuasemasovelluksen jatkokehitys](https://github.com/luomus/lintuasemasovellus) 6 | - [Robot mapper with ROS2 and Turtlebot3](https://github.com/Le36/ros2-mapper) 7 | - [MammalBase](https://github.com/karilint/mammalbase) 8 | - [Helsinki Genomic Graph Database](https://github.com/Helsinki-Genomic-Graph-Database/HGGD) 9 | - [Pharmacy VR Game Part 3](https://github.com/tjvalkonen/farmasia-vr) 10 | - [Robot Logo Compiler](https://github.com/Robot-Logo-Compiler/Robot-Logo-Compiler) 11 | 12 | ### Dokumentaatio 13 | 14 | - [Lintuasemasovelluksen jatkokehitys](https://github.com/luomus/lintuasemasovellus/tree/master/documentation) 15 | - [Robot mapper with ROS2 and Turtlebot3](https://github.com/Le36/ros2-mapper/blob/main/documentation/tutorials.md) 16 | - [MammalBase](https://github.com/karilint/mammalbase/tree/main/documentation) 17 | - [Helsinki Genomic Graph Database](https://github.com/Helsinki-Genomic-Graph-Database/HGGD/tree/main/documentation) 18 | - [Pharmacy VR Game Part 3](https://github.com/tjvalkonen/farmasia-vr/tree/dev/Docs) 19 | - [Robot Logo Compiler](https://github.com/Robot-Logo-Compiler/Robot-Logo-Compiler/blob/main/Documentation/instructions.MD) 20 | 21 | 22 | ### Tuotantosovellukset 23 | 24 | - [Lintuasemasovelluksen jatkokehitys](http://lintuasema-lintuasema-staging.rahtiapp.fi/) 25 | - [Robot mapper with ROS2 and Turtlebot3](https://github.com/Le36/ros2-mapper/tree/main/workspace) 26 | - [MammalBase](https://staging.mammalbase.net/) 27 | - [Helsinki Genomic Graph Database](https://hggd.cs.helsinki.fi/hggd/index) 28 | - [Pharmacy VR Game Part 3](https://github.com/tjvalkonen/farmasia-vr) 29 | -------------------------------------------------------------------------------- /history/spring2019.md: -------------------------------------------------------------------------------- 1 | ## Kevään 2019 ohjelmistotuotantoprojektit 2 | 3 | ### Parhaat käytänteet 4 | 5 | Ota mallia [täältä](https://github.com/ohtu-ohjaajat/OhTuHistory/blob/master/reference.md) 6 | 7 | ### Ryhmien repot 8 | 9 | - Partio 10 | - [Frontend](https://github.com/partio-scout/tosu-frontend) 11 | - [Backend](https://github.com/partio-scout/tosu-backend-node) 12 | - [Ohtuprojekti-ilmo](https://github.com/ohtuprojekti-ilmo) 13 | - [Kisallioppiminen.fi](https://github.com/Matikkaprojekti) 14 | - [TKT-ohjaajarekisteri](https://github.com/TKT-ohjaajarekisteri) 15 | - Fluxx Chat 16 | - [Frontend](https://github.com/FluxxChat/FluxxChat-webasiakas) 17 | - [Backend](https://github.com/FluxxChat/FluxxChat-palvelin) 18 | 19 | ### Dokumentaatio 20 | 21 | - Partio 22 | - Ohtuprojekti-ilmo 23 | - [Backlog](https://docs.google.com/spreadsheets/d/1205Vjsr9tYh99stufyOv2tWTvFBVQ1rwzXtABFH2EsI/edit?usp=sharing) 24 | - [Tuntikirjanpito](https://docs.google.com/spreadsheets/d/1uagIAAlsbgqUgsZ5_jsUPeGgxEzarq86cyLeBCV282E/edit?usp=sharing) 25 | - [Kisallioppiminen.fi](https://docs.google.com/spreadsheets/d/e/2PACX-1vRPtzcQTtghurkIFXZ38BT5HgzWY6mAbIIx0y8FKe3SPWxwXvilJqsDdFW4aE9DMEN7EuQZhJhZ7NPl/pubhtml) 26 | - [TKT-ohjaajarekisteri](https://github.com/TKT-ohjaajarekisteri/TKT-ohjaajarekisteri-front/tree/master/documentation) 27 | - [Fluxx Chat](https://github.com/FluxxChat/FluxxChat-dokumentaatio) 28 | 29 | ### Sovellukset 30 | 31 | - Partio 32 | - Ohtuprojekti-ilmo 33 | - [sovellus](https://studies.cs.helsinki.fi/projekti/) 34 | - Kisallioppiminen.fi 35 | - [staging](https://matikkaprojekti.github.io/kisallioppiminen-staging/) 36 | - [TKT-ohjaajarekisteri](https://tkt-ohjaajarekisteri-front.herokuapp.com/) 37 | - [Fluxx Chat](https://fluxxchat-webasiakas.herokuapp.com/) 38 | -------------------------------------------------------------------------------- /history/autumn2019.md: -------------------------------------------------------------------------------- 1 | ## Syksyn 2019 ohjelmistotuotantoprojektit 2 | 3 | ### parhaat käytänteet 4 | 5 | ota mallia [täältä](https://github.com/ohtu-ohjaajat/OhTuHistory/blob/master/reference.md) 6 | 7 | ### Ryhmien repot 8 | 9 | - [Hintahaukka](https://github.com/Hintahaukka) 10 | - [Mobiilishakki](https://github.com/Mobiilishakki/Mobiilishakki) 11 | - [VR-peli](https://github.com/ohtuprojekti-farmasia/farmasia-vr) 12 | - [Monihakusovellus](https://github.com/Ohtu-FaceTed) 13 | - [Saavutettava somepalvelu](https://github.com/kohdataan) 14 | - Data Structures and Algorithms Project templates 15 | - [Chess](https://github.com/TiraLabra/chess) 16 | - [Minesweeper](https://github.com/TiraLabra/minesweeper) 17 | - [Labtool-2019](https://github.com/UniversityOfHelsinkiCS/labtool) 18 | 19 | ### Dokumentaatio 20 | 21 | - Hintahaukka 22 | - [backlog](https://docs.google.com/spreadsheets/d/1Mazq4EFbfbMsLPeCpOckbu11LNR1Ki2RiNf460z-rpU/edit#gid=517998298) 23 | - Mobiilishakki 24 | - [backlog](https://docs.google.com/spreadsheets/d/1zG-0s1h2mIXxn2nuR7uvuNg6FT7avz7rtKZj1EuxpaE/edit#gid=1) 25 | - VR-peli 26 | - [Product backlog](https://github.com/ohtuprojekti-farmasia/farmasia-vr/projects/1) 27 | - Monihakusovellus 28 | - [backlog](https://github.com/Ohtu-FaceTed/FaceTed-Search/projects) 29 | - Saavutettava somepalvelu 30 | - [backlog](https://github.com/orgs/kohdataan/projects/2) 31 | - Data Structres and Algorithms Project Templates 32 | - [backlog[(https://helsinkifi-my.sharepoint.com/:x:/g/personal/jermusto_ad_helsinki_fi/EbSHuSez9tVNi0CxTRtVU_sBo6SEdoqiayo5-I-wRxh_XA?e=TAZVRq) 33 | - Labtool-2019 34 | - [backlog](https://github.com/UniversityOfHelsinkiCS/labtool/projects/3) 35 | 36 | 37 | ### Tuotantosovellukset 38 | - Labtool-2019 39 | - [sovellus](https://study.cs.helsinki.fi/labtool) 40 | -------------------------------------------------------------------------------- /history/spring2023.md: -------------------------------------------------------------------------------- 1 | ## Kevään 2023 ohjelmistotuotantoprojektit 2 | 3 | ### Parhaat käytänteet 4 | 5 | ota mallia [täältä](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/blob/master/best-practices.md) 6 | 7 | ### Ryhmien repot 8 | 9 | - [Anturidatan_visualisointi](https://github.com/Anturit/Anturidatan_visualisointi) 10 | - [Berry Picker Tracker](https://github.com/marjanpoimijat) 11 | - [Cast2023](https://github.com/Cast2023/cast) 12 | - [FarmasiaVR](https://github.com/FarmasiaVR/farmasia-vr) 13 | - [Koululentovaraukset](https://github.com/Ohtuprojekti-Fintraffic/lentovaraukset) 14 | - [Movie-Book Recommender](https://github.com/movie-book-recommender/movie-book-recommender-project) 15 | - [Origami-TinyML](https://github.com/Origami-TinyML/tflm_hello_world) 16 | - [Revita](https://github.com/UniversityOfHelsinkiCS/mobvita) 17 | - [TMC-Coach](https://github.com/tmc-coach/tmc-coach) 18 | 19 | ### Dokumentaatio 20 | 21 | - [Anturidatan_visualisointi](https://github.com/Anturit/Anturidatan_visualisointi/tree/main/documentation) 22 | - [Berry Picker Tracker](https://github.com/marjanpoimijat/berry-picker-tracker-docs) 23 | - [Cast2023](https://github.com/Cast2023/cast/tree/master/documentation) 24 | - [FarmasiaVR](https://github.com/FarmasiaVR/farmasia-vr/tree/dev/Docs) 25 | - [Koululentovaraukset](https://github.com/Ohtuprojekti-Fintraffic/lentovaraukset/wiki) 26 | - [TMC-Coach](https://github.com/tmc-coach/tmc-coach/tree/main/documentation) 27 | - [Movie-Book Recommender](https://github.com/movie-book-recommender/movie-book-recommender-project/tree/main/Documentation) 28 | 29 | ### Tuotantosovellukset 30 | 31 | - [Cast2023](https://cast23.lol) 32 | - [Koululentovaraukset](https://ohtup-staging.cs.helsinki.fi/lentovaraukset/) 33 | - [Revita](https://revita.cs.helsinki.fi) 34 | - [Movie-Book Recommender](http://128.214.253.51:5000/) 35 | -------------------------------------------------------------------------------- /history/autumn2022.md: -------------------------------------------------------------------------------- 1 | ## Syksyn 2022 ohjelmistotuotantoprojektit 2 | 3 | ### Parhaat käytänteet 4 | 5 | ota mallia [täältä](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/blob/master/best-practices.md) 6 | 7 | ### Ryhmien repot 8 | 9 | - [Berrry picker tracker](https://github.com/hy-ohtu-syksy-22-bpt/) 10 | - [Vesialueen inventointi-ilmoitus](https://github.com/ohtuprojekti-2022) 11 | - [Admin application for existing Online Questionnaire tool](https://github.com/QueryAdmin-ohtu/SuperAdmin3000) 12 | - [Kokoushuoneiden varaaminen](https://github.com/ohtuprojekti-kokoushuone/kokoushuoneiden-varaaminen) 13 | - [Logomotion](https://github.com/logo-to-lego/logomotion) 14 | - [Transpilation methods for quantum computers](https://github.com/Helsinki-Qubits/Ohtu-A2022-Transpilation_methods_for_quantum_computers) 15 | - [RDM Intro platform](https://version.helsinki.fi/rdmintro/rdmintro) 16 | 17 | ### Dokumentaatio 18 | 19 | - [Berrry picker tracker](https://github.com/hy-ohtu-syksy-22-bpt/berry-picker-tracker-docs) 20 | - [Vesialueen inventointi-ilmoitus](https://github.com/ohtuprojekti-2022/vesialueen-inventointi-ilmoitus) 21 | - [Admin application for existing Online Questionnaire tool](https://github.com/QueryAdmin-ohtu/SuperAdmin3000) 22 | - [Kokoushuoneiden varaaminen](https://github.com/ohtuprojekti-kokoushuone/kokoushuoneiden-varaaminen/tree/main/documentation) 23 | - [Logomotion](https://github.com/logo-to-lego/logomotion/tree/main/documentation) 24 | - [RDM Intro platform](https://version.helsinki.fi/rdmintro/rdmintro) 25 | 26 | ### Tuotantosovellukset 27 | 28 | - [Berry picker tracker](https://berry-picker-tracker.cs.helsinki.fi) 29 | - [Vesialueen inventointi-ilmoitus](https://vesialue-front.herokuapp.com/) 30 | - [Admin application for existing Online Questionnaire tool](https://superadmin3000.herokuapp.com) 31 | - [Kokoushuoneiden varaaminen](https://reservator.ubikampus.net) 32 | - [RDM Intro platform](https://rdmintro.helsinki.fi/) 33 | -------------------------------------------------------------------------------- /history/spring2020.md: -------------------------------------------------------------------------------- 1 | ## Kevään 2020 ohjelmistotuotantoprojektit 2 | 3 | ### parhaat käytänteet 4 | 5 | ota mallia [täältä](https://github.com/ohtu-ohjaajat/OhTuHistory/blob/master/reference.md) 6 | 7 | ### Ryhmien repot 8 | 9 | - [Graafinen funktionaalinen ohjelmointikieli](https://github.com/funktionaalinen-graafinen-kieli) 10 | - [Projektiryhmäytymistyökalu](https://github.com/UniversityOfHelsinkiCS/prkl) 11 | - [Kisatehtäväpankki](https://github.com/Partioprojekti/kisatehtavapankki) 12 | - [Lunch Application](https://github.com/team-lunch-app/lunch-app) 13 | - [Maastokartoitus sovellus](https://github.com/Maastokartoitusryhma/maastokartoitus-app) 14 | - [RPA Dashboard](https://github.com/Robo-Project) 15 | - [Suorituspolut-sovellus](https://github.com/suorituspolut/Suorituspolut) 16 | - [VSCode TMC-liitännäinen](https://github.com/rage/tmc-vscode) 17 | 18 | ### Backlogit 19 | 20 | - [Graafinen funktionaalinen ohjelmointikieli](https://github.com/funktionaalinen-graafinen-kieli/backlogs/projects) 21 | - [Projektiryhmäytymistyökalu](https://github.com/UniversityOfHelsinkiCS/prkl) 22 | - [Kisatehtäväpankki](https://github.com/Partioprojekti/kisatehtavapankki) 23 | - [Lunch Application](https://docs.google.com/spreadsheets/d/1M-zd3dfMU6X8cAQRekaUWfHNRmXgxpYUZim4LKkOV8Q/edit?usp=sharing) 24 | - [Maastokartoitus sovellus](https://docs.google.com/spreadsheets/d/1m7VQjWEWSzhMSs83YdCRn0AIC5W5rsfShjiJ0MSNvu4/edit?usp=drivesdk) 25 | - [Suorituspolut-sovellus](https://docs.google.com/spreadsheets/d/10I3woz3KTBmCiSt_vDrgeIdjG_VAujJe4kMJsc5h_64/edit#gid=2097623665) 26 | - [VSCode TMC-liitännäinen](https://github.com/rage/tmc-vscode/projects/1) 27 | 28 | ### Backlogit 29 | 30 | - Projektiryhmäytymistyökalu: https://github.com/UniversityOfHelsinkiCS/prkl/projects/ 31 | 32 | ### Tuotantosovellukset 33 | 34 | - [Graafinen funktionaalinen ohjelmointikieli](http://funkly.herokuapp.com/) 35 | - [Projektiryhmäytymistyökalu](https://toska.cs.helsinki.fi/assembler/) 36 | - [Lunch Application](https://lunch-application.herokuapp.com/) 37 | - [Suorituspolut-sovellus](https://toska.cs.helsinki.fi/suorituspolut/) 38 | -------------------------------------------------------------------------------- /history/autumn2018.md: -------------------------------------------------------------------------------- 1 | ## Syksyn 2018 ohjelmistotuotantoprojektit 2 | 3 | ### Parhaat käytänteet 4 | 5 | Ota mallia [täältä](https://github.com/ohtu-ohjaajat/OhTuHistory/blob/master/reference.md) 6 | 7 | ### Ryhmien repot 8 | - [Aikavälikertaus](https://github.com/ohtu-aikavali) 9 | - [Quer.io](https://github.com/Quer-io/Quer.io) 10 | - [Rekrytyökalu](https://github.com/ohtu-rekry) 11 | - Partio 12 | - [Frontend](https://github.com/partio-scout/tosu-frontend) 13 | - [Backend (uusi)](https://github.com/partio-scout/tosu-backend-node) 14 | - [Backend (vanha)](https://github.com/partio-scout/tosu-backend 15 | - [Ohtuprojekti-ilmo](https://github.com/ohtuprojekti-ilmo) 16 | 17 | 18 | 19 | ### Dokumentaatio 20 | 21 | - Aikavälikertaus 22 | - [backlog](https://docs.google.com/spreadsheets/d/1eLOK-ZdBtr7S7bItJMD2JX7B941bgRIqcAq6uivDRaY/edit#gid=1) 23 | - Quer.io 24 | - [product backlog](https://docs.google.com/spreadsheets/d/1zoZrZ76nHl1ytfHcbrPXzbQAAnYuDqROq3syIgq6yv4/edit#gid=0) 25 | - [sprint backlog](https://docs.google.com/spreadsheets/d/1356DjMJaCLzRHgTVMD-nwnh5C8HQBULkCzGxY0TGmIg/edit#gid=0) 26 | - [drive kansio](https://drive.google.com/drive/folders/14ewSGMBRCjzhqK1nLX_qdbn0I-8p89ea) 27 | - Rekrytyökalu 28 | - [muu dokumentaato](https://drive.google.com/open?id=15oY17CYTkx-eXyyLoGN5QNCkrILjgnGNioUANWcxRZY) 29 | - [sprint backlog](https://trello.com/b/1ElKPbZ2/rekryty%C3%B6kalu) 30 | - Partio 31 | - [backlog](https://docs.google.com/spreadsheets/d/1s8WgWyk6s9hXbjHSsdBv8X7MHLPGrLpprMkqOl15yBo/edit?usp=sharing) 32 | - Ohtuprojekti-Ilmo 33 | - [Product backlog - kaikki ei julkisia](https://trello.com/b/Wv50WMSA/backlog) 34 | - [Drive](https://drive.google.com/drive/folders/1v3a2n6J6dK_4WmFbfaqIPxp1raWmBIwv) 35 | 36 | ### Sovellukset 37 | - Aikavälikertaus 38 | - [sovellus](https://opi.mooc.fi/#/login) 39 | - Quer.io 40 | - ei web-sovellusta 41 | - Rekrytyökalu 42 | - [staging](https://rekrysofta-staging.apps.emblica.com/) 43 | - Partio 44 | - [sovellus](https://suunnittelu.partio-ohjelma.fi/) 45 | - Ohtuprojekti-ilmo 46 | - [sovellus](https://studies.cs.helsinki.fi/projekti/) 47 | 48 | -------------------------------------------------------------------------------- /history/spring2018.md: -------------------------------------------------------------------------------- 1 | 2 | ## Kevään 2018 ohjelmistotuotantoprojektit 3 | 4 | ### parhaat käytänteet 5 | 6 | ota mallia [täältä](https://github.com/ohtu-ohjaajat/OhTuHistory/blob/master/reference.md) 7 | 8 | ### Ryhmien repot 9 | - [Labtool](https://github.com/labtool/labtool) 10 | - Hunt for glory 11 | - [backend](https://github.com/OhtuHunt/HuntForGlory) 12 | - [frontend](https://github.com/OhtuHunt/HuntForGloryFrontend) 13 | - Partio 14 | - [partio backend](https://github.com/partio-scout/tosu-backend) 15 | - [partio frontend](https://github.com/partio-scout/tosu-frontend) 16 | - Ruokavälitys 17 | - [backend](https://github.com/ohtu2018-rv/rv-backend) 18 | - [frontend](https://github.com/ohtu2018-rv/rv-app-frontend) 19 | - [Neural networks](https://github.com/Ohtu-project/Ohtu-neural-networks) 20 | - [3Dmaps](https://github.com/3Dmaps/3Dmaps) 21 | - [Vieraslajit.fi](https://github.com/Vieraslajit/Vieraslajit) 22 | 23 | ### Backlogit 24 | - Labtool [uusi](https://github.com/labtool/labtool/projects/1) [vanha](https://docs.google.com/spreadsheets/d/1wfYeFRiMauQRatbCnSYI_PLEFFzRq0rX9pKsR6tte3g/edit#gid=1798859574) 25 | - [Ruokavälitys](https://docs.google.com/spreadsheets/d/1a6bmQr5vvjFKoaNGr8-ilExtwjr2A6OBHpKnpp8d45Y/edit?usp=sharing) 26 | - [Partio](https://docs.google.com/spreadsheets/d/1cA-ldx-M_ppxSicxjL06BmAjhoNi5I55M5BugoUBD98/edit#gid=0) 27 | - [Hunt for glory](https://docs.google.com/spreadsheets/d/17PduZQHrmnuX6p_RP01JO7bq5TDrcI7-3gSi1h1wwI4/edit?ts=5a5c6da6#gid=0) 28 | - [Neural Networks](https://docs.google.com/spreadsheets/d/1pWFfQ25zzc4l9Z6x5c-glNwFVsxB1zB1c1MTcro23Ak/edit?usp=sharing) 29 | - [3Dmaps](https://docs.google.com/spreadsheets/d/15aIlJD48ZQKQ7nGFM40B4Lvwt3_bHjMlxDbJSRVtRH8/edit) 30 | - [Vieraslajit](https://docs.google.com/spreadsheets/d/1J_Fyd4nz4NiaO80L46lcEIjyo2mbTOU2jSYKFGTQdM4/edit#gid=0) 31 | 32 | ### Tuotantosovellukset 33 | - Ruokavälitys 34 | - [staging](https://rv-frontend-dev.herokuapp.com/) 35 | - [tuotanto](https://rv-frontend.herokuapp.com/) 36 | - labtool 37 | - [staging](https://svm-61.cs.helsinki.fi/labtool/) toimii vain laitoksen verkossa 38 | - [tuotanto](https://studies.cs.helsinki.fi/labtool/) 39 | - Partio 40 | - [Hunt for glory](http://huntforglory.herokuapp.com/) 41 | - 3DMaps - TBA 42 | -------------------------------------------------------------------------------- /history/spring2022.md: -------------------------------------------------------------------------------- 1 | ## Kevään 2022 ohjelmistotuotantoprojektit 2 | 3 | ### Parhaat käytänteet 4 | 5 | ota mallia [täältä](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/blob/master/best-practices.md) 6 | 7 | ### Ryhmien repot 8 | 9 | - [TaxonManager](https://github.com/karilint/TaxonManager) 10 | - [Sukellusilmoitus](https://github.com/Sukellusilmoitus) 11 | - [Farmasian VR-peli](https://github.com/MikkoHimanka/farmasia-vr) 12 | - [Webbipohjainen (Moodle) työkalu suullisen kielitaidon harjoitteluun](https://github.com/aalto-speech/moodle-puheentunnistus) 13 | - [Serverless data parser tool for project proposals](https://github.com/Ohtu-org/Serverless-data-parser-tool-for-project-proposals) 14 | - [Assembler - Projektiryhmäytymistyökalu](https://github.com/UniversityOfHelsinkiCS/prkl) 15 | - [XR demonstrator](https://github.com/UbiKampus-ohtu) 16 | - [Eläinlääkiksen luupeli](https://version.helsinki.fi/luupeli/Luupeli) 17 | 18 | ### Dokumentaatio 19 | 20 | - [TaxonManager](https://github.com/karilint/TaxonManager/tree/main/docs) 21 | - [Sukellusilmoitus](https://helsinkifi-my.sharepoint.com/:w:/g/personal/juhasik_ad_helsinki_fi/EcePdrwaPSdKkFvCSziiHZ8BvUHol3_TtcW4fdK60JyLJQ?e=1fDkQA) 22 | - [Farmasian VR-peli](https://github.com/MikkoHimanka/farmasia-vr/tree/dev/Docs) 23 | - [Webbipohjainen (Moodle) työkalu suullisen kielitaidon harjoitteluun](https://github.com/aalto-speech/moodle-puheentunnistus/tree/main/docs) 24 | - [Serverless data parser tool for project proposals](https://github.com/Ohtu-org/Serverless-data-parser-tool-for-project-proposals/tree/main/documentation) 25 | - [Assembler - Projektiryhmäytymistyökalu](https://github.com/UniversityOfHelsinkiCS/prkl/tree/trunk#readme) 26 | - [Eläinlääkiksen luupeli](https://version.helsinki.fi/luupeli/Luupeli/-/blob/staging/README.md) 27 | 28 | ### Tuotantosovellukset 29 | 30 | - [TaxonManager](https://Taxonmanager.it.helsinki.fi) 31 | - [Sukellusilmoitus](https://sukellusilmoitus.herokuapp.com/) 32 | - [Farmasian VR-peli](https://github.com/MikkoHimanka/farmasia-vr/releases) 33 | - [Serverless data parser tool for project proposals](https://main.dtatk8xusyguu.amplifyapp.com/) 34 | - [Assembler - Projektiryhmäytymistyökalu](https://study.cs.helsinki.fi/assembler) 35 | - [Eläinlääkiksen luupeli - ei vielä tuotannossa](http://luupeli.helsinki.fi/) 36 | -------------------------------------------------------------------------------- /itseisarvioinnin_kysymykset.md: -------------------------------------------------------------------------------- 1 | # Itsearvionnin kysymykset 2 | 3 | Ohje: Anna avovastauksiin vapaamuotoiset perustelut arvosanaehdotuksille. Voit käyttää apuna vinkkeinä annettuna esimerkkejä asioista, joihin voi kiinnittää huomiota. Voit myös kertoa vapaasti mielestäsi olennaisista asioista. 4 | 5 | ## Tekninen 6 | 7 | Arvioi ryhmäläisten teknistä kontribuutiota. Kiinnitä huomioita ainakin seuraaviin: 8 | - tehtyjen taskien määrä, vaikeusaste 9 | - osallistumisesi teknisten ratkaisujen suunnitteluun 10 | - tiimille tuomasi lisäarvo tai erityisosaaminen 11 | - projektin aikana muodostuneet vastuualueet 12 | 13 | ## Prosessin noudattaminen 14 | 15 | Scrum-tiimi sopii keskenään noudattamistaan työtavoista. Kuinka hyvin noudatit niitä? Kiinnitä huomiota ainakin seuraaviin: 16 | - Oman tekemisen läpinäkyvyys 17 | - Osallistuminen dailyihin 18 | - Product ja Sprint backlogin käyttö 19 | - DoD noudattaminen 20 | - Keskittyminen taskeihin prioriteettijärjestyksessä 21 | - Tuntikirjanpidon ajantasaisuus 22 | - Aktiivisuus sprint planningissä 23 | 24 | ## Prosessin kehittäminen 25 | 26 | Toiminnan jatkuva kehittäinen (Inspect ja Adapt) on Scrumin perusperiaate. Kerro miten kukin ryhmäläinen osallistui tiimisi työskentely prosessin parantamiseen. Kiinnitä huomioita ainakin seuraaviin: 27 | - Havaitut ongelmakohdat 28 | - Ongelmien esille tuominen esim retroissa 29 | - Ratkaisujen kehittäminen ongelmiin. Esim. backlog refinement, asiakaspalavereiden valmistautumiset, branching-käytännöt, user storyjen parantaminen, jne 30 | 31 | ## Ryhmätyö 32 | 33 | Kaikki ryhmätyöskentelyn aspektit eivät ole prosessin noudattamista tai kehittämistä. Tässä voit arvioida esim seuraavia asioita 34 | - Kyky koordinoida oma toiminta muiden kanssa 35 | - Luotettavuus, täsmällisyys 36 | - On paikalla kun on sovittu 37 | - Ilmoittaa ajoissa poikkeukset 38 | - Saa kiinni työaikojen sisällä, jos on etänä 39 | - Muiden auttaminen työnteossa; ei keskity vain omaan suoritukseen 40 | - Eri asioiden monipuolinen osaaminen tai yrittäminen (vs. siiloutuminen) 41 | - Yhteisen työskentelyn mielekkääksi tekeminen, ryhmähengen ylläpito 42 | 43 | ## Asiakastyöskentely 44 | 45 | Tärkeä osa scrum tiimin tekemistä on toimiminen asiakkaan kanssa. Kuinka hyvin kukin ryhmäläinen myötävaikutti asiakkaan kanssa työskentelyn onnistumiseen. 46 | - demojen valmistelu, demojen sujuvuus 47 | - asiallinen käytös 48 | - täsmällisyys 49 | - kommunikointi 50 | - agendan laatiminen 51 | - muistiinpanojen tekeminen 52 | - user storyjen muodostaminen asiakkaan toiveista 53 | - väli- ja loppudemoon valmistautuminen 54 | -------------------------------------------------------------------------------- /best-practices.md: -------------------------------------------------------------------------------- 1 | # Linkkejä hyviin käytänteisiin 2 | 3 | Näistä vanhojen ohtuprojektin artefakteista voi ottaa mallia omaa projektia varten. Älä kuitenkaan kopioi suoraan vaan pohtikaa mitä teidän projektinne ja tiiminne tarvitsee. Voit myös lisätä vinkkejä tekemällä pr! 4 | 5 | ## Development workflown kuvaaminen 6 | 7 | - https://github.com/OhtuKisalli/project-info/blob/master/workflow.md 8 | 9 | ## Backlog 10 | 11 | ### Product backlog 12 | Ajan kuluessa GitHub Projects on saavuttanut suosiotaan niin product kuin sprint backlogien alustana. Tässä pari esimerkkiä näistä 13 | - https://github.com/orgs/Anturit/projects/2/views/1 14 | - https://github.com/orgs/marjanpoimijat/projects/3 15 | 16 | Toinen suosittu alusta backlogeille on ollut Google Sheets. 17 | - https://docs.google.com/spreadsheets/d/1a6bmQr5vvjFKoaNGr8-ilExtwjr2A6OBHpKnpp8d45Y/edit#gid=0 18 | 19 | ### Sprint backlog 20 | 21 | Sprintti 1 aika hyvä, sprintin 2 taskijako voisi olla hienosyisempi: 22 | - https://docs.google.com/spreadsheets/d/1a6bmQr5vvjFKoaNGr8-ilExtwjr2A6OBHpKnpp8d45Y/edit#gid=166436744 23 | 24 | Loistava taskijako sprintissä 1: 25 | - https://docs.google.com/spreadsheets/d/1cA-ldx-M_ppxSicxjL06BmAjhoNi5I55M5BugoUBD98/edit#gid=1159093674 26 | 27 | ## README.md 28 | 29 | Ehkä overall paras tähänastinen 30 | - https://github.com/OhtuKisalli/project-info 31 | 32 | ### Oikeaoppinen development-ohje 33 | 34 | - https://github.com/ohtu2018-rv/rv-backend 35 | 36 | ## Dokumentaatio 37 | 38 | ### Definition of Done 39 | 40 | Riittävän perusteellinen sen suhteen että asioista on mahdollista todeta ovatko ne "done" 41 | - https://docs.google.com/document/d/1eTyUjT8rQvBWOGFAobeOJKGN3qU0LiBdK6p5i7BTWTQ/edit 42 | 43 | ### REST-apin kuvaus 44 | 45 | Muuten esimerkillinen mutta formaatiksi sopisi paremmin githubin markdown: 46 | - https://docs.google.com/document/d/1NivINt2Pj7I66VPD99HeDnT9LGFb32-2YCBa1Jmjv8w/edit 47 | 48 | ### Usecasejen kuvaus 49 | 50 | - https://drive.google.com/drive/folders/0B1wLG72sys_SQVBKSGFpNTJmX1E 51 | 52 | ### Arkkitehtuuri 53 | 54 | Melko perusteellinen, jopa hieman raskaahko dokumentti 55 | - https://docs.google.com/document/d/1MkSI6UdJo2KNHohv3ef9ym2W6n7OzVb3rv0yaz3nDZQ/edit 56 | 57 | Tiivis mutta informatiivinen 58 | - https://github.com/kehitysto/coaching-chatbot/blob/master/doc/architecture.md 59 | 60 | ### Development / Build pipeline arkkitehtuurikaavio 61 | 62 | - 404 63 | 64 | ### Käyttöönotto-ohje 65 | 66 | - https://github.com/kehitysto/coaching-chatbot/blob/master/doc/deploy-instructions.md 67 | 68 | ### Testaus 69 | 70 | Tiivis mutta aikalailla riittävä 71 | - https://github.com/kehitysto/coaching-chatbot/blob/master/doc/testing-instructions.md 72 | 73 | Olisi toki hyvä luonnehtia myös jos jokin osa ohjelmistosta jää automaattisen testauksen ulkopuolelle 74 | -------------------------------------------------------------------------------- /ohjeita-asiakaspalaveriin.md: -------------------------------------------------------------------------------- 1 | # Ohjeita asiakastapaamista varten: 2 | 3 | - **Olkaa ajoissa paikalla**. Demovastaava mieluiten puoli tuntia etukäteen varatussa luokassa katsomassa, että tekniikka on kunnossa. Yllätyksenä voi tulla, että ei saakaan kytkettyä projektoriin konetta tms. 4 | - **Tekniikka kuntoon**. Kun asiakas saapuu paikalle, projektorilla on jo jotain kamaa ja demo on kaikin puolin valmis alkamaan (sitä ei tarvitse aloittaa heti, mutta pointti on että on valmius aloittaa se välittömästi) 5 | - **Seuraavat storyt valmiina mielessä**. Viime tapaamisessa on todennäköisesti tullut esiin user storyjä, joita ei viime sprintissä tehty. Nämä user storyt on estimoitu viime kokouksen jälkeen ja asiakas on alustavasti priorisoinut ne viime kokouksessa, ja tämän perusteella tiimi voi tehdä alustavan ehdotuksen asiakkaalle siitä, mitä nyt uudessa sprintissä ollaan tekemässä. 6 | - **Suunnittelu!** Kannattaa suunnitella etukäteen, mitä demotaan ja miten. Demon on oltava asiakkaalle selkeä. Puheenjohtaja puhuu demon sisällön läpi ja demovastaava kliksuttelee taustalla. Jos demo vaatii testidataa, se on laitettu valmiiksi. Asiakkaan ei pidä joutua odottelemaan sitä, kun dataa luodaan, ellei nimenomaan demota luomistoimintoja. 7 | - **Agenda**. Asiakastapaamista varten on hyvä laatia etukäteen "agenda", joka on kirjattu ylös, jotta on selvää, missä järjestyksessä asioita käydään läpi. Agendan voi jakaa etukäteen asiakkaalle, jos kokee tarpeelliseksi. 8 | - **Harjoitusdemo**. Jos on paljon demottavaa tai on epäselvää, mitä tai miten demotaan, voi olla hyödyllistä vetää tiimin kesken "leikki-demo". 9 | - **Kirjuri**. Asiakastapaamisessa tulee esiin uusia user storyjä. Kirjuri kirjaa näitä lennosta ylös. Mieluiten tämä tapahtuisi niin, että kirjuria ei jouduta odottamaan ("oota mä kirjoitan tän ylös"). (Kirjuri voi toki tarvittaessa kysyä, että anteeksi, nyt en kuullut, tai mikä se story olikaan.) Kirjuri on siis eri henkilö kuin ne, jotka ovat pääosin äänessä. Muistiinpanot voivat olla raakoja ja sisältää miljoona typoa – ne kirjoitetaan sitten myöhemmin puhtaaksi. Kirjuri kirjaa myös muut sovitut ja puhutut asiat ylös. Tarvittaessa voi olla useampi kirjuri, jolloin kirjurien työnjako on hyvä sopia etukäteen selväksi. 10 | - **Yllätyksiä**. Jos uudet user storyt ovatkin yllättäen prioriteetiltaan korkeampia kuin ne, mitkä ovat tulleet aiemmin esiin ja mitkä on valittu alustavasti seuraavaan sprinttiin, pitää ehkä jotenkin lennosta muokata seuraavan sprintin suunnitelmaa. Miten sen voi tehdä, kun asiakaspalsussa on vähän paha lähteä vetämään mitään planning pokeria? Beats me. Tällaisissa tilanteissa joutuu improvisoimaan. 11 | - **Asiakaspalvelua**. Hommat tehdään helpoksi asiakkaalle. Asiakkaan aika käytetään tehokkaasti ja fiksusti. Asiakas saa hyvää palvelua. Tarkentavia kysymyksiä, ei yhdessä tyhjästä ihmettelyä. Asiakas hahmottaa, missä mennään. 12 | - **Follow-up / next steps**. Asiakastapaamisen lopuksi pitää ehdottomasti muistaa sopia (vähintään) seuraava tapaaminen. 13 | 14 | **No stress!** Ekat demot tulevat olemaan todennäköisesti sähläystä, joten ei stressiä, jos kaikki ei mene putkeen. Tärkeintä on inspect & adapt! Seuraavalla kerralla tehdään paremmin se, mikä meni heikommin aiemmilla kerroilla. :) 15 | -------------------------------------------------------------------------------- /openshift/OLD_README.md: -------------------------------------------------------------------------------- 1 | # OpenShift, vanha ohje 2 | 3 | > ÄLÄ LUE TÄTÄ OHJETTA 4 | 5 | Yliopistolla on käytössä OpenShift-konttialusta, jolla voi ajaa projektin testi- sekä tuotantoversioita. Konttialustan wiki-sivut löytyvät [täältä](https://wiki.helsinki.fi/xwiki/bin/view/SO/Sovelluskehitt%C3%A4j%C3%A4n%20ohjeet/Alustat/Tiken%20konttialusta/). Ohtuprojektin osallistujilla on käyttöoikeudet (sen jälkeen kun ne lisätään, eli jos tarvitsette OpenShiftiä, pyytäkää pääsyä ohjaajaltanne) konttialustan testipuolen projektiin `ohtuprojekti-staging` osoitteessa [console-openshift-console.apps.ocp-test-0.k8s.it.helsinki.fi](https://console-openshift-console.apps.ocp-test-0.k8s.it.helsinki.fi/). 6 | 7 | Usein kysyttyjä kysymyksiä https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/blob/master/openshift/faq.md 8 | 9 | Lue https://devops.pages.helsinki.fi/guides/tike-container-platform/instructions/all-in-one.html 10 | 11 | ## Esimerkkiprojektit 12 | 13 | OpenShiftiin on konfiguroitu kaksi yliopiston kirjautumista käyttävää esimerkkiprojektia ks. [github.com/UniversityOfHelsinkiCS/shibboleth-postgres-example](https://github.com/UniversityOfHelsinkiCS/shibboleth-postgres-example) sekä [github.com/UniversityOfHelsinkiCS/openid-mongo-example](https://github.com/UniversityOfHelsinkiCS/openid-mongo-example/). 14 | 15 | Jos on tarve yliopiston kirjautumiselle ks. [kirjautuminen.md](kirjautuminen.md). 16 | 17 | ## Tietokannat 18 | 19 | - [Konttialustan ohjeet](https://wiki.helsinki.fi/xwiki/bin/view/SO/Sovelluskehitt%C3%A4j%C3%A4n%20ohjeet/Alustat/Tiken%20konttialusta/3%20-%20Ohjeet/Tietokannat/) 20 | 21 | Tietokantaa voi suorittaa konttialustalla, mutta tätä ei yleensä suositella. Parempi ratkaisu on tilata Postgres-tietokanta yliopiston yhteiskäyttöklusterille ks. [wiki.helsinki.fi/xwiki/bin/view/SO/Sovelluskehittäjän ohjeet/Alustat/Yhteiskäyttöiset tietokannat/PostgreSQL/](https://wiki.helsinki.fi/xwiki/bin/view/SO/Sovelluskehitt%C3%A4j%C3%A4n%20ohjeet/Alustat/Yhteisk%C3%A4ytt%C3%B6iset%20tietokannat/PostgreSQL/). 22 | 23 | Konttialustalla toimivan tietokannan pysyväistallentaminen vaati persistent volume claimin käyttöä ks. [ohjeet]([https://wiki.helsinki.fi/pages/viewpage.action?pageId=350278065](https://wiki.helsinki.fi/xwiki/bin/view/SO/Sovelluskehitt%C3%A4j%C3%A4n%20ohjeet/Alustat/Tiken%20konttialusta/3%20-%20Ohjeet/3.8%20Levyn%20k%C3%A4ytt%C3%B6%20Tiken%20OpenShiftiss%C3%A4/)). Projektin `storageClassName` on `pomppa25`. Mallia voi katsoa esimerkkisovelluksista, joille on konfiguroitu pysyväistallennetut Postgres- ja Mongo-tietokannat. 24 | 25 | ### Tietokantaan yhdistäminen 26 | 27 | Konttialustan suuntaan avattuihin yliopiston yhteiskäyttökantoihin ei voi yhdistää OpenShiftin ulkopuolelta. Vastaavasti konttialustan sisällä ajettaville tietokannoille ei ole tarvetta luoda klusterin ulkopuolisen yhteyden mahdollistavaa `route`-resurssia. 28 | 29 | Tietokantoihin on siis yhdistettävä klusterin sisältä käsin. `ohtuprojekti-staging`-projektille on tätä varten konfiguroitu `db-tools` podi, joka sisältää manuaalisten tietokantayhteyksien kannalta tarvittavat työkalut, kuten `psql` ja `mongosh`. Podin sisälle pääsee käyttöliittymän kautta Topology-näkymästä painamalla podia `db-tools` -> View logs -> Terminal. 30 | 31 | Tietokantoihin voi yhdistää podin kautta myös komentorivityökalun `oc` avulla esim. 32 | 33 | ```bash 34 | oc exec -it $(oc get pods -l deployment=db-tools -o jsonpath='{.items[0].metadata.name}') -- psql postgres://kayttaja:salasana@possu-test.it.helsinki.fi:5432/tietokanta 35 | ``` 36 | 37 | Tämä edellyttää, että olet Eduroamissa ja kirjautunut klusteriin, ks lisää Tiken [konttialustaohjeesta](https://wiki.helsinki.fi/xwiki/bin/view/SO/Sovelluskehitt%C3%A4j%C3%A4n%20ohjeet/Alustat/Tiken%20konttialusta/). 38 | 39 | ## Sovelluksen julkaisu 40 | 41 | OpenShiftiin voi julkaista sovelluksia monella tavalla. Suositeltu ratkaisu on julkaista sovellus konttina johonkin konttirekisteriin, kuten [quay.io](https://quay.io/) tai [Docker Hub](https://hub.docker.com/). Uuden version sovelluksesta voi puskea rekisteriin automaattisesti esimerkiksi GitHub Actions:in avulla. 42 | 43 | OpenShiftin verkkokonsolin avulla voi helposti lisätä konttirekisteristä löytyvän kontin. Developer-näkymässä +Add-tabista löytyy kohta Container images. Täyttämällä vaaditut kentät OpenShift luo sovellukselle resurssit: `deployment`, `service`, `route` ja `imageStream`. 44 | 45 | Administrator-näkymässä -> Builds -> ImageStreams, muokkaa luotua `imageStream`-resurssia asettamalla `importPolicy` arvoksi `scheduled: true`. Tämän jälkeen OpenShift hakee 15 minuutin välein konttirekisteristä uudet julkaisut. 46 | 47 | Esimerkkisovelluksille on konfiguroitu Github Actions ja quay.io pohjainen julkaisuputki konttialustalle ks. [esimerkki](https://github.com/UniversityOfHelsinkiCS/shibboleth-postgres-example/blob/main/.github/workflows/staging.yaml). 48 | 49 | ### Resurssirajat 50 | 51 | Kun sovellus on lisätty OpenShiftiin aseta resurssirajat Topology-näkymässä painamalla sovelluksen podin kohdalla hiiren oikealla näppäimellä -> Edit resource limits. Podin Observe-tabista näkee nykyisen CPU:n ja RAM:in käytön, joita kannattaa käyttää hyödyksi rajoja asettaessa. 52 | 53 | Klusteri priorisoi sovelluksia, joille on asetettu resurssirajat. Jos resursseista on pulaa, niin ilman rajojen asettamista sovellus ei välttämättä edes käynnisty. 54 | 55 | 56 | ### Käyttöoikeudet 57 | 58 | OpenShift ei salli tietoturvasyistä konttien ajoa root-oikeuksilla. Suoritusaikaisen kontin käyttäjän UID on sattumanvarainen ja käyttäjä kuuluu aina root-ryhmään. Näin ollen tiedostoon voi antaa oikeudet esim. 59 | 60 | ```bash 61 | chgrp root tiedosto && chmod 660 tiedosto 62 | ``` 63 | -------------------------------------------------------------------------------- /learning-goals-of-software-engineering-lab.md: -------------------------------------------------------------------------------- 1 | # Learning goals of 'Software engineering lab' 2 | **_..and how Scrum helps us achieve them?_** 3 | 4 | ### Intro 5 | 6 | [Software engineering lab](https://courses.helsinki.fi/en/tkt20007) is one of the final courses in the bachelor's programme in Computer Science in the University of Helsinki. Students are divided into 4-6 person teams and a real customer will be assigned to each team. The team will build a piece of software according to the specifications given by the customer. The implementation requires a vast amount of skills gathered from various courses on topics like [programming](https://courses.helsinki.fi/en/tkt10002), [databases](https://courses.helsinki.fi/en/tkt10004), [web development](https://courses.helsinki.fi/en/tkt21009/) and [software engineering methods](https://courses.helsinki.fi/en/tkt20006). However the learning goals of this course are quite different from any of these. This is because coding for a customer with a team is very different from personal projects or programming course exercises. 7 | 8 | ### Personal project vs team work 9 | 10 | When you're building a personal project, you're the one who's creating the requirements and implementing them. So its simple like this: 11 | 12 |

13 | Drawing 14 |

15 | 16 | When you're building a project for a customer, then it's he or she who's creating the requirements. This means that you need to communicate in order to know what to build. And when you got a whole team doing the implementation, you need to coordinate and communicate with the team to know who's building what. That looks more like this: 17 | 18 |

19 | Drawing 20 |

21 | 22 | The students should already have the technical skills for creating software but communication and team work are not practiced much in the theoretically and technically focused programme. Communication is challenging both with the customer and within the team. The communication overhead seems amaze the students over and over again. The main learning goal of Software engineering lab may be reduced to one word - **communication**. 23 | 24 | ### Teaching communication with scrum 25 | 26 | Software used to be build with the waterfall method. This can be seen as a two step process: 1) collect requirements from the customer 2) implement the software. This has proven to be a difficult method. Agile methodologies have gained popularity and they seem to be the prevalent way of building software today. In Software engineering lab the students are also required to use agile methodologies, namely Scrum. 27 | 28 | Why do we enforce a specific framework? When we analyse the events and artefacts of Scrum we notice that they are actually methods communication. And in the two week sprints the students get to practice them efficiently in a iterative fashion. So by using Scrum the teams will practice a lot of communication. 29 | 30 | | Scrum item |Communication? | 31 | |:-----------|:---------------| 32 | | Sprint planning | Customer communicates their requirements to the team. | 33 | | Sprint review | Validating the finished work with the customer. | 34 | | Daily scrum | Coordinating within the team. What has been done? What's next? Any challenges etc? | 35 | | Retrospective | Disclose all the successes and obstacles of the last sprint to enable improving on the next one | 36 | | Product backlog | Written communication of requirements and project progress between the customer and the team. | 37 | | Sprint backlog | Written communication of sprint progress and "who's doing what". | 38 | 39 | It's useful to analyse these items also from the perspective of the _Three Pillars of Empiricism_ in Scrum: 1) Transparency 2) Inspection and 3) Adaption. Inspection and adaptation are so closely linked that we will analyse them together. 40 | 41 | **Transparency** 42 | * All of the events and artefacts of Scrum improve transparency. Transparency is almost synomous to communication in this context. Suitably extensive and accurate communication in events and artefacts results in good transparency. 43 | 44 | **Inspect & Adapt** 45 | * Review and Sprint planning 46 | * Finished work is validated _(inspect)_ and requirements are refined _(adapt)_ if necessary. 47 | * Daily scrum 48 | * Obstacles are identified _(inspect)_ and appropriate actions the taken to tackle them _(adapt)_. 49 | * Retrospective 50 | * Things enhancing and impairing teams performance are identified _(inspect)_ and practices are improved _(adapt)_. 51 | * Product backlog 52 | * Written counterpart of sprint planning & review - same aspect apply. 53 | * Sprint backlog 54 | * Written counterpart of daily scrum - same aspect apply. 55 | 56 | ### Connecting the dots 57 | 58 | By doing this analysis we are starting to see a connection: 59 | 60 | 1. Use Scrum 61 | 2. Having regural and frequent meetings and using backlogs teaches the students how to communicate better 62 | 3. Good communication → Good transparency 63 | 4. Transparency enables inspection of progress, workflow, practices etc. 64 | 5. Inspection enables adaptation. This is crucial for students or any teams to develop their skills and performance. 65 | 66 | ![steps-from-scrum-to-improvement](img/scrum-to-improvement.png) 67 | 68 | This brings us to another learning goal of the course - **continuous improvement**. The ability to make observations, analyse them and make suitable adaptations to improve is highly valuable. This is nicely embedded into the values and iterative methods of Scrum. 69 | 70 | ### Evaluation 71 | 72 | The course instructor can use following questions to evaluate team success on communication and continous improvement. Any team can use these same questions to evaluate themselves. 73 | * Are customers requirements communicated in such precision that makes completion of User Stories possible? 74 | * Are customers requirements communicated in such precision that there are no conflicting intepretations that hinder development? 75 | * Does lack of communication within the team (verbal or written) cause confusion or duplicate code? Or 'forgotten tasks'? 76 | * Does the team recognize problems in their workflow, practices, etc? 77 | * Is the team able to adapt/improve on the results of inspection? 78 | * If aspects are in good order, is this because of individual accomplishments or establised practices? 79 | -------------------------------------------------------------------------------- /ohje-hyväksymiskriteerit.md: -------------------------------------------------------------------------------- 1 | ## Hyväksymiskriteerien parhaat käytännöt 2 | 3 | ### User story formaatti 4 | 5 | User Storyn tuttu formaatti kertoo korkealla tasolla mitä toteutettava toiminnallisuus pitää sisällään ja mitä lisäarvoa se tuottaa käyttäjälle. 6 | 7 | _“As a [type of user], 8 | I want to [some goal] 9 | (so that [some reason])”_ 10 | 11 | Jos otetaan esimerkiksi jo kliseeksi muodostunut verkkokauppa, yksi User Story voisi olla vaikka 12 | 13 | _“As a shopper, 14 | I want to be able to add products to my shopping cart 15 | so that I can later order them.”_ 16 | 17 | ### User storyn laajuus 18 | 19 | Nyt herää kysymys mitä Story oikeasti pitää sisällään, eli mikä on Storyn “laajuus” (engl scope) 20 | - Näkeekö shopper jostain Shopping cartin sisällön, tuotteiden määrän tai niiden yhteissumman? 21 | - Voiko tuotteita lisätä tai poistaa? 22 | - Kuinka kauan cart muistaa sinne kerätyt ostokset? 23 | - Voiko tuotteen lisätä, vaikka sitä ei olisi varastossa? 24 | - Kerätäänkö sisällön muutoksista dataa analytiikkaa varten? 25 | 26 | On tärkeätä että tiimin kaikki jäsenet ja asiakas ovat yhtä mieltä storyjen laajuudesta. 27 | Jos storyjen laajuudesta ei ole yksimielisyyttä, on mahdotonta sanoa kuinka “valmiina” asiat ovat tai projektin valmiuden asteesta on useita näkemyksiä. 28 | Ja se taas ei ole ollenkaan hyvä asia, ketterän yksi perusperiaate on transparency, eli läpinäkyvyys ja sitä taas ei voida saavuttaa jos tiimiläiset eivät jaa yhteistä näkemystä tärkeistä asioista kuten projektin valmiusasteesta. 29 | 30 | ### Hyväksymiskriteerit 31 | 32 | User Storyn laajuus määritellään hyväksymiskriteereillä. Storya voidaan pitää valmiina vain, jos kaikki sille asetetut kriteerit täyttyvät. 33 | Hyväksymiskriteerit jaetaan kahteen yleisesti ohjelmistojen vaatimusmäärittelyssä käytettävään luokkaan: 34 | - Toiminnalliset vaatimukset 35 | - _"Mitä tekee"_ 36 | - Ei-toiminnalliset vaatimukset 37 | - _"Miten tekee"_ 38 | - Suorituskyky 39 | - Tietoturva 40 | - Datan tallennus myöhempää käyttöä varten 41 | - Dokumentaatio 42 | - Ulkonäkö 43 | 44 | Hyvä kriteeri ei ole liian yksityiskohtainen, mutta ei myöskään liian ylimalkainen. 45 | Taso on sopiva silloin, kun kriteereitä joudutaan muuttamaan vain harvoin sprintin aikana ja storyn valmistuessa väärinymmärryksiä ei ole tapahtunut. 46 | Tavallisesti kannattaa jättää pois tarkat ulkonäköön liittyvät seikat. Esimerkiksi kriteeri: 47 | 48 | _“The purchaser will see a big red box containing a message with text ‘You have insufficient funds’ 49 | when clicking the purchase button if they cannot afford the purchase.”_ 50 | 51 | on parempi muotoilla 52 | 53 | _“The purchaser will be informed that they have insufficient funds 54 | when they are attempting to make a purchase they cannot afford.”_ 55 | 56 | Hyväksymiskriteerien tulee ehdottomasti olla sellaisia, että on kaikkien tiimin jäsenten ja mielellään myös asiakkaan helppo testata täyttyykö kriteeri. 57 | **Optimaalisessa tapauksessa kriteerit ovat automaattisesti suoritettavia testejä.** 58 | Jos kriteerien toteutuminen testataan manuaalisesti, tulee kriteerien olla siten ilmaistuja, että kaikki tiimiläiset (ja asiakas) ovat yksimielisiä kriteerien täyttymisen suhteen. 59 | 60 | ### Hyväksymiskriteerien formaatti 61 | 62 | Kriteerien kirjaamiseen on olemassa useita eri tapoja, mutta tässä on esiteltynä niistä kaksi yleisesti käytettyä tapaa. Ensimmäinen tapa, Given-When-Then/Gherkin, on tuttu Ohjelmistotuotanto-kurssilta. Kriteereitä kirjoitettaisiin tällöin esimerkiksi 63 | 64 | 65 | **Scenario**: The shopper sees the total amount of products in their shopping cart
66 |   Given a shopper who has 2 products in their shopping cart
67 |   When the shopper adds an item to the cart
68 |   Then the shopper sees that they have 3 products in their shopping cart
69 | 70 | **Scenario**: The shopper sees the total price of the products shopping cart
71 |   Given a shopper who has products totaling 8,99 euros in their shopping cart
72 |   When the shopper adds an item costing 20,00 euros to their cart
73 |   Then the shopper sees that the total price of the products in the shopping cart is 28.99 euros
74 | 75 | 76 | **Scenario**: The cart is remembered for 3 days
77 |   Given a shopper who last updated their cart 3 days ago
78 |   When the shopper visits the site
79 |   Then the shopper can see their cart unchanged from their last visit
80 | 81 | **Scenario**: The cart is forgotten after 4 days
82 |   Given a shopper who last updated their cart 4 days ago
83 |   When the shopper visits the site
84 |   Then the cart will be empty
85 | 86 | **Scenario**: The cart is remembered for another 3 days after updating it
87 |   Given a shopper who last updated their cart 3 days ago
88 |   And the shopper updates their cart today
89 |   When the shopper visits the site tomorrow
90 |   Then the shopper can see their cart unchanged from their last visit
91 | 92 | Jos hyväksymiskriteerien kirjoittaminen puuduttaa niin voi googlata esim. [software requirements specification example](https://www.google.fi/search?query=software+requirements+specification+example), 93 | ihmetellä vaikka [tätä](http://www.cse.chalmers.se/~feldt/courses/reqeng/examples/srs_example_2010_group2.pdf) 60 sivuista speksausdokumenttia, 94 | ja todeta, että ei niiden hyväksymiskriteerien kirjoittaminen olekaan niin paha rasti. :D 95 | 96 | Toinen tapa ilmaista kriteerit on lyhyesti otsikkotasolla, jolloin hyväksymiskriteeriksi jää ainoastaan äskeisten esimerkkien Scenario-kohta. Kummankin tavan hyvät ja huonot puolet löytyvät pääpiirteissään alla olevassa taulukossa: 97 | 98 | 99 | | Given-When-Then/Gherkin | Pelkät otsikot | 100 | | ----------------------- | -------------- | 101 | | + Kriteereistä saadaan suoraan automatisoidut testit käyttämällä jotain Gherkiniä tukevaa ohjelmistokehystä. | + Nopea kirjoittaa | 102 | | + Hyvin eksplisiittinen, vähentää väärinymmärryksiä. | + Ohjelmiston toimintaa ei tarvitse suunnitella etukäteen yhtä tarkasti |  103 | | - Vaatii enemmän etukäteissuunnittelua | - Koska toimintaa ei tarvitse suunnitella samalla tarkkuustasolla, voi lopputulos olla ratkaisevasti erilainen kuin mitä asiakas toivoi | 104 | | - Ei sovellu hyvin ei-toiminnallisten vaatimusten määrittelyyn. | - Voivat jäädä epämääräisiksi | 105 | 106 | 107 | Joskus hyväksymiskriteerien erittäin suuri määrä saattaa kieliä siitä, että story on liian laaja. Tällöin kannattaa ehdottomasti harkita storyn jakamista. 108 | Esimerkkitapauksessamme kannattaisi story ehkä jakaa kahteen osaan. Ensimäinen kattaisi kenties ostoskorin perustoiminnallisuuden, eli suunnilleen skenaariot 109 | 110 |   **Scenario**: The shopper sees the total amount of products in their shopping cart
111 |   **Scenario**: The shopper sees the total price of the products shopping cart
112 | 113 | Jälkimmäiseen jäisivät ne osat, jotka ottaisivat tarkemmin kantaa siihen, kuinka kauan korin sisältö säilyy 114 | 115 |   **Scenario**: The cart is remembered for 3 days
116 |   **Scenario**: The cart is forgotten after 4 days
117 |   **Scenario**: The cart is remembered for another 3 days after updating it
118 | -------------------------------------------------------------------------------- /openshift/django_openid.md: -------------------------------------------------------------------------------- 1 | # Django-openid Testproject for University of Helsinki Login Service 2 | This project is an example of a Django OpenID Connect configuration for University of Helsinki login service. The app connects to a test service and does not deal with any personal information of students or personnel. 3 | The project is available in github: https://github.com/ellaverak/django-openid 4 | 5 | # The Basics 6 | 7 | OpenID Connect is an identity layer built on top of the OAuth 2.0 framework. OpenID Connect is based on configuration data that is openly available and can be read by the OAuth-client. For example the configuration data for the University of Helsinki login (test) service can be found from https://login-test.it.helsinki.fi/.well-known/openid-configuration 8 | 9 | The OAuth-client is set up using the configuration data. The Client communicates with the University of Helsinki sp-registry service responsible for distibuting user data. User data can be reached via an userinfo endpoint or it can be decoded from an id_token. 10 | 11 | # Configuration 12 | 13 | ## [pyproject.toml](https://github.com/ellaverak/django-openid/blob/main/pyproject.toml) 14 | 15 | ```authlib = "^1.2.1"``` 16 | Configuration base for the OpenID Connect client (OAuth-client). 17 | 18 | ```django-environ = "^0.11.2"``` 19 | Add-on for environemnt variables. 20 | 21 | ```psycopg2 = "^2.9.9"``` 22 | This project uses a postgres database. The database connection is created with psycopg2. 23 | 24 | ```django-cryptography = "^1.1"``` 25 | Cryptography base for the postgres database. 26 | 27 | ## [settings.py](https://github.com/ellaverak/django-openid/blob/main/project/project/settings.py) 28 | 29 | ``` 30 | LOGOUT_REDIRECT_URL = 'https://login-test.it.helsinki.fi/idp/profile/Logout' 31 | ``` 32 | 33 | Defines the logout url as the University of Helsinki logout url. When the logout url is defined in the setting it doesn't need to have it's own function in views.py. However ```path("accounts/", include("django.contrib.auth.urls"))``` needs to be added to [urls.py](https://github.com/ellaverak/django-openid/blob/main/project/openid/urls.py) 34 | 35 | ``` 36 | AUTHENTICATION_BACKENDS = ['openid.authentication.LoginBackend'] 37 | ``` 38 | 39 | Defines a custom backend for django authentication. 40 | 41 | ``` 42 | AUTHLIB_OAUTH_CLIENTS = { 43 | 'helsinki': { 44 | 'client_id': os.getenv('OIDC_CLIENT_ID'), 45 | 'client_secret': os.getenv('OIDC_CLIENT_SECRET') 46 | } 47 | } 48 | ``` 49 | 50 | Defines the name of the new OAuth-client (helsinki) and sets the client_id and client_secret parameters. The parameter values can be found from the University of Helsinki sp-registry. 51 | 52 | ## [views.py](https://github.com/ellaverak/django-openid/blob/main/project/openid/views.py) 53 | 54 | ```import urllib.request, json``` 55 | Keyset for decoding userdata from the id_token is in json format. 56 | 57 | ```from django.contrib.auth import authenticate as django_authenticate``` 58 | 59 | ```from django.contrib.auth import login as django_login``` 60 | Django's inbuild functions are importent with custom names to avoid conflict with the view-function names. 61 | 62 | ```from authlib.integrations.django_client import OAuth``` 63 | OAuth-client. 64 | 65 | ```from authlib.oidc.core import CodeIDToken``` 66 | CodeIDToken includes the instructions for decoding the id_token. 67 | 68 | ```from authlib.jose import jwt``` 69 | Used for transferring claims between the OAuth-client and the corresponding service. 70 | 71 | ``` 72 | CONF_URL = 'https://login-test.it.helsinki.fi/.well-known/openid-configuration' 73 | oauth = OAuth() 74 | oauth.register( 75 | name='helsinki', 76 | server_metadata_url=CONF_URL, 77 | client_kwargs={ 78 | 'scope': 'openid profile' 79 | } 80 | ) 81 | ``` 82 | 83 | Registers the OAuth-client (helsinki) using the openid-configuration. 84 | 85 | ``` 86 | claims_data = { 87 | "id_token": { 88 | "hyPersonStudentId": None 89 | 90 | }, 91 | "userinfo": { 92 | "email": None, 93 | "family_name": None, 94 | "given_name": None, 95 | "uid": None 96 | } 97 | } 98 | ``` 99 | 100 | Defines the claims that OAuth-client requests from the service. 101 | 102 | ``` 103 | with urllib.request.urlopen("https://login-test.it.helsinki.fi/idp/profile/oidc/keyset") as url: 104 | keys = json.load(url) 105 | ``` 106 | 107 | Gets the keyset for decoding the id_token. The url can be found from the openid configuration data: https://login-test.it.helsinki.fi/.well-known/openid-configuration 108 | 109 | ### login-function 110 | 111 | ``` 112 | redirect_uri = request.build_absolute_uri(reverse('auth')) 113 | ``` 114 | 115 | Builds the redirect url defined in the sp-registry. In this case the redirect url form is: [openshift-address]/auth/ 116 | 117 | ``` 118 | return oauth.helsinki.authorize_redirect(request, redirect_uri, claims=claims) 119 | ``` 120 | 121 | Authorizes the redirect url and provides claims to the service. 122 | 123 | ### auth-function 124 | 125 | ``` 126 | token = oauth.helsinki.authorize_access_token(request) 127 | ``` 128 | 129 | Fetches the token from the service after a successfull login. The token is a dictionary that includes the access_token, id_token etc. 130 | 131 | ``` 132 | userinfo = oauth.helsinki.userinfo(token=token) 133 | ``` 134 | 135 | The token is used to access the userinfo-enpoint. The userinfo-enpoint returns the data defined in the userinfo claims. The data is returned as a dictionary. 136 | 137 | ``` 138 | userdata = jwt.decode(token['id_token'], keys, claims_cls=CodeIDToken) 139 | userdata.validate() 140 | ``` 141 | 142 | Data from the id_token is decoded using the keys from the keyset and the instructions from the CodeIDToken. After that the data is validated and it is available as a dictionary. 143 | 144 | ``` 145 | user = django_authenticate(userinfo=userinfo, userdata=userdata) 146 | if user is not None: 147 | django_login(request, user) 148 | 149 | return redirect(home) 150 | ``` 151 | 152 | After a successful University of Helsinki login the user is logged in using a modified django-login. This ensures that the django framework works properly and the logged in user has access to django's default functionality. 153 | 154 | 155 | ## [authentication.py](https://github.com/ellaverak/django-openid/blob/main/project/openid/authentication.py) 156 | 157 | Django's default authentication backend uses usernames for authentication. This custom authentication backend chances that to emails. The backend is called after a successfull university login. 158 | 159 | 160 | ## [models.py](https://github.com/ellaverak/django-openid/blob/main/project/openid/models.py) 161 | 162 | ```from django_cryptography.fields import encrypt``` 163 | Database encryption is implemented using django-cryptography. 164 | 165 | ``` 166 | class User(AbstractUser): 167 | student_id = encrypt((models.CharField(default="000000000"))) 168 | first_name = encrypt((models.CharField(max_length = 100))) 169 | last_name = encrypt((models.CharField(max_length = 100))) 170 | email = (models.CharField(max_length = 100)) 171 | username = encrypt((models.CharField(unique=True, max_length = 100))) 172 | ``` 173 | 174 | Defines the User-model corresponding to the user relation in the postgres database. Student_id, first-name, last_name and username are encrypted. Email is saved as plain text because django uses email for custom authentication and decrypting relation data is complicated during the authentication process. 175 | 176 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ohjelmistoprojekti TKT20007 2 | 3 | Kurssin yleinen kuvaus: [courses.helsinki.fi](https://studies.helsinki.fi/kurssit/opintojakso/otm-f07aa52f-df4c-4a9a-8e89-d6222b88e2f2/TKT20007) 4 | 5 | Ohtuprojekti osallistujan silmin: syksyn 2024 NOW-tietokanta-tiimin [kertomus](https://www.youtube.com/watch?v=yrxqB_y0lMs&t=165s) 6 | 7 | [Projektien repositorioita](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/tree/master/history) 8 | 9 | ## Ajankohtaista 10 | 11 | - Kurssilla on Discord-kanava _ohtuproj_, liity nyt https://study.cs.helsinki.fi/discord/join/ohtuproj 12 | 13 | Demot syksy 2025: 14 | 15 | * Välidemo pe 17.10. klo 9.00-12 Exactum B123 16 | * Loppudemo pe 12.12. klo 9:00-12 Exactum B123 17 | 18 | Aloitus tasalta ilman akateemista varttia. 19 | 20 | Vertaisarviot: 21 | 22 | * puolessa välissä ja lopussa vertaisarvio osoitteessa [https://study.cs.helsinki.fi/projekti/peerreview](https://study.cs.helsinki.fi/projekti/peerreview) 23 | 24 | ## Tekninen tuki 25 | 26 | Ryhmille on tarjolla teknistä tukea! Kysy [discordissa](https://study.cs.helsinki.fi/discord/join/ohtuproj), kanavalla *ohtuproj_tekninen_tuki* 27 | 28 | Katso myös [OpenShift](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/tree/master/openshift)-ohje 29 | 30 | ## Arvosteluperusteet 31 | 32 | Arvostelu perustuu seuraaviin asioihin 33 | - Ryhmän sopimien työskentelytapojen noudattaminen 34 | - Ryhmän työskentelytapojen (=prosessin) kehittäminen 35 | - Ryhmätyöskentely 36 | - Tekninen kontribuutio - koodi tai asiantuntijuus 37 | - Valmistautuminen asiakastapaamisiin ja toiminta asiakaspalaverissa 38 | - Työtuntien määrä ja tasaisuus sekä merkintöjen asiallisuus (vaatimuksena noin 200 tuntia työtä koko kurssin aikana, mikä on noin 15 tuntia viikossa) 39 | 40 | Katso tarkemmat kriteerit [arvostelumatriisista](https://docs.google.com/spreadsheets/d/1fMmlOMQDZMRFMCbgGtPuXB1n9w3hXnmotDZO3n_TdUI/edit#gid=428576263) 41 | 42 | ## Projektin kulku 43 | 44 | - Noudatetaan Scrum-henkistä prosessia. 45 | - Kahden viikon välein asiakastapaaminen (Sprint Review), jonka jälkeen Sprint Planning ja Sprint Retrospective. 46 | - Mahdollisuuksien mukaan päivän aluksi Daily Scrum. 47 | - Ensimmäinen viikko ns. nollasprintti, josta lisää alempana. 48 | - Tarkastellaan jatkuvasti prosessin toimivuutta Sprint Retrospectivessä. 49 | - Transparency, Inspect & Adapt! 50 | - Ensimmäisessä asiakastapaamisessa pyritään määrittelemään [Minimum Viable Product](https://en.wikipedia.org/wiki/Minimum_viable_product), koska tarkoituksena on saada ohjelma tuotantoon mahdollisimman nopeasti. 51 | 52 | ### Nollasprintti 53 | 54 | Perustakaa **heti** jonkinlainen yhteinen TODO-lista. Kirjatkaa sinne nollasprintin tehtävät. Siellä tulisi olla ainakin nämä: 55 | - [ ] Slack, tai vastaava keskustelualusta pystyyn. 56 | - Ohjaajalle kutsu 57 | - [ ] Product backlogin laatiminen 58 | - [ ] Sprint Task Board / Sprint backlog (fyysinen tai sähköinen) 59 | - [ ] Tuntikirjanpito, josta näkee jokaiseen viikkoon käytetyt tunnit opiskelijoittain, Kirjaukset tehdään [timelogs](https://study.cs.helsinki.fi/projekti/timelogs) -palvelussa kuluvan sprintin aikana - mieluiten päivittäin. 60 | - [ ] Luokaa GitHub-organisaatio ja repository 61 | - [README standardin mukaiseksi](https://guides.github.com/features/wikis/), lisäksi "päärepoon" linkit muihin repositorioihin, backlogiin sekä sovellukseen. 62 | - [ ] Sopikaa käytettävät teknologiat 63 | - Huom! Asiakkailla voi olla mielipide käytettävistä teknologioista tai koodauskäytännöistä. 64 | - [ ] CI- ja staging-ympäristö mahdollisimman nopeasti pystyyn 65 | - [ ] Branching-käytännöistä sopiminen 66 | - Hyvä käytäntö on pitää master-haarassa vain tuotantokelpoista (deployable) koodia. Näin voidaan aina siirtää koodi staging-palvelimelle (ja myöhemmin tuotantoon.) 67 | - Ohtuprojektien [OpenShift-konttialustaa](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/tree/master/openshift) voi käyttää staging-ympäristönä, erityisesti jos asiakas HY:llä 68 | - [ ] Koodauskäytännöt 69 | - Sopikaa Definition of Done 70 | - Pitää olla sellainen, että DoDin kriteerit täyttävä story voitaisiin viedä sellaisenaan tuotantoon! 71 | - Huom: DoD:ia voi päivittää tiukemmaksi projektin edetessä 72 | - [ ] Valituilla teknologioilla toteutettu "hello world" / [Walking skeleton](http://wiki.c2.com/?WalkingSkeleton) -sovellus staging-ympäristöön. 73 | - _"A Walking Skeleton is a tiny implementation of the system that performs a small end-to-end function"_ 74 | 75 | ## Kurssin vaatimuksia 76 | 77 | ### Backlogit 78 | 79 | - **DEEP** Product Backlog pitää olla [DEEP](https://www.romanpichler.com/blog/make-the-product-backlog-deep/). 80 | - **User storyt** Vaatimukset User Story -muodossa. INVEST on tärkeä! 81 | - **Hyväksymiskriteerit** Storylla pitää olla hyväksymiskriteerit (Acceptance critieria), jos se on Product Backlogissa korkealla (=tulee kohta tehtäväksi). Kriteerit kannattaa käydä läpi koko tiimin ja asiakkaan kanssa, vaikka kaikkia ei tarvitse kirjoittaa asiakkaan läsnäollessa. Lue hyvistä käytännöistä alla. 82 | - lue lisää hyväksymiskriteereistä omasta [ohjeestaan](https://github.com/ohtu-ohjaajat/opiskelijalle/blob/master/ohje-hyv%C3%A4ksymiskriteerit.md) 83 | - **Storyjen seuranta** Seurataan missä sprintissä valmistuneen storyn tekeminen on aloitettu. Tarkoituksena on, että kaikki storyt olisivat valmiita samassa sprintissä kuin ne on aloitettu, mutta metriikoiden optimointi ei saa missään nimessä olla itsetarkoitus — storyn pitää olla aidosti laadukkaasti tehty ja muilta osin valmis ennen kuin se lasketaan tehdyksi. 84 | 85 | ### Scrum-tapaamiset 86 | 87 | - Sprint planning 88 | - Sprint review 89 | - Retrospektiivi 90 | - Daily 91 | 92 | ### Koodi 93 | 94 | - **Open source** 95 | - **GitHub** Ohjaajan päästävä näkemään lähdekoodi ja commitit 96 | 97 | ### Deployment environments 98 | 99 | - **Staging-ympäristö** mahdollisimman tuotannon kaltainen. 100 | - ks [ohtuprojektin OpenShift](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/tree/master/openshift) 101 | - **Tuotantoon!** Tuotos täytyy saada tuotantoon jo projektin aikana, mielellään mahdollisimman nopeasti. 102 | - **CD** Tuotantoon päivityksen pitää olla [tehokasta ja/tai jatkuvaa](https://puppet.com/blog/continuous-delivery-vs-continuous-deployment-what-s-diff) 103 | - **Demot stagingista tai tuotannosta** Asiakkaalle demotaan ainoastaan vain ja ainoastaan staging- tai tuotantopalvelimelta, ei omalta koneelta. 104 | - **Testaus** 105 | - Automaatiotestauksen pitää olla riittävän kattava ja hyvin toteutettu 106 | - Kaikkien yksikkötestien ajaminen on hyvä kestää korkeintaan muutaman minuutin. Korkeamman tason testien, kuten UI-testien ajo saa kestää pidempään, eikä niitä tarvitse ajaa yhtä usein. 107 | - Erittäin tärkeä konsepti on ns. testipyramidi http://martinfowler.com/bliki/TestPyramid.html. Parin minuutin lukeminen voi säästää kymmeniä tunteja aikaa. 108 | - Testikoodin laatu tulee mielellän olla yhtä hyvää kuin muunkin koodin. 109 | 110 | ### Työtunnit 111 | 112 | - **Tuntikirjapito** Kurssin aikana seurataan tuntimääriä. Työtunneiksi lasketaan myös tapaamiset, esim. tiimin kanssa yhdessä lounastamiset ja itseopiskelu. 113 | - Kirjaukset tehdään [timelogs](https://study.cs.helsinki.fi/projekti/timelogs) -palvelussa kuluvan sprintin aikana - mieluiten päivittäin. 114 | - Lähtökohtaisesti *työtunteja ei voi merkitä edelliselle sprintille*, vaan ne jää silloin merkitsemättä. 115 | - Huomaathan, että sprintti vaihtuu tasan kello 0:00. 116 | - **Tasaisuus** Ehdottomana vaatimuksena työmäärien tasaisuus viikkotasolla, eli tuntimäärän kuuluu olla viikosta toiseen suunnilleen sama. Sairastumiset yms. neuvoteltava poikkeus. Ilmoita reilusti etukäteen jos tiedät, että osallistumisesi viikon töihin estyy jollain tapaa. 117 | - **Kurssi = 200h** Vaatimuksena noin 200 tuntia työtä koko kurssin aikana, mikä on noin 15 tuntia viikossa. 118 | 119 | ### Sekalaisia vaatimuksia 120 | 121 | - **Commit esiin** Varmista että committisi näkyvät GitHubissa oikein. Ks. [ohje](https://github.com/mluukkai/ohjelmistotuotanto2018/wiki/miniprojektin-arvosteluperusteet#commitit-kadoksissa) 122 | - **Kunnioita** kanssaopiskelijoitasi, kyseessä ei ole yksilökurssi. 123 | - Käyttäydy samojen standardien mukaan kuin olisit töissä. 124 | - Sovittuihin yhteisiin tapaamisiin pitää tulla. Myöhästymisistä, esteistä yms. pitää ilmoittaa ajoissa. 125 | - Siiloutumista tulee välttää. Koodikatselmoinnit! 126 | - **Arvot ja käytännöt** 127 | - Ryhmän sovittava yhteiset käytännöt. Ks. [esimerkki](https://github.com/ohtu-ohjaajat/opiskelijalle/blob/master/tiimin_kaytanteet.md) 128 | - **Asiakastapaamiset** 129 | - **Tilavaraukset** Ensimmäisen asiakastapaamisen jälkeen ryhmä on vastuussa asiakastapaamisten järjestämisestä. Tarvittaessa tilavaraus tiettyihin kokoushuoneisiin voidaan hoitaa ohjaajan kautta. 130 | - **Agenda** Asiakastapaamisiin kannattaa luoda melko yksityiskohtainen agenda, joka on hyvä lähettää asiakkaalle jo ennen asiakastapaamista. 131 | - **Roolit** Kiertävä puheenjohtajan roolit. Lisäksi ainakin kirjuri ja demovastaava. 132 | * **Muistiinpanot** Asiakastapaamisista tehtävä muistiinpanot. Keskusteltuja asioita ei saa jättää muistin varaan vaan ne tulee kirjata backlogille. 133 | - [Vinkkejä asiakaspalaveriin](ohjeita-asiakaspalaveriin.md) 134 | - **Retrospektiivit dokumentoitava** 135 | - Ohjaajan oltava paikalla jokaisessa retrospektiivissä. Doodlaus tiimin vastuulla. 136 | - **"Kamerapakko"** 137 | - Etäyhteydellä tapahtuvissa asiakastapaamisissa, retrospektiiveissä ja dailyissä on pidettävä kamera päällä. 138 | 139 | ## Projektin tavoite 140 | 141 | - Ryhmätyötaitojen harjoittelu. 142 | - Tehtävien ja työn jakaminen 143 | - Kommunikaatio 144 | - Organisointi 145 | - Ohjelmistotuotantomenetelmien käytännön harjoittelu. 146 | - Yhteisen codebasen kanssa työskentely (git) 147 | - Deployment 148 | - Ketterät toimintatavat 149 | - Transparency 150 | - Inspect & Adapt 151 | - [Miksi Scrum?](learning-goals-of-software-engineering-lab.md) Kirjoitus ohtuprojektin tavoitteista ja miten scrum auttaa niiden saavuttamisessa. 152 | 153 | ## Vinkkejä 154 | - Töitä kannattaa tehdä mahdollisimman paljon muiden kanssa fyysisesti samassa tilassa. 155 | - Sprintin aikana on hyvä olla tekeillä ainoastaan 2-3 storya kerrallaan. Tällöin storyt valmistuvat varmemmin. Muutama valmis > melkein kaikki kesken. 156 | - Ohjelmiston arkkitehtuuriin kannattaa kiinnittää paljon huomiota ja jättää sprinttiin aikaa tehdä parannuksia sisäiseen laatuun. Puhdas User Story -hikipaja, jossa keskitytään ainoastaan mahdollisimman nopeaan ominaisuuksien tuottamiseen ei pitkällä tähtäimellä tuota hyviä tuloksia. 157 | - Voi olla hyvä idea hahmotella hyväksymiskriteerit ennen varsinaista asiakastapaamista. Kannattaa kuitenkin jättää hieman pureskeltavaa kriteereihin ennen tapaamista. 158 | - On hyvä käytäntö pitää agenda näkyvillä asiakastapaamisen aikana, jotta keskustelu saadaan pysymään paremmin aiheessa. Käydään kokouskäytäntöjä tarpeen mukaan läpi yhdessä. 159 | - [Vinkkejä asiakaspalaveriin](ohjeita-asiakaspalaveriin.md) 160 | - [ohtuprojektin OpenShift-konttialusta](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/tree/master/openshift) 161 | - Eräs hyväksi havaittu sovellus retrojen pitoon on 162 | 163 | ## Roolit 164 | 165 | [Rooleista](roolit.md) 166 | 167 | ## Käytännön ohjeita 168 | 169 | - **Tilat:** 170 | - DK107 eli "Luola" ensisijaisesti ohtuprojektiryhmien käytössä 171 | - Myös muita saleja voi käyttää: esim B221 (yläpaja), BK107 (alapaja), C221, DK108 (haxo) 172 | - **Sali asiakaspalaverille:** Palaverin voi pitää tiimitilassa tai "neukkarissa". Pyydä tilavaraus Luukkaiselta (email tai discord) tai kysy ohjaajalta. Myös kirjaston ryhmätyötiloja voi käyttää. Varausohjeet: http://www.helsinki.fi/kirjasto/fi/asioi/tyoskentele-kirjastossa/ryhmatyotilat/ 173 | 174 | ## Ohtuprojekti staging 175 | 176 | Staging nykyään Tiken [OpenShift](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/blob/master/openshift/README.md)-klusterissa 177 | 178 | ## Parhaat käytänteet 179 | 180 | Aina ei tarvitse keksiä pyörää uudelleen - katso vinkkejä [täältä](best-practices.md) tai [edellisten ryhmien repoista](history/). 181 | -------------------------------------------------------------------------------- /openshift/kirjautuminen.md: -------------------------------------------------------------------------------- 1 | # Yliopistokirjautuminen 2 | 3 | Jos projekti vaatii yliopiston kirjautumista, vaihtoehdot ovat käytännössä SAML-pohjainen Shibboleth-kirjautuminen tai modernimpaan OAuthiin ja OpenID Connectiin (OIDC) perustuva ratkaisu. Tutustutaan seuraavassa modernimpaan ratkaisuun. 4 | 5 | Muutetaan sovellusta siten, että jos käyttäjä ei ole kirjautunut, ei nollausnappia näytetä. 6 | 7 | 8 | 9 | Kun käyttäjä kirjautuu, on nollaaminen mahdollista. 10 | 11 | 12 | 13 | Koodi on kokonaisuudessaan GitHubissa haarassa [login](https://github.com/mluukkai/openshift-demo/tree/login?tab=readme-ov-file). 14 | 15 | Katsotaan ensin kirjautumista frontendin kannalta. 16 | 17 | Sovellus kysyy aina etusivulle tultaessa kirjautuneen käyttäjän tietoja tekemällä HTTP GET -pyynnön osoitteeseen `/api/user`. 18 | 19 | Pyyntö on toteutettu Reactille tyypillisellä tavalla, eli `useEffect`-hookissa: 20 | 21 | ```js 22 | useEffect(() => { 23 | axios.get('/api/user') 24 | .then(response => { 25 | setUser(response.data) 26 | }) 27 | .catch(error => { 28 | console.log('not logged in') 29 | }) 30 | }, []) 31 | ``` 32 | 33 | Jos käyttäjä on kirjautunut, palauttaa `/api/user` käyttäjän, joka talletetaan tilaan `user` kutsumalla funktiota `setUser`. 34 | 35 | Jos käyttäjä ei ole kirjautunut, on tilan `user` arvona `null`. Eri napit näytetään tämän perusteella. 36 | 37 | Sisään- ja uloskirjautumisen napinkäsittelijät ovat seuraavassa: 38 | 39 | ```js 40 | const onLogin = () => { 41 | window.location.href = '/api/login' 42 | } 43 | 44 | const onLogut = async () => { 45 | await axios.post('/api/logout') 46 | setUser(null) 47 | } 48 | ``` 49 | 50 | Sisäänkirjautuessa vaihdetaan selaimen osoiteriville `/api/login`. Tämä saa aikaan sen, että selain tekee HTTP GET -pyynnön tähän osoitteeseen. Kirjautuminen on pakko tehdä näin sen sijaan että pyyntö tehtäisiin JavaScript-koodista (lisätietoa esim. [täällä](https://community.auth0.com/t/cors-error-when-initiating-silent-auth-requests/103208)). 51 | 52 | Kirjautumisen yhteydessä backend tekee selaimelle uudelleeohjauksen sovelluksen juuriosoitteeseen `/`. Tämän ansiosta sovellus tekee heti pyynnön `/api/user` ja saa kirjautuneen käyttäjän tiedot. 53 | 54 | Uloskirjautuminen tapahtuu tekemällä HTTP POST -pyyntö backendiin ja asettamalla tilan `user` arvoksi `null`. 55 | 56 | ## Backend passport-kirjastoa käyttäen 57 | 58 | Tarkastellaan seuraavaksi backendin koodia. Backend käyttää kirjautumisen apuna [passport](https://www.passportjs.org/)-kirjastoa. Jos käytät jotain muuta kuin Node/Expressiä backendin toteutukseen, joudut turvautumaan Googleen ja kielimalleihin. 59 | 60 | Toteutus edellyttää seuraavien kirjastojen asentamista: 61 | 62 | ``` 63 | passport 64 | express-session 65 | passport-openid 66 | openid-client@5.4.3 67 | ioredis 68 | connect-redis 69 | ``` 70 | 71 | Backend käyttää [Redis](https://redis.io/)-avain-arvo-tietokantaa kirjautuneiden käyttäjien sessioiden tietojen tallettamiseen. Redisistä huolehtiva deployment ja service löytyvät [täältä](https://github.com/mluukkai/openshift-demo/blob/login/manifests/redisdeployment.yaml). Määrittely on suoraviivainen, ainoa huomionarvoinen seikka on käytössä oleva image `registry.redhat.io/rhel9/redis-7` jota joudumme käyttämään OpenShiftin rajoitusten takia sillä Dockerhubissa oleva image suorittaa koodia root-tilassa ja se aiheuttaa ongelman OpenShiftin oikeuksien suhteen. 72 | 73 | Aluksi määritellään Redis, sekä [sessioista](https://www.passportjs.org/concepts/authentication/sessions/) vastaava middleware passportin käyttöön: 74 | 75 | ```js 76 | const passport = require('passport') 77 | const session = require('express-session') 78 | 79 | const SESSION_SECRET = process.env.SESSION_SECRET 80 | const REDIS_HOST = process.env.REDIS_HOST 81 | 82 | const redis = new Redis({ 83 | host: REDIS_HOST, 84 | port: 6379, 85 | }) 86 | 87 | app.use(session({ 88 | secret: SESSION_SECRET, 89 | resave: false, 90 | saveUninitialized: false, 91 | store: new RedisStore({ client: redis }), 92 | })) 93 | 94 | app.use(passport.initialize()) 95 | app.use(passport.session()) 96 | ``` 97 | 98 | Kirjautumista ja käyttäjänhallintaa varten tarvitaan neljä routea: 99 | 100 | ```js 101 | app.get('/api/login', passport.authenticate('oidc')) 102 | 103 | app.get('/api/login/callback', passport.authenticate('oidc', { failureRedirect: '/' }), (req, res) => { 104 | res.redirect('/') 105 | }) 106 | 107 | app.post('/api/logout', (req, res, next) => { 108 | req.logout((err) => { 109 | if (err) { return next(err); } 110 | res.redirect('/'); 111 | }); 112 | }); 113 | 114 | app.get('/api/user', async (req, res) => { 115 | console.log('User:', req.user) 116 | if (req.user) { 117 | res.json(req.user); 118 | } else { 119 | res.status(401).json({ message: 'Unauthorized' }); 120 | } 121 | }); 122 | ``` 123 | 124 | Ensimmäinen route ohjaa HTTP GET `/api/login` -pyynnön yliopiston kertakirjautumispalveluun. Routeista toinen on _takaisinkutsuroute_, jota kertakirjautuminen kutsuu kirjautumisen onnistuessa. Kirjautumisen yhteydessä passport suorittaa kirjautumistoimenpiteet (joiden koodiin palaamme kohta), sekä tallettaa tiedon kirjautuneesta käyttäjästä sessioon, eli käytännössä selaimelle asetettavaan evästeeseen. Sovellus uudelleenohjataan juurisoitteeseen `/`, joka saa siis aikaan sen, että selain tekee uuden pyynnön osoitteeseen `/api/user` joka kirjautumisen ansiosta voi palauttaa `req.user`:iin passportin asettaman kirjautuneen käyttäjän. 125 | 126 | Uloskirjautumisen route on yksinkertainen. Se kutsuu funktiota [req.logout](https://www.passportjs.org/concepts/authentication/logout/), ja ohjaa selaimen juuriosoiteeseen (joka ei tapauksessamme ole aivan välttämätöntä). 127 | 128 | Käynnistyessään sovellus vielä alustaa autentikoinnin kutsumalla erillisessä tiedostossa määriteltyä funktiota: 129 | 130 | ```js 131 | app.listen(PORT, async () => { 132 | const { setupAuthentication } = await import('./oicd.mjs'); 133 | 134 | await setupAuthentication() 135 | // ... 136 | } 137 | ``` 138 | 139 | Oleelliset osat tiedostosta `oicd.mjs` (joka käyttää JavaScriptin ES-moduuleita) näyttävät seuraavalta: 140 | 141 | ```js 142 | const verifyLogin = async (_tokenSet, userinfo, done) => { 143 | console.log('userinfo', userinfo) 144 | 145 | const user = { 146 | id: userinfo.sub, 147 | username: userinfo.uid, 148 | name: userinfo.name, 149 | } 150 | 151 | // save user to db if that is required in your app 152 | 153 | done(null, user) 154 | } 155 | 156 | export const setupAuthentication = async () => { 157 | const client = await getClient() 158 | 159 | const object = { 160 | cn: { essential: true }, 161 | name: { essential: true }, 162 | given_name: { essential: true }, 163 | hyGroupCn: { essential: true }, 164 | email: { essential: true }, 165 | family_name: { essential: true }, 166 | uid: { essential: true }, 167 | } 168 | 169 | const params = { 170 | scope: 'openid profile email', 171 | claims: { 172 | id_token: object, 173 | userinfo: object, 174 | }, 175 | } 176 | 177 | passport.use('oidc', new openidClient.Strategy({ client, params }, verifyLogin)) 178 | } 179 | ``` 180 | 181 | Määrittelyn ytimessä on funktio [verifyLogin](https://www.passportjs.org/concepts/authentication/openid/), joka suoritetaan onnistuneen kirjautumisen yhteydessä. Funktion toinen parametri on kirjautumispalvelun palauttama kirjautuneen käyttäjän tiedot. Jos käyttäjien tiedot on esim. tarve tallettaa tietokantaan, tallennus tulee tehdä tässä kohtaa jos kirjautunutta käyttäjää ei vielä tietokannasta löydy. Funktion lopussa kutsutaan kolmatta parametria antamalla kutsussa parametrina ne tiedot joita passportin halutaan palauttavan kutsun `req.user` yhteydessä (jota käytettiin reitin GET `/api/user` käsittelijässä). 182 | 183 | Tiedoston [oidc.mjs](https://github.com/mluukkai/openshift-demo/blob/login/server/oicd.mjs) metodissa `getClient` konfiguroidaan kirjautumispalvelimelle yhteydessä oleva openidClient, joka konfiguroidaan sovelluksen kertakirjautumisjärjestelmään määritellyillä arvoilla. 184 | 185 | Kertakirjautuminen konfiguroidaan osoitteessa , painamalla nappia _Add a new OICD relying party_. 186 | - Käyttöoikeuksista [käyttöohje](https://wiki.helsinki.fi/xwiki/bin/view/SO/User%20management/SP%20Registry) sanoo seuraavasti: _If you are not verified as a university employee during login, please contact atk-autentikointi@helsinki.fi after login, so that an administrator can add the necessary user rights for you. If necessary, an administrator can also create local usernames for SP-Registry._ 187 | 188 | Mallia voi ottaa tiedostoista [conf1.png](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/blob/master/openshift/images/conf1.png) ja [conf2.png](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/blob/master/openshift/images/conf2.png). Huomaa, että urlit ovat kuvissa hieman väärässä muodossa. Oikea alkuosa urleille on `https://demoapp-toska-playground.ext.ocp-test-0.k8s.it.helsinki.fi`. 189 | 190 | Sovelluksen käyttämät attribuutit, eli kirjautumispalvelulta pyydettävät käyttäjäkohtaiset arvot määritellään välilehdellä _Attributes_: 191 | 192 | 193 | 194 | Selitys attribuuttien merkityksestä on [täällä](https://wiki.helsinki.fi/xwiki/bin/view/SO/User%20management/User%20attributes/). Lisää jonkinlaista ohjeistusta SP-registryn käyttöön on [täällä](https://wiki.helsinki.fi/xwiki/bin/view/SO/User%20management/SP%20Registry/). 195 | 196 | Client secretin arvo löytyy välilehden _Technical attributes_ alaosasta. 197 | 198 | Salaisuuksien arvot on määritelty sovellukselle tiedostossa `configmap.yaml`. 199 | 200 | ```yaml 201 | apiVersion: v1 202 | kind: ConfigMap 203 | metadata: 204 | name: demoapp-config 205 | data: 206 | DB_URL: postgresql://ohtuprojektitesti:passwordhere@hostnamehere:5432/ohtuprojekti?targetServerType=primary&ssl=true 207 | OIDC_CLIENT_ID: id_valuesehe_see_the_spregistry 208 | OIDC_CLIENT_SECRET: secret_secretvaluehere_see_the_spregistry 209 | OIDC_REDIRECT_URI: https://demoapp-toska-playground.ext.ocp-test-0.k8s.it.helsinki.fi/api/login/callback 210 | OIDC_ISSUER: https://login-test.it.helsinki.fi/.well-known/openid-configuration 211 | REDIS_HOST: redis-svc 212 | SESSION_SECRET: randomsecretstringhere 213 | ``` 214 | 215 | Muutetaan tiedostoa `deployment.yaml` siten, että se antaa samantien kaikki configmapin määrittelemät ympäristömuuttujat podille: 216 | 217 | ```yaml 218 | spec: 219 | containers: 220 | - name: demoapp 221 | image: demoapp:login 222 | imagePullPolicy: Always 223 | ports: 224 | - containerPort: 3000 225 | envFrom: 226 | - configMapRef: 227 | name: demoapp-config 228 | ``` 229 | 230 | ## Backend ilman kirjastoja käyttäen 231 | 232 | Esimerkissä käytetty passport-kirjasto piilottaa monia kirjautumiseen liittyviä yksityiskohtia. Jos käytät jotain muuta kuin JavaScript-pohjaista teknologiaa yliopistokirjautumiseen, ei passport-esimerkistä välttämättä ole kovin paljon hyötyä. Sovelluksesta on olemassa versio, joka tekee kertakirjautumisen ilman mitään kirjastoa, käyttäen ainoastaan HTTP GET- ja POST-pyyntöjä. Versio löytyy branchista [oidc](https://github.com/mluukkai/openshift-demo/tree/oidc). Sen tutkiminen voi olla hyödyksi jos toteutat kertakirjautumista esim. Python Flaskilla. 233 | 234 | ## Sovelluskehitys paikallisella koneella ja kertakirjautuminen 235 | 236 | Kertakirjautuminen aiheuttaa pienen haasteen sovelluksen kehittämiselle omalla koneella. Eräs ratkaisu tähän on ohittaa OpenID ja kovakoodata kirjautumsen tiedot backendiin. Tämä on tehty nyt tiedostoon [index.js](https://github.com/mluukkai/openshift-demo/blob/login/server/index.js#L67) seuraavasti: 237 | 238 | ```js 239 | let loggedIn = false 240 | 241 | if (process.env.NODE_ENV !== 'production') { 242 | const setMocUser = (req, res, next) => { 243 | if (!loggedIn) { 244 | return next() 245 | } 246 | 247 | req.user = { 248 | "id": "2Q6XGZP4DNWAEYVIDZV2KLXKO3Z4QEBM", 249 | "username": "mluukkai-test", 250 | "name": "Matti Luukkainen" 251 | } 252 | next() 253 | } 254 | 255 | app.use(setMocUser) 256 | 257 | app.get('/api/login', (req, res) => { 258 | loggedIn = true 259 | res.redirect('/'); 260 | }) 261 | 262 | app.post('/api/logout', (req, res, next) => { 263 | loggedIn = false 264 | res.redirect('/'); 265 | }); 266 | } 267 | 268 | // normaalisti käytettävät routet 269 | ``` 270 | 271 | Jos sovellus ei ole tuotannossa, eli `process.env.NODE_ENV !== 'production'` määritelläänkin käyttäjän feikkaava middleware sekä endpointit `/api/login` ja `/api/logout`. Kun kirjautuminen tehdään, asetetaan `loggedIn = true`, ja middleware lisää `req.user`:n arvoksi kovakoodatun käyttäjän. 272 | 273 | Esimerkissä on nyt kirjoitettu lähes kaikki koodi yhteen tiedostoon. Tämä ei tietenkään ole ohtuprojektissa järkevää, ja eri asiat, mm. tietokantayhteyksien avaaminen ja erityisesti feikkikirjautuminen on hyvä eriyttää omiin moduuleihinsa. 274 | -------------------------------------------------------------------------------- /openshift/README.md: -------------------------------------------------------------------------------- 1 | ## OpenShift-konttialustan käyttö staging-ympäristönä 2 | 3 | Tämä ohje olettaa, että hallitset jossain määrin Dockeria, esim. vähintään luvun _Docker basics_ verran kurssilta [DevOps with Docker](https://courses.mooc.fi/org/uh-cs/courses/devops-with-docker). Docker-kurssi jatkuu vielä 16.6. asti, seuraava versio kurssista alkaa toisen periodin alussa. Jokaisen käpistelijän kannattaa ehdottomasti suorittaa kurssi! 4 | 5 | Jos käytät fuksiläppäriä ja koneellasi ei ole jo Dockeria asennettuna, seuraa [tätä](https://version.helsinki.fi/cubbli/cubbli-help/-/wikis/Docker) ohjetta! 6 | 7 | ### Esimerkkisovellus 8 | 9 | Seuraavassa asennetaan yliopiston tietotekniikkakeskuksen OpenShift-klusterille Reactilla ja NodeJS:llä toteutettu SPA-sovellus, jonka koodi löytyy [GitHubista](https://github.com/mluukkai/openshift-demo). 10 | 11 | Sovellus on hyvin yksinkertainen laskuri. Laskurin arvo on talletettu Postgres-tietokantaan, johon backend on yhteydessä [Sequelize](https://sequelize.org/)-kirjaston avulla. Frontend sisältää napit laskurin kasvattamiseen sekä nollaamiseen. Käytössä ovat siis kurssilta [Full stack open](https://fullstackopen.com/) tutut teknologiat. 12 | 13 | Projektiin on määritelty GitHub Action -workflow, joka luo projektista Docker-imagen ja pushaa sen Dockerhubiin. Sama image sisältää sekä backendin, että frontendin. 14 | 15 | Sovellus on GitHubissa siinä tilanteessa mihin tämä tutoriaali päättyy. Alkutilanne on branchissa [start](https://github.com/mluukkai/openshift-demo/tree/start). Koodissa ei muutoksia ole, mutta tutoriaalin aikana tehdyt konfiguraatiot puuttuvat vielä haarasta start. 16 | 17 | ### OpenShift 18 | 19 | Käytössämme on Tietotekniikkakeskuksen [OpenShift](https://devops.pages.helsinki.fi/guides/platforms/tike-container-platform.html)-klusteri. OpenShift on [Kubernetes](https://github.com/mluukkai/openshift-demo/blob/main/.github/workflows/main.yaml)-klusteri tietyin lisämaustein. 20 | 21 | Kubernetes on melko monimutkainen olio, kurssi [DevOps with Kubernetes](https://devopswithkubernetes.com/) käsittelee aihetta laajasti. Seuraavassa käydään läpi minimioppimäärä yksinkertaisen sovelluksen tarpeisiin. 22 | 23 | Ytimessä olevan Kuberneteksen lisäksi OpenShift sisältää mm. graafisen käyttöliittymän, jonka kautta konfiguraatioita on mahdollista tehdä, mutta se **ei ole suositeltua** sillä näin päädytään usein hallitsemattoman epämääräisiin konfiguraatioihin. On suositeltavaa pitäytyä määrittelyissä mahdollisimman "puhtaassa" Kuberneteksessa, ja näin tulemme seuraavassakin tekemään. 24 | 25 | > [!CAUTION] 26 | > Älä määrittele mitään OpenShiftin käyttöliittymän kautta. 27 | > Jos teet näin, teknistä tukea ei kurssin puolesta ole luvassa. 28 | 29 | Käytämme klusteria yksinomaan komentoriviltä, komennon [oc](https://docs.redhat.com/en/documentation/openshift_container_platform/4.11/html/cli_tools/openshift-cli-oc) avulla. `oc` toimii samoin kun Kubernetesin [kubectl](https://kubernetes.io/docs/reference/kubectl/), mutta se sisältää muutamia OpenShift-spesifejä komentoja. 30 | 31 | Asenna nyt koneellesi `oc` [tämän ohjeen](https://devops.pages.helsinki.fi/guides/platforms/tike-container-platform.html#openshift-client) mukaan. Kannattaa myös ehdottomasti konfiguroida [tabulaattoritäydennys](https://docs.redhat.com/en/documentation/openshift_container_platform/4.9/html/cli_tools/openshift-cli-oc#cli-enabling-tab-completion). 32 | 33 | Oletetaan nyt, että `oc` asennettu. Jotta yhteys klusteriin toimisi, on oltava Eduroamissa tai HY:n vpn:ssä. 34 | 35 | Kirjaudu klusterille suorittamalla komento `oc login -u https://api.ocp-test-0.k8s.it.helsinki.fi:6443`. 36 | 37 | Jostain syystä kirjautuminen ei kaikilla toimi. Jos käy näin, kirjaudu OpenShift-webkonsoliin ja valitse _Copy login command_: 38 | 39 | 40 | 41 | Kirjaudu uudelleen, ja saat toimivan kirjautumiskomennon: 42 | 43 | 44 | 45 | Kirjautumisen jälkeen voidaan vaikkapa suorittaa komento `oc status`, joka kertoo että olemme onnistuneesti kirjautuneet, omassa tapauksessani projektiin _toska-playground_: 46 | 47 | ```bash 48 | $ oc status 49 | In project toska-playground on server https://api.ocp-test-0.k8s.it.helsinki.fi:6443 50 | ``` 51 | 52 | Esimerkissä on käytössä projekti `toska-playground`. Ohtuprojekteissa käytetään projektia `ohtuprojekti-staging`. Projektista on olemassa sekä tuotanto- että testipuoli. Kysy ohjaajaltasi kumpaa ryhmäsi käyttää. 53 | 54 | Testipuolen osoite on https://api.ocp-test-0.k8s.it.helsinki.fi:6443 ja tuotantopuolen https://api.ocp-prod-0.k8s.it.helsinki.fi:6443, eli kirjautuessa käytä oikeaa osoitetta! Tuotantopuolen web-konsolin osoite on 55 | 56 | ### Pod ja deployment 57 | 58 | OpenShiftissa sovelluksen paketoinnin perusyksikkö on [podi](https://kubernetes.io/docs/concepts/workloads/pods/) (engl. pod). Podit ovat Kubernetes-ympäristön perusyksiköitä, ja ne sisältävät yleensä yhden Docker-imagen. Joissain tilanteissa podissa voi olla useita imageja, mutta tämä on yleensä mielekästä vain, jos imaget ovat tiiviisti yhteydessä toisiinsa, esimerkiksi jakamalla verkkoyhteyden tai tallennustilan. 59 | 60 | Podeja ei yleensä laiteta klusteriin suoraan. Näiden sijaan käytetään [deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)-objekteja. 61 | 62 | Määritellään deployment sovellustamme varten hakemistoon `manifests` sijoitettavaan tiedostoon `deployment.yaml`: 63 | 64 | ```yaml 65 | apiVersion: apps/v1 66 | kind: Deployment 67 | metadata: 68 | name: demoapp-dep 69 | spec: 70 | replicas: 1 71 | selector: 72 | matchLabels: 73 | app: demoapp 74 | template: 75 | metadata: 76 | labels: 77 | app: demoapp 78 | spec: 79 | containers: 80 | - name: demoapp 81 | image: mluukkai/demoapp:1 82 | ports: 83 | - containerPort: 3000 84 | env: 85 | - name: DB_URL 86 | value: postgresql://ohtuprojektitesti:passwordhere@hostnamehere:5432/ohtuprojekti?targetServerType=primary&ssl=true 87 | ``` 88 | 89 | Avaimen `spec` arvona määritellään deploymentin hallitseman podin (tai podien jos `replicas` on suurempi kuin 1) kontit. Tapauksessamme on yksi kontti, jonka käyttämä image on `mluukkai/demoapp:1`. Kontille on annettu sen käyttämä tietokantaosoite määrittelemällä ympäristömuuttuja `DB_URL`. Lue [täältä](https://github.com/HY-TKTL/TKT20007-Ohjelmistotuotantoprojekti/tree/master/openshift#tietokannan-hankkiminen) miten saat Postgres-tietokannan jos projektisi sellaista tarvitsee! 90 | 91 | Deploymentin määrittelevä yaml-tiedosto näyttää monimutkaiselta. Osa määrittelyn sisällöstä on sovelluksesta riippumatta suunnilleen sama, tärkein osuus on juurikin avaimen `spec` arvona. Metadatassa oleva `name: demoapp-dep` määrittelee deploymentin nimen. 92 | 93 | Deployment luodaan klusterille seuraavalla komennolla ($ on komentokehote): 94 | 95 | ```bash 96 | $ oc apply -f manifests/deployment.yaml 97 | ``` 98 | 99 | Deployment näyttää onnistuneen: 100 | 101 | ```bash 102 | $ oc get deployments 103 | NAME READY UP-TO-DATE AVAILABLE AGE 104 | demoapp-dep 1/1 1 1 16s 105 | ``` 106 | 107 | Deploymentin on siis tarkoitus käynnistää yksi podi. Katsotaan miltä podien tilanne näyttää: 108 | 109 | ```bash 110 | $ oc get pod 111 | NAME READY STATUS RESTARTS AGE 112 | demoapp-dep-5dbb664966-p6kfh 1/1 Running 0 25s 113 | ``` 114 | 115 | Podi on käynnissä. 116 | 117 | Testataan nyt sovellusta. Sovellus ei näy vielä klusterin ulkopuolelle, mutta pääsemme siihen käsiksi klusterin sisältä podin IP-osoitteen avulla. Saamme IP-osoitteen selville komennolla `oc describe pod `: 118 | 119 | ```bash 120 | $ oc describe po demoapp-dep-7499f5c5bd-8lm9p 121 | Name: demoapp-dep-7499f5c5bd-8lm9p 122 | Namespace: toska-playground 123 | Priority: 0 124 | Service Account: default 125 | Node: worker-1.ocp-test-0.k8s.it.helsinki.fi/128.214.137.138 126 | Start Time: Tue, 06 May 2025 17:00:38 +0300 127 | 128 | ... 129 | 130 | Status: Running 131 | IP: 10.12.2.177 132 | ``` 133 | 134 | Käynnistetään klusterin sisälle [curl](https://curl.se/)-komennon sisältävä Docker [image](https://hub.docker.com/r/curlimages/curl): 135 | 136 | ```bash 137 | $ oc run curlimage --image=curlimages/curl --restart=Never --command -- sleep infinity 138 | $ oc exec -it curlimage -- sh 139 | ``` 140 | 141 | Olemme nyt podin sisällä, ja voimme kokeilla ottaa yhteyttä sovellukseen tekemällä GET-pyynnön testirajapintaan _api/ping_: 142 | 143 | ```bash 144 | $ curl 10.12.2.177:3000/api/ping 145 | {"message":"pong"} 146 | ``` 147 | 148 | Jostain syystä GET-pyyntö laskurin arvon palauttavaan rajapintaan _api/counter_ ei toimi: 149 | 150 | ```bash 151 | $ curl 10.13.2.114:3000/api/counter 152 | 153 | 154 | 155 | 156 | Error 157 | 158 | 159 |
Internal Server Error
160 | 161 | 162 | ``` 163 | 164 | Tutkitaan sovelluksen lokia komennolla `oc logs `: 165 | 166 | ```bash 167 | $ oc logs demoapp-dep-68c95df467-w4glg 168 | 169 | > demoapp@0.0.0 prod 170 | > NODE_ENV=production node server/index.js 171 | 172 | Server running on http://localhost:3000 173 | Unable to connect to the database: ConnectionError [SequelizeConnectionError]: no pg_hba.conf entry for host 174 | "128.214.137.139", user "ohtuprojektitesti", database "ohtuprojekti", SSL encryption 175 | ``` 176 | 177 | Tietokantayhteyden suhteen näyttää olevan jotain häikkää. Ja kun virheilmoitusta lukee tarkemmin, huomaa, että sovelluksen käyttämä tietokantaurl on väärä, tietokannan nimi on _ohtuprojektitesti_, ei _ohtuprojekti_ kuten konfiguraatio vahingossa määritteli. 178 | 179 | Korjataan konfiguraatio ja päivitetään klusteri komennolla `apply -f manifests/deployment.yaml`. Katsotaan lokia uudelleen: 180 | 181 | ```bash 182 | $ oc logs demoapp-dep-6746c5d5dc-jjp88 183 | > demoapp@0.0.0 prod 184 | > NODE_ENV=production node server/index.js 185 | 186 | Server running on http://localhost:3000 187 | Executing (default): SELECT 1+1 AS result 188 | Connected to the database 189 | Executing (default): SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'counters' 190 | Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'counters' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname; 191 | ``` 192 | 193 | Hyvältä näyttää! Yritetään uudelleen 194 | 195 | ```bash 196 | $ curl 10.13.2.114:3000/api/counter 197 | curl: (7) Failed to connect to 10.13.2.114 port 3000 after 18688 ms: Could not connect to server 198 | ``` 199 | 200 | Yhteys ei enää yllättäen toimi. Syynä on se, että podin IP-osoite ei ole pysyvä. Tarkastetaan komennolla `oc describe pod ` uusi osoite, ja curlataan tähän osoitteeseen: 201 | 202 | ```bash 203 | $ curl 10.15.3.15:3000/api/counter 204 | {"id":1,"value":0} 205 | ``` 206 | 207 | Sovellus näyttää toimivan! 208 | 209 | ### Deklaratiivinen vs imperatiivinen määrittely 210 | 211 | Veimme sovelluksen tuotantoon määrittelemällä yaml-tiedoston ja antamalla komennon 212 | `oc apply -f manifests/deployment.yaml` 213 | 214 | Curl-podi taas käynnistettiin seuraavasti 215 | 216 | ```bash 217 | $ oc run curlimage --image=curlimages/curl --restart=Never --command -- sleep infinity 218 | ``` 219 | 220 | Mistä on kyse? Ensimmäinen tapa, missä käytettiin yamlia on ns. [deklaratiivinen](https://kubernetes.io/docs/concepts/overview/working-with-objects/object-management/#declarative-object-configuration) konfigurointitapa, joka on jossain määrin ehkä haastavampi, mutta ehdottomasti suositeltava tapa. Etuna on mm. se, että konfiguraatiot on mahdollista tallettaa versionhallintaan. 221 | 222 | Jälkimmäinen komento `oc run ...` taas edustaa [imperatiivistä](https://kubernetes.io/docs/concepts/overview/working-with-objects/object-management/#imperative-object-configuration) tyyliä Kubernetes-objektien luomiseen. Imperatiivisen tyylin ongelma on se, että klusterin tila ei pysy samalla tavalla hallittavasti näkyvillä kuin vaikkapa versionhallintaan tallennetuissa yaml-manifesteissä. Imperatiivista tyyliä kannattaa käyttää lähinnä yksinkertaisiin tilanteisiin, mm. esimerkkimme tapaan debugatessa. 223 | 224 | Käytettäköön siis deklaratiivista tyyliä, joka on myös tämän hetkisen teollisen parhaan käytänteen [GitOpsin](https://www.redhat.com/en/topics/devops/what-is-gitops) taustalla. Tätäkin teemaa käsitellään kurssilla [DevOps with Kubernetes](https://devopswithkubernetes.com/). 225 | 226 | Laajennetaan ohtuprojektimanifestia: 227 | 228 | > [!CAUTION] 229 | > Älä määrittele mitään OpenShiftin käyttöliittymän kautta tai imperatiivisin käskyin. 230 | > Jos teet näin, teknistä tukea ei kurssin puolesta ole luvassa. 231 | 232 | ### Service 233 | 234 | Podin IP-osoite siis näyttää vaihtuvan. Tämä johtuu siitä, että podi itseasiassa luodaan aina uudelleen kun siihen tehdään minkäänlaisia muutoksia, podit eivät siis ole pysyviä. Tarvitaankin jotain pysyvämpää, jotta ohjelma tavoitetaan varmemmin klusterin sisältä. Tätä varten on Kubernetesissa tarjolla [Service](https://kubernetes.io/docs/concepts/services-networking/service/). 235 | 236 | Tehdään tiedostoon `service.yaml` seuraava määrittely: 237 | 238 | ```yaml 239 | apiVersion: v1 240 | kind: Service 241 | metadata: 242 | name: demoapp-svc 243 | spec: 244 | selector: 245 | app: demoapp 246 | ports: 247 | - protocol: TCP 248 | port: 80 249 | targetPort: 3000 250 | type: ClusterIP 251 | ``` 252 | 253 | Spec-osassa määritellään, että service "kohdistuu" sovellukseen _demoapp_, joka on portissa 3000, service tarjoaa ulospäin portin 80. 254 | 255 | Seuraava havainnollistaa deploymentin ja servicen yhteyttä: 256 | 257 | 258 | 259 | Luodaan service, ja varmistetaan heti, että kaikki meni hyvin: 260 | 261 | ```bash 262 | $ oc apply -f manifests/service.yaml 263 | service/demoapp-svc created 264 | $ oc get svc 265 | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 266 | demoapp-svc ClusterIP 172.30.117.37 80/TCP 3s 267 | ``` 268 | 269 | Klusteri on luonut servicelle IP-osoitteen jonka avulla pääsisimme käsiksi sovellukseen. Parempi tapa on käyttää servicen nimeä _demoapp-svc_, tämä toimii klusterin sisällä DNS-nimenä palvelulle: 270 | 271 | ```bash 272 | $ curl http://demoapp-svc/api/ping 273 | {"message":"pong"} 274 | $ curl http://demoapp-svc/api/counter 275 | {"id":1,"value":0} 276 | $ curl http://172.30.117.37/api/counter 277 | {"message":"pong"} 278 | ``` 279 | 280 | Eli vaikka alla oleva podi vaihtuu, osoite pysyy servicen ansiosta ennallaan. Voisimme myös käynnistää podista useampia replikoita muuttamalla konfiguraatiota: 281 | 282 | ```yaml 283 | apiVersion: apps/v1 284 | kind: Deployment 285 | metadata: 286 | name: demoapp-dep 287 | spec: 288 | replicas: 3 289 | ... 290 | ``` 291 | 292 | Kun komento `oc apply -f manifests/deployment.yaml` on suoritettu uudelleen, näemme että klusterille on käynnistynyt uusia kopioita samasta podista: 293 | 294 | ```bash 295 | $ oc get pod 296 | NAME READY STATUS RESTARTS AGE 297 | curlimage 1/1 Running 0 16h 298 | demoapp-dep-5bb7578b6-2xljw 1/1 Running 0 13h 299 | demoapp-dep-5bb7578b6-4bk6c 1/1 Running 0 47s 300 | demoapp-dep-5bb7578b6-w2b9j 1/1 Running 0 47s 301 | ``` 302 | 303 | Kun podiin otetaan yhteyttä servicen osoitteen kautta, yhdistää service pyynnön yhdelle podeista [round robin](https://en.wikipedia.org/wiki/Round-robin_scheduling) -periaateella. 304 | 305 | Voimme tässä vaiheessa poistaa debuggausta varten käynnistämämme podin `curlimage`: 306 | 307 | ```bash 308 | $ oc delete curlimage 309 | ``` 310 | 311 | ### Näkyvyys klusterin ulkopuolelle 312 | 313 | Sovelluksemme on muuten oikein hyvä, mutta emme pääse käyttämään sitä klusterin ulkopuolelta. Kubernetes tarjoaa muutamia ratkaisuja liikenteen ohjaamiseksi klusteriin. 314 | 315 | Debuggaustarkoituksiin kätevä ratkaisu on komento [port-forward](https://kubernetes.io/docs/reference/kubectl/generated/kubectl_port-forward/), joka ohjaa jonkun paikallisen koneen portin klusterin sisälle. 316 | 317 | Voimme tehdä portinohjauksen palveluun seuraavasti 318 | 319 | ```bash 320 | $ oc port-forward svc/demoapp-svc 8080:80 321 | Forwarding from 127.0.0.1:8080 -> 3000 322 | ``` 323 | 324 | Nyt pääsemme sovellukseen käsiksi selaimella portista 8080: 325 | 326 | 327 | 328 | Portinohjaus voidaan tehdä myös suoraan yksittäiseen podiin: 329 | 330 | ```bash 331 | $ oc port-forward demoapp-dep-5bb7578b6-2xljw 8080:3000 332 | ``` 333 | 334 | Portinohjaus sopii hyvin debuggaukseen, esim. sen tarkastamiseen että sovellus toimii kokonaisuudessaan. 335 | 336 | Tarvitsemme kuitenkin todelliseen käyttöön jotain muuta. Kubernetes tarjoaa tähän kaksi ratkaisua: Ingressin ja uudemman Gateway API:n joita molemia käsitellään kurssilla [DevOps with Kubernetes](https://devopswithkubernetes.com/). Tiken OpenShiftissä joudumme kuitenkin käyttämään OpenShit-spesifiä ratkaisua [Routea](https://docs.redhat.com/en/documentation/openshift_container_platform/4.11/html/networking/configuring-routes#route-configuration). 337 | 338 | Tehdään seuraava määrittely tiedostoon `manifests/route.yaml` 339 | 340 | ```yaml 341 | apiVersion: route.openshift.io/v1 342 | kind: Route 343 | metadata: 344 | name: demoapp-route 345 | namespace: toska-playground 346 | labels: 347 | app: demoapp 348 | type: external 349 | spec: 350 | host: demoapp-toska-playground.ext.ocp-test-0.k8s.it.helsinki.fi 351 | port: 352 | targetPort: 3000 353 | to: 354 | kind: Service 355 | name: demoapp-svc 356 | tls: 357 | termination: edge 358 | insecureEdgeTerminationPolicy: Redirect 359 | wildcardPolicy: None 360 | ``` 361 | 362 | Namespace on tässä tapauksessa _toska-playground_, se vastaa OpenShift-projektin nimeä, ohtuprojekteilla se on _ohtuprojekti-staging_. Host-nimen pitää olla Tiken klusteritasolla uniikki, sopiva nimi on esim. sovelluksen nimi ja sen perässä namespacen nimi. `spec/to` määrittelee reitityksen kohteena olevan palvelun. Kohdeportiksi pitää määritellä servicen takana olevan podin portti, ei siis servicen portti (joka oli tapauksessamme 80), servicen sisäistä porttia käytetään tapauksessamme klusterin sisäisessä kommunikoinnissa. 363 | 364 | Sovellus toimii nyt koko maailmalle osoitteessa https://demoapp-toska-playground.ext.ocp-test-0.k8s.it.helsinki.fi/ 365 | 366 | 367 | 368 | Host-nimi riippuu myös käytetystä klusteriympäristöstä. Jos käytetään tuotantoklusteria, vaihtuu sana `test` sanaksi `prod`. 369 | 370 | ### Image stream 371 | 372 | Sovelluksessamme on nyt eräs hieman ikävä puoli. Jos haluamme käynnistää uuden version, tulee luoda Docker-image jolla on uusi tagi, esim mluukkai/demoapp:2 ja deploymentia on muutettava siten, että se viittaa muuttuneeseen tagiin. 373 | 374 | OpenShift tarjoaa [image stream](https://docs.redhat.com/en/documentation/openshift_container_platform/4.8/html/images/managing-image-streams) -nimisen objektin, jonka ansiosta deploymentin on mahdollista viitata koko ajan samaan tagiin, ja taustalla olevan imagen päivittyminen Dockerhubiin otetaan tästä huolimatta huomioon. 375 | 376 | Muutetaan Dockerhubiin pushattavan imagen tagiksi _mluukkai/demoapp:staging_: 377 | 378 | ```yaml 379 | - name: Build and push Docker image 380 | uses: docker/build-push-action@v4 381 | with: 382 | context: . 383 | push: true 384 | tags: ${{ secrets.DOCKER_USERNAME }}/demoapp:staging 385 | ``` 386 | 387 | Luodaan nyt seuraava määrittely tiedostoon _imagestream.yaml_: 388 | 389 | ```yaml 390 | kind: ImageStream 391 | apiVersion: image.openshift.io/v1 392 | 393 | metadata: 394 | name: demoapp 395 | labels: 396 | app: demoapp 397 | spec: 398 | lookupPolicy: 399 | local: false 400 | tags: 401 | - name: staging 402 | from: 403 | kind: DockerImage 404 | name: mluukkai/demoapp:staging 405 | importPolicy: 406 | scheduled: true 407 | referencePolicy: 408 | type: Local 409 | ``` 410 | 411 | Tämä määrittelee imagestreamin nimeltään _demoapp_, ja sille tägin _staging_, mihin viitataan esim. deploymenteissa nimellä `demoapp:staging`. 412 | 413 | Luodaan imagestream ja tarkistetaan vielä miltä se näyttää 414 | 415 | ```bash 416 | $ oc apply -f manifests/imagestream.yaml 417 | imagestream.image.openshift.io/demoapp created 418 | $ oc get imagestream 419 | NAME IMAGE REPOSITORY TAGS UPDATED 420 | demoapp registry.apps.ocp-test-0.k8s.it.helsinki.fi/toska-playground/demoapp staging 4 seconds ag 421 | ``` 422 | 423 | Voimme nyt ottaa image streamin viittaaman imagen käyttöön muokkaamalla deploymentia seuraavasti 424 | 425 | ```yaml 426 | apiVersion: apps/v1 427 | kind: Deployment 428 | metadata: 429 | annotations: 430 | alpha.image.policy.openshift.io/resolve-names: "*" 431 | image.openshift.io/triggers: >- 432 | [{"from":{"kind":"ImageStreamTag","name":"demoapp:staging","namespace":"toska-playground"},"fieldPath":"spec.template.spec.containers[?(@.name==\"demoapp\")].image","pause":"false"}] 433 | name: demoapp-dep 434 | spec: 435 | replicas: 1 436 | selector: 437 | matchLabels: 438 | app: demoapp 439 | template: 440 | metadata: 441 | labels: 442 | app: demoapp 443 | spec: 444 | containers: 445 | - name: demoapp 446 | image: demoapp:staging 447 | imagePullPolicy: Always 448 | ports: 449 | - containerPort: 3000 450 | env: 451 | - name: DB_URL 452 | value: postgresql://ohtuprojektitesti:passwordhere@hostnamehere:5432/ohtuprojektitesti?targetServerType=primary&ssl=true 453 | ``` 454 | 455 | Uutta tässä on avaimeen `meta/annotations` lisätyt määreet, jotka saavat deploymentin seuraamaan image streamissa tapahtuvia muutoksia. Toinen muutos on kontainerin `image`, joka arvo on nyt `demoapp:staging`, eli viite image streamiin. 456 | 457 | Image stream päivittyy 15 min välein, eli jos pushaamme sovelluksesta uuden version Dockerhubiin, kestää korkeintaan 15 minuuttia, ennen kuin klusterilla oleva imagestream päivittyy, ja sovelluksen uusi versio käynnistyy. 458 | 459 | Jos on tarve nopeampaan päivitykseen, voidaan suorittaa komento `oc import-image demoapp:staging` joka päivittää imagestreamin välittömästi, sekä käynnistää podin uudelleen jos image streamin osoittama image on muuttunut. 460 | 461 | ### Konfiguraatiot 462 | 463 | Sovellus saa tietokannan osoitteen ympäristömuuttujan `DB_URL` avulla. Ympäristömuuttujan arvo määritellään deploymentissa: 464 | 465 | ```yaml 466 | spec: 467 | containers: 468 | - name: demoapp 469 | image: demoapp:staging 470 | imagePullPolicy: Always 471 | ports: 472 | - containerPort: 3000 473 | env: 474 | - name: DB_URL 475 | value: postgresql://ohtuprojektitesti:passwordhere@hostnamehere:5432/ohtuprojekti?targetServerType=primary&ssl=true 476 | ``` 477 | 478 | Tämä tapa on ok mutta ei optimaali, emme esim. voi laittaa deployment.yaml:ia GitHubiin koska URL sisältää salasanan. Kubernetes tarjoaa pari mekanismia, joiden avulla konfiguraatiot voidaan eriyttää deploymenteista, käytetään nyt näistä [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/):ia. 479 | 480 | Tehdään tätä varten tiedosto `configmap.yaml` 481 | 482 | ```yaml 483 | apiVersion: v1 484 | kind: ConfigMap 485 | metadata: 486 | name: demoapp-config 487 | data: 488 | DB_URL: postgresql://ohtuprojektitesti:passwordhere@hostnamehere:5432/ohtuprojekti?targetServerType=primary&ssl=true 489 | ``` 490 | 491 | Lisätään tiedoto välittömästi `.gitignore`:n, jotta tietokannan salasana ei livahda internettiin. 492 | 493 | Deploymentissa oleva ympäristömuuttujan määrittely muuttuu seuraavasti 494 | 495 | ```yaml 496 | spec: 497 | containers: 498 | - name: demoapp 499 | image: demoapp:staging 500 | imagePullPolicy: Always 501 | ports: 502 | - containerPort: 3000 503 | env: 504 | - name: DB_URL 505 | valueFrom: 506 | configMapKeyRef: 507 | name: demoapp-config 508 | key: DB_URL 509 | ``` 510 | 511 | Kubernetes tarjoaa myös resurssin [Secret](https://kubernetes.io/docs/concepts/configuration/secret/), joka periaatteessa sopisi paremmin salasanan sisältävän tietokantaurlin tarpeisiin. Nimestään huolimatta secretit eivät oikeastaan tuo juurikaan turvaa, joten sivuutamme asian nyt. Myös secretejä käsitellään kurssilla [DevOps with Kubernetes](https://devopswithkubernetes.com/). 512 | 513 | ### Kustomize 514 | 515 | Sovelluksen Kubernetes-konfiguraatiot, eli manifestit on nyt talletettu hakemistoon `manifests`, ja konfiguraatioista muut paitsi salaista tietoa sisältävä `configmap.yaml` on tallennettu versionhallintaan. 516 | 517 | Koko sovelluksen konfiguraatiot voi päivittää klusterille komennolla `oc apply -f manifests`, eli antamalla parametriksi manifestit sisältämän hakemiston. Monimutkaisemmassa sovelluksessa manifestitiedostot voivat olla hajaantuneet useampaan hakemistoon ja klusterin synkronointi voi olla hankalampaa. 518 | 519 | [Kustomize](https://kustomize.io/)-työkalu (joka on nykyään sisäänrakennettu Kubernetesin komentoriville) tuo helpotusta tähän (ja tarjoaa paljon muutakin). Määritellään tiedosto `kustomize.yaml`, joka listaa yksittäiset manifestit: 520 | 521 | ```yaml 522 | apiVersion: kustomize.config.k8s.io/v1beta1 523 | kind: Kustomization 524 | 525 | resources: 526 | - manifests/configmap.yaml 527 | - manifests/route.yaml 528 | - manifests/service.yaml 529 | - manifests/imagestream.yaml 530 | - manifests/deployment.yaml 531 | ``` 532 | 533 | Manifestit saadaan synkronoitua klusterille komennolla `oc apply -k .` 534 | 535 | Esimerkkimme tapauksessa Kustomize ei tuo juurikaan etuja, suuremmassa projektissa tilanne on toinen. Kurssilla [DevOps with Kubernetes](https://devopswithkubernetes.com/) asiaa käsitellään enemmän. 536 | 537 | ### Resurssirajat 538 | 539 | Klusteri priorisoi sovelluksia, joille on asetettu resurssirajat. Jos resursseista on pulaa, niin ilman rajojen asettamista sovellus ei välttämättä edes käynnisty. 540 | 541 | Deploymenteille onkin syytä asettaa [resurssirajat](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/): 542 | 543 | ```yaml 544 | apiVersion: apps/v1 545 | kind: Deployment 546 | metadata: 547 | annotations: 548 | alpha.image.policy.openshift.io/resolve-names: "*" 549 | image.openshift.io/triggers: >- 550 | [{"from":{"kind":"ImageStreamTag","name":"demoapp:staging","namespace":"toska-playground"},"fieldPath":"spec.template.spec.containers[?(@.name==\"demoapp\")].image","pause":"false"}] 551 | name: demoapp-dep 552 | spec: 553 | replicas: 1 554 | selector: 555 | matchLabels: 556 | app: demoapp 557 | template: 558 | metadata: 559 | labels: 560 | app: demoapp 561 | spec: 562 | containers: 563 | - name: demoapp 564 | image: demoapp:staging 565 | imagePullPolicy: Always 566 | ports: 567 | - containerPort: 3000 568 | env: 569 | - name: DB_URL 570 | valueFrom: 571 | configMapKeyRef: 572 | name: demoapp-config 573 | key: DB_URL 574 | resources: 575 | limits: 576 | memory: "512Mi" 577 | cpu: "500m" 578 | requests: 579 | memory: "50Mi" 580 | cpu: "50m" 581 | ``` 582 | 583 | Limits määrittää enimmäismäärän laskentaresursseja, joita kontti voi käyttää. Requests määrittää resurssimäärän, joka taataan olevan saatavilla kontille. 584 | 585 | Voit säätää memory ja cpu arvoja sovelluksesi vaatimusten mukaan. Muisti määritetään MiB-yksiköissä ja CPU milliCPU-yksiköissä. 586 | 587 | Älä pyydä turhaan liikaa resursseja! 588 | 589 | ### Kooste tärkeimmistä komennoista 590 | 591 | | Komento | Kuvaus | 592 | | :------------------------------ | :------------------------------------------------------------------------------------ | 593 | | `oc get po` | listaa podit | 594 | | `oc get svc` | listaa servicet | 595 | | `oc describe po ` | katso podin tarkemmat tiedot, toimii myös muille resursseille, esim. svc, deployments | 596 | | `oc exec -it -- bash` | suorita podilla komento bash eli komentotulkki | 597 | | `oc apply -f manifest.yaml` | luo/päivitä manifestin määrittelemät objektit | 598 | | `oc delete -f manifest.yaml` | tuhoa manifestin määrittelemät objektit | 599 | | `oc import-image image:tagi` | päivitä imagestream heti | 600 | | `oc logs ` | näytä sovelluksen lokit | 601 | | `oc logs -f ` | seuraa sovelluksen lokeja | 602 | | `oc port-forward ` | ohjaa lokaalin koneen portin liikenne podiin | 603 | | `oc port-forward svc/` | ohjaa lokaalin koneen portin liikenne palveluun | 604 | 605 | ### Tietokannan hankkiminen 606 | 607 | Esimerkkisovellus käyttää Tiken ylläpitämää yhteiskäyttöistä tietokantaa. Tietokannan hankkiminen on helppoa, yksi email riittää, ks https://devops.pages.helsinki.fi/guides/platforms/shared-dbs.html 608 | 609 | Pyyntöön voi käyttää seuraavaa email-pohjaa 610 | 611 | ``` 612 | Saisimmeko uuden tietokannan yhteiskäyttöiseen Postgresin testikantaan esim. possu-test-1-21.it? 613 | 614 | kantatunnus: omansovelluksennimi 615 | sovelluksen osoite: openshift 616 | kannan ylläpitäjä: oili.opiskelija@helsinki.fi 617 | klusteri, jossa sovellus pyörii: prod tai testi (ocp-prod/ocp-test klusterin urlissa) 618 | ``` 619 | 620 | Osoitteena siis _openshift_. Jos kyse on tuotantosovelluksesta, tulee pyytää _possu-test-1-21.it_ sijaan tuotantokantaan. 621 | 622 | Kannattaa huomata, että tietokanta edellyttää SSL:n käyttöä, eli tietokantaurl on muotoa `postgresql://ohtuprojektitesti:passwordhere@hostnamehere:5432/ohtuprojekti?targetServerType=primary&ssl=true` asia kyllä mainitaan yo dokumentaatiossa mutta esim. allekirjoittanut ei lukenut dokumenttia aluksi tarpeeksi tarkasti... 623 | 624 | Jos haluat ottaa tietokantaan yhdeyden suoraan, on projektiin `ohtuprojekti-staging` on konfiguroitu podi `db-tools`, joka sisältää tietokantayhteyksien kannalta tarvittavat komentorivityökalut, kuten `psql` ja `mongosh`. Tietokantayhteys avataan tämän podin avulla seuraavasti 625 | 626 | ```bash 627 | $ oc exec -it $(oc get pods -l deployment=db-tools -o jsonpath='{.items[0].metadata.name}') -- psql postgres://kayttaja:salasana@possu-test.it.helsinki.fi:5432/tietokanta 628 | ``` 629 | 630 | Komentoriviltä yhdistäessäsi riittää tietokantaurlin lyhyempi muoto. 631 | 632 | ### Mongo ja tiedostojen tallentaminen 633 | 634 | Jos päätät käyttää MongoDB:tä, ei yliopistolla ole valitettavasti tarjolla hostattua palvelua. On käytettävä ulkoista palvelua tai konfiguroitava Mongo itse OpenShiftiin. Tämäkään ei ole vaikeaa. Pienen mutkan matkaan aiheuttaa se, että Mongoa varten on varattava pysyvään talletukseen sopivaa levytilaa. 635 | 636 | Levytilan varaaminen tapahtuu luomalla [PersistentVolumeClaim](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims). Tehdään tiedosto `volumeclaim.yaml` ja sinne sisältö: 637 | 638 | ```yaml 639 | kind: PersistentVolumeClaim 640 | apiVersion: v1 641 | 642 | metadata: 643 | name: demoapp-claim 644 | namespace: toska-playground 645 | spec: 646 | accessModes: 647 | - ReadWriteOnce 648 | resources: 649 | requests: 650 | storage: 1Gi 651 | storageClassName: data-2 652 | volumeMode: Filesystem 653 | ``` 654 | 655 | Määritelty levypyyntö varaa yhden gigan levyä. Tilauksessa on määritelty `storageClassName: data-2`, tämä ohjaa pyynnön Tiken meille varaamalle levylle eli PersistentVolumelle. 656 | 657 | Kokeillaan ensin liittää levy normaaliin podiin. 658 | 659 | Tehdään tiedostoon `ubuntu-deployment.yaml` deployment joka käynnistää Ubuntun: 660 | 661 | ```yaml 662 | apiVersion: apps/v1 663 | kind: Deployment 664 | metadata: 665 | name: my-ubuntu-deployment 666 | spec: 667 | replicas: 1 668 | selector: 669 | matchLabels: 670 | app: my-ubuntu 671 | template: 672 | metadata: 673 | labels: 674 | app: my-ubuntu 675 | spec: 676 | containers: 677 | - name: ubuntu 678 | image: ubuntu 679 | imagePullPolicy: Always 680 | command: 681 | - sleep 682 | - "3600" 683 | ``` 684 | 685 | Ennen kun liitämme pysyväislevyn deploymentin luovaan podiin, kokeillaan mitä tapahtuu jos kirjoitamme tiedostoja podin sisälle ilman pysyväislevyn käyttöä. 686 | 687 | Luodaan deployment, mennään podiin ja tehdään podin hakemistoon `/tmp` kaksi tiedostoa: 688 | 689 | ```bash 690 | $ oc apply -f ubuntu-deployment.yaml 691 | $ oc exec -it my-ubuntu-deployment-d7b6d85d4-drsbr -- bash 692 | $ cd tmp 693 | $ touch tiedosto1 694 | $ touch tiedosto2 695 | $ ls 696 | tiedosto1 697 | tiedosto2 698 | ``` 699 | 700 | Tehdään nyt muutos deploymentiin, esim. muutetaan komennon sleep sekuntimäärää. Kun suoritetaan `apply`, luodaan uusi podi edellisen tilalle. 701 | 702 | Kun mennään nyt uuden podin hakemistoon `/tmp` huomataan että se on tyhjä: 703 | 704 | ```bash 705 | $ oc apply -f ubuntu-deployment.yaml 706 | $ oc exec -it my-ubuntu-deployment-6b947f9bbc-ztls -- bash 707 | $ cd tmp 708 | $ ls -l 709 | total 0 710 | ``` 711 | 712 | Podin levylle kirjoittaminen siis on turhaa, jos on tarkoitus tallettaa asioita pysyvästi. 713 | 714 | Otetaan nyt käyttöön klusterilta pyytämämme levyvoluumi, ja mäpätään se podin hakemistoon `/tmp`: 715 | 716 | ```yaml 717 | apiVersion: apps/v1 718 | kind: Deployment 719 | metadata: 720 | name: my-ubuntu-deployment 721 | spec: 722 | replicas: 1 723 | selector: 724 | matchLabels: 725 | app: my-ubuntu 726 | template: 727 | metadata: 728 | labels: 729 | app: my-ubuntu 730 | spec: 731 | containers: 732 | - name: ubuntu 733 | image: ubuntu 734 | imagePullPolicy: Always 735 | command: 736 | - sleep 737 | - "3601" 738 | volumeMounts: 739 | - mountPath: /tmp 740 | name: demoapp-volume 741 | volumes: 742 | - name: demoapp-volume 743 | persistentVolumeClaim: 744 | claimName: demoapp-claim 745 | ``` 746 | 747 | Deploymentissa on kaksi lisäystä, ensinnäkin `template/spec`:in alla on osa `volumes`, joka kertoo mitä volumeja deployment käyttää. Käyttöön on otettu levypyyntöä `demoapp-claim` vastaava voluumi ja on annettu sille nimi `demoapp-volume`. Osan `containers` alle on määritelty, että käyttöön otettu voluumi mäpätään podiin polulle `/tmp`. 748 | 749 | Kokeillaan sitten samaa uusiksi, eli lisätään volumille mäpättyyn hakemistoon `/tmp` tiedostoja, pakotetaan podin uudelleenluonti, ja tarkastetaan että tiedostot säilyvät: 750 | 751 | ```bash 752 | $ oc exec -it my-ubuntu-deployment-755d7b8889-t2ctk -- bash 753 | $ cd tmp 754 | $ ls 755 | lost+found 756 | $ touch tiedosto1 757 | $ touch tiedosto2 758 | $ ls 759 | lost+found tiedosto1 tiedosto2 760 | $ exit 761 | exit 762 | $ of apply -f ubuntu-deployment.yaml 763 | deployment.apps/my-ubuntu-deployment configured 764 | $ oc exec -it my-ubuntu-deployment-76bfb959bb-jpdng -- bash 765 | $ cd tmp 766 | $ ls 767 | lost+found tiedosto1 tiedosto2 768 | ``` 769 | 770 | Kuten olettaa saattaa, tiedostot säilyvät. Volumella olevat tiedot säilyvät vaikka deployment tuhottaisiin ja luotaisiin uudelleen: 771 | 772 | ```bash 773 | $ oc delete -f ubuntu-deployment.yaml 774 | $ oc apply -f ubuntu-deployment.yaml 775 | $ oc exec -it my-ubuntu-deployment-76bfb959bb-qxckz -- ls /tmp 776 | lost+found tiedosto1 tiedosto2 777 | ``` 778 | 779 | Uskomme nyt että persistent volumet ovat sitä mitä tarvitsemme, tuhotaan kokeiluun käytetty Ubuntu ja luodaan Mongoa varten deployment ja service. Luodaan tällä kertaa molemmat samaan tiedostoon `mongo-deployment.yaml`: 780 | 781 | ```yaml 782 | apiVersion: apps/v1 783 | kind: Deployment 784 | metadata: 785 | name: demoapp-mongo-deployment 786 | spec: 787 | replicas: 1 788 | selector: 789 | matchLabels: 790 | app: demoapp-mongo 791 | template: 792 | metadata: 793 | labels: 794 | app: demoapp-mongo 795 | spec: 796 | containers: 797 | - name: my-mongo 798 | image: mongo 799 | imagePullPolicy: Always 800 | ports: 801 | - containerPort: 27017 802 | env: 803 | - name: MONGO_INITDB_ROOT_USERNAME 804 | value: demo_user 805 | - name: MONGO_INITDB_ROOT_PASSWORD 806 | value: demo_password 807 | volumeMounts: 808 | - mountPath: /data/db 809 | name: demoapp-volume 810 | volumes: 811 | - name: demoapp-volume 812 | persistentVolumeClaim: 813 | claimName: demoapp-claim 814 | 815 | --- 816 | 817 | apiVersion: v1 818 | kind: Service 819 | metadata: 820 | name: demoapp-mongo-svc 821 | spec: 822 | selector: 823 | app: demoapp-mongo 824 | ports: 825 | - protocol: TCP 826 | port: 27017 827 | targetPort: 27017 828 | type: ClusterIP 829 | ``` 830 | 831 | Levyvoluumi on mäpätty Mongo-podin polulle `/data/db`, kyseessä on [dokumentaation](https://hub.docker.com/_/mongo) mukaan hakemisto minne Mongo tallettaa tietokannan. 832 | 833 | Suoritetaan tuttu komento `oc apply -f mongo-deployment.yaml`. Komentoja `oc get po` ja `oc logs` tarkastelemalla olemme vakuuttuneita, että Mongo on käynnissä. 834 | 835 | Klusterin sisältä kantaan päästään nyt käsiksi osoitteella `mongodb://demo_user:demo_password@demoapp-mongo-svc:27017`. 836 | 837 | Laskurisovelluksesta on tehty Mongoa käyttävä versio repositorion branchiin [mongo](https://github.com/mluukkai/openshift-demo/tree/mongo). Mongoa käyttävän versiosta luodaan Docker-image on `demoapp-mongo`. 838 | 839 | Laajennetaan image streamia ottamaan huomioon myös tämä tägi: 840 | 841 | ```yaml 842 | kind: ImageStream 843 | apiVersion: image.openshift.io/v1 844 | 845 | metadata: 846 | name: demoapp 847 | labels: 848 | app: demoapp 849 | spec: 850 | lookupPolicy: 851 | local: false 852 | tags: 853 | - name: staging 854 | from: 855 | kind: DockerImage 856 | name: mluukkai/demoapp:staging 857 | importPolicy: 858 | scheduled: true 859 | referencePolicy: 860 | type: Local 861 | - name: mongo 862 | from: 863 | kind: DockerImage 864 | name: mluukkai/demoapp:mongo 865 | importPolicy: 866 | scheduled: true 867 | referencePolicy: 868 | type: Local 869 | ``` 870 | 871 | Muutetaan deploymentia seuraavasti: 872 | 873 | ```yaml 874 | spec: 875 | containers: 876 | - name: demoapp 877 | image: demoapp:mongo 878 | imagePullPolicy: Always 879 | ports: 880 | - containerPort: 3000 881 | env: 882 | - name: MONGO_DB_URL 883 | value: mongodb://demo_user:demo_password@demoapp-mongo-svc:27017 884 | ``` 885 | 886 | 887 | Olemme tällä kertaa laiskoja ja määrittelemme tietokantaurlin suoraan GitHubiin menevässä tiedostossa `deployment.yaml` 888 | 889 | > [!CAUTION] 890 | > Älä yritä tätä kotona äläkä missään muuallakaan! 891 | 892 | Kokeillaan! Sovellus toimii: 893 | 894 | 895 | 896 | ### Ongelmatilanteita 897 | 898 | Kubernetes/OpenShift on loistava työkalu, mutta moni asia voi mennä pieleen. Kielimalleista on erittäin suuri apu yaml-manifestien kanssa, esim ChatGPT osaa bongata virheet manifesteista ja luoda niitä ainakin pääpiirteissään jos promptaus on kohtuullisella tasolla. 899 | 900 | Debugatessa ei auta oikein muu kun systemaattisuus. Komentoja `oc get`, `oc describe` ja `oc logs` ei voi koskaan käyttää liikaa... 901 | 902 | #### Lokaalisti toimiva kontti ei toimi... 903 | 904 | Käyttöoikeusongelmien kirjo voi olla moninainen riippuen kontissa ajettavasta teknologiasta. Tähän liittyy yleensä jonkinlainen tiedostojen käyttöön liittyvä virheilmoitus: 'not writable', 'permission denied'. 905 | 906 | Kun kontti käynnistetään OpenShiftissa, arvotaan kontin käyttäjäksi satunnainen UID ja käyttäjälle tulee asettaa sopivat oikeudet kontin sisälle. Esimerkkimme tilanteessa ei mitään toimenpiteitä tarvittu. Aina ei ole näin. Joissain tilanteissa selviää seuraavasti: 907 | 908 | ```dockerfile 909 | WORKDIR /app 910 | 911 | COPY . . 912 | ``` 913 | 914 | voit asettaa käyttöoikeudet Dockerfilessa yksinkertaisella (joskaan ei kovin mallikelpoisella) tavalla, 915 | 916 | ```dockerfile 917 | RUN chmod -R 777 * 918 | ``` 919 | 920 | jonka jälkeen käyttäjän oikeudet ulottuvat kansion /app alikansioihin ja tiedostoihin. 921 | 922 | Esimerkkitapauksena mainittakoon Pythonin virtuaaliympäristö, jota saatetaan yrittää suorittaa jossain muussa hakemistossa kuin /app, jolloin venv-moduuli ei välttämättä käynnisty laisinkaan. Sopivaa ympäristömuuttujaa käyttämällä virtuaaliympäristö voidaan asettaa suoritettavaksi /app kansion sisällä. Ympäristömuuttujia voi esitellä kontille Dockerfilen käskyllä ENV. 923 | 924 | Seuraava esimerkki toi ratkaisun ainakin erääseen Poetry-projektiin: 925 | 926 | ```dockerfile 927 | ENV POETRY_VIRTUALENVS_IN_PROJECT=true 928 | ``` 929 | 930 | Jossain tilanteessa ongelman voi aiheuttaa kolmannen osapuolen image. Esim. avain-arvo-tietokanta [Redisin](https://redis.io/) virallinen [Docker image](https://hub.docker.com/_/redis) olettaa suorittavansa koodia rootin oikeuksilla. OpenShift kuitenkin vaihtaa tilalle satunnaisen ei-rootkäyttäjän ja oletusarvoisesti konfiguroitu kontti törmää ongelmiin kirjoittaessaan dataa tiedostoihin. Ongelma ratkeaa ottamalla käyttöön [Red Hatin](https://catalog.redhat.com/software/containers/rhel9/redis-7/64881353e0e10aaf1cbac8b7?gs&q=redis) versio Redisistä, esim. `registry.redhat.io/rhel9/redis-7`, joka ei edellytä root-käyttäjää. Red Hatilta löytyy OpenShiftille sopiva versio monesta yleisestä palvelusta. 931 | 932 | ### Objektien nimennästä 933 | 934 | On oleellisen tärkeää, että jokainen ryhmä nimeää Kubernetes-objektit järkevästi ja yhdenmukaisesti, siten että on mahdollista helposti päätellä minkä ryhmän tuotoksista on kyse. Jos projektin nimi olisi esim. labtool, objektien nimet noudattaisivat seuraavaa kaavaa 935 | 936 | ``` 937 | labtool-backend-dep 938 | labtool-backend-svc 939 | labtool-route 940 | labtool-mongo-dep 941 | labtool-mongo-svc 942 | ``` 943 | 944 | Nimi siis alkaa ryhmän nimeä edustavalla kuvaavalla merkkijonolla. 945 | 946 | Klusterille ei saa jättää mitään roskaa eikä ylimääräisiä Kubernetes-objekteja. Eli jos jokin rersurssi todetaan turhaksi, se poistetaan. 947 | 948 | Jos klusterilta löytyy holtittomasti nimettyjä objekteja, ne saatetaan poistaa ilman varoitusta. 949 | 950 | ### HY-kirjautuminen 951 | 952 | Katso erillinen [ohje](kirjautuminen.md) 953 | --------------------------------------------------------------------------------