From 329f630f76487e658dfbf64b00125b8d68940cf1 Mon Sep 17 00:00:00 2001 From: saddogsec Date: Wed, 28 Jan 2026 19:26:41 +0300 Subject: [PATCH 01/21] feat: implement lab01 devops info service --- app_python/.gitignore | 5 + app_python/README.md | 39 +++++ app_python/app.py | 152 ++++++++++++++++++ app_python/docs/LAB01.md | 57 +++++++ .../docs/screenshots/01-main-endpoint.jpg | Bin 0 -> 49974 bytes .../docs/screenshots/02-health-check.jpg | Bin 0 -> 20104 bytes .../docs/screenshots/03-formatted-output.jpg | Bin 0 -> 81536 bytes app_python/requirements.txt | 1 + app_python/tests/__init__.py | 0 9 files changed, 254 insertions(+) create mode 100644 app_python/.gitignore create mode 100644 app_python/README.md create mode 100644 app_python/app.py create mode 100644 app_python/docs/LAB01.md create mode 100644 app_python/docs/screenshots/01-main-endpoint.jpg create mode 100644 app_python/docs/screenshots/02-health-check.jpg create mode 100644 app_python/docs/screenshots/03-formatted-output.jpg create mode 100644 app_python/requirements.txt create mode 100644 app_python/tests/__init__.py diff --git a/app_python/.gitignore b/app_python/.gitignore new file mode 100644 index 0000000000..ffb798c533 --- /dev/null +++ b/app_python/.gitignore @@ -0,0 +1,5 @@ +# Python +__pycache__/ +*.py[cod] +venv/ +*.log diff --git a/app_python/README.md b/app_python/README.md new file mode 100644 index 0000000000..bb8575ca03 --- /dev/null +++ b/app_python/README.md @@ -0,0 +1,39 @@ +# DevOps Info Service + +## Overview +This service reports: +- Service metadata (name, version, framework) +- System data (hostname, operating system, cpu, python version) +- Runtime data (uptime and current UTC time) +- Request metadata (IP, user agent, method, path) + +## Prerequisites +- Python 3.11+ + +## Installation +```bash +cd app_python +python -m venv venv +source venv/bin/activate # or source `venv/bin/activate.fish` if you using fish instead of bash/sh. +pip install -r requirements.txt +``` + +## Running the Application +```bash +python app.py + +# Or with custom config +PORT=8080 python app.py +``` + +## API Endpoints +- `GET /` - Service and system information +- `GET /health` - Health check + +## Configuration +`HOST` - Interface to bind (0.0.0.0 by default) + +`PORT` - Port to listen on (5000 by default) + +`DEBUG` - Enable Flask debug logging (False by default) + diff --git a/app_python/app.py b/app_python/app.py new file mode 100644 index 0000000000..755e88066e --- /dev/null +++ b/app_python/app.py @@ -0,0 +1,152 @@ +import logging +import os +import platform +import socket +from datetime import datetime, timezone +from flask import Flask, jsonify, request + +APP_NAME = "devops-info-service" +APP_VERSION = "1.0.0" +APP_DESCRIPTION = "DevOps course info service" +FRAMEWORK = "Flask" + +HOST = os.getenv("HOST", "0.0.0.0") +PORT = int(os.getenv("PORT", "5000")) +DEBUG = os.getenv("DEBUG", "False").lower() == "true" + +START_TIME = datetime.now(timezone.utc) + + +def iso_utc_z(dt: datetime) -> str: + utc_dt = dt.astimezone(timezone.utc) + return utc_dt.isoformat(timespec="milliseconds").replace("+00:00", "Z") + + +def get_uptime() -> dict: + delta = datetime.now(timezone.utc) - START_TIME + seconds = int(delta.total_seconds()) + hours = seconds // 3600 + minutes = (seconds % 3600) // 60 + hour_label = "hour" if hours == 1 else "hours" + minute_label = "minute" if minutes == 1 else "minutes" + return { + "seconds": seconds, + "human": f"{hours} {hour_label}, {minutes} {minute_label}", + } + + +def get_client_ip() -> str: + forwarded = request.headers.get("X-Forwarded-For", "") + if forwarded: + return forwarded.split(",")[0].strip() + return request.remote_addr or "unknown" + + +def get_system_info() -> dict: + return { + "hostname": socket.gethostname(), + "platform": platform.system(), + "platform_version": platform.platform(), + "architecture": platform.machine(), + "cpu_count": os.cpu_count() or 0, + "python_version": platform.python_version(), + } + + +def get_runtime_info() -> dict: + uptime = get_uptime() + now_utc = datetime.now(timezone.utc) + return { + "uptime_seconds": uptime["seconds"], + "uptime_human": uptime["human"], + "current_time": iso_utc_z(now_utc), + "timezone": "UTC", + } + + +def get_request_info() -> dict: + return { + "client_ip": get_client_ip(), + "user_agent": request.headers.get("User-Agent", ""), + "method": request.method, + "path": request.path, + } + + +def get_endpoints() -> list[dict]: + return [ + {"path": "/", "method": "GET", "description": "Service information"}, + {"path": "/health", "method": "GET", "description": "Health check"}, + ] + + +def create_app() -> Flask: + app = Flask(__name__) + + logging.basicConfig( + level=logging.DEBUG if DEBUG else logging.INFO, + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", + ) + logger = logging.getLogger(__name__) + + @app.before_request + def log_request() -> None: + logger.debug("Request: %s %s", request.method, request.path) + + @app.get("/") + def index(): + payload = { + "service": { + "name": APP_NAME, + "version": APP_VERSION, + "description": APP_DESCRIPTION, + "framework": FRAMEWORK, + }, + "system": get_system_info(), + "runtime": get_runtime_info(), + "request": get_request_info(), + "endpoints": get_endpoints(), + } + return jsonify(payload) + + @app.get("/health") + def health(): + uptime = get_uptime() + return jsonify( + { + "status": "healthy", + "timestamp": iso_utc_z(datetime.now(timezone.utc)), + "uptime_seconds": uptime["seconds"], + } + ) + + @app.errorhandler(404) + def not_found(_error): + return ( + jsonify( + { + "error": "Not Found", + "message": "Endpoint does not exist", + } + ), + 404, + ) + + @app.errorhandler(500) + def internal_error(_error): + return ( + jsonify( + { + "error": "Internal Server Error", + "message": "An unexpected error occurred", + } + ), + 500, + ) + + return app + + +if __name__ == "__main__": + app = create_app() + app.run(host=HOST, port=PORT, debug=DEBUG) diff --git a/app_python/docs/LAB01.md b/app_python/docs/LAB01.md new file mode 100644 index 0000000000..17c2aa8c7f --- /dev/null +++ b/app_python/docs/LAB01.md @@ -0,0 +1,57 @@ +# Lab 1 — DevOps Info Service (Python) + +## Framework Selection +- **Choice:** Flask +- **Why:** Easiest to implement and support, has enough functionality for required software + +### Comparison Table +| Option | Pros | Cons | +|-------|------|------| +| **Flask** | Simple, flexible, quick to implement | Less “built-in” structure | +| **FastAPI** | Async-ready, auto OpenAPI docs | Slightly more concepts upfront | +| **Django** | Full stack batteries included | Overkill for 2 endpoints | + +## Best Practices Applied +- **Clean code organization:** standartized code style with meaningful names. + This ensures other developers can understand what's happening right away. +- **Configuration via env vars:** `HOST`, `PORT`, `DEBUG`. + Env variables lets change programm behaviour without changing any code. +- **Logging:** basic logging + Logs are critical for debugging in production; they show what requests were made and help trace issues after they happen. +- **Error handling:** `404` and `500` responses. + Errors wont cause programm to stop, crash, or cause any unexpected behaviour. +- **Reproducible deps:** pinned `Flask==3.1.0` in `requirements.txt`. + Using specific version in requirements.txt ensures the software works on different machines, and won't break due to version mismatches +## API Documentation +### `GET /` +Returns service metadata, system info, runtime info, request info, and endpoints list. +Example response: +```bash +{"endpoints":[{"description":"Service information","method":"GET","path":"/"},{"description":"Health check","method":"GET","path":"/health"}],"request":{"client_ip":"127.0.0.1","method":"GET","path":"/","user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:146.0) Gecko/20100101 Firefox/146.0"},"runtime":{"current_time":"2026-01-28T14:54:41.735Z","timezone":"UTC","uptime_human":"0 hours, 0 minutes","uptime_seconds":22},"service":{"description":"DevOps course info service","framework":"Flask","name":"devops-info-service","version":"1.0.0"},"system":{"architecture":"x86_64","cpu_count":8,"hostname":"host","platform":"Linux","platform_version":"Linux-6.17.13-hardened1-2-hardened-x86_64-with-glibc2.42","python_version":"3.14.2"}}``` +``` +### `GET /health` +Returns health status, UTC timestamp, and uptime seconds. +Example response: +```bash +{"status":"healthy","timestamp":"2026-01-28T14:54:24.458Z","uptime_seconds":4}``` +``` +## Testing Commands +```bash +cd app_python +python -m venv venv +source venv/bin/activate +pip install -r requirements.txt + +python app.py +curl -s http://localhost:5000/ | jq . +curl -s http://localhost:5000/health | jq . +``` + +## Testing Evidence +All screenshots are located in `app_python/docs/screenshots/` + +## Challenges & Solutions +No challenges were encountered during the implementation. + +## GitHub Community +Starring repos helps to discover them, and add some "trust" to using software in them. Following developers just notifies you about their activity. diff --git a/app_python/docs/screenshots/01-main-endpoint.jpg b/app_python/docs/screenshots/01-main-endpoint.jpg new file mode 100644 index 0000000000000000000000000000000000000000..72b061581809fda71081850ab057d7d4002fa5f0 GIT binary patch literal 49974 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�w=ksp+5)r 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

-6^CqucAn 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 E0BMfGivR!s literal 0 HcmV?d00001 diff --git a/app_python/docs/screenshots/02-health-check.jpg b/app_python/docs/screenshots/02-health-check.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f0579f2d4dcfa97c2218f4ae891b444236abeb7d GIT binary patch literal 20104 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 z%0A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

#%T6XMys5dY7CQ_fIl5K{COa9U!Z>gguA z!U#Vvl#uDdg}$KnY-5km^=q8XO=%5|X~#FXGJSx+d%eQZPhfog$BQYxJ_uvV{dOJ+ z{&0z2!mI6P_ZXoBkkarzTOh$W=}!u@_NxOptp;x;QlqfEtVg+p<}3jwekH)pbUu+TE|D5CF z+m{8B9fUUu*V8 zuL^F>{Ja6$@(8)VLmV@_CRXYk=nSOINO*$>7*e9jc<84QU_V zW`)ewFCr<6>~!!fmkaC28bV)w9fMVL{{T3gky_r?_3>hCH!bWl_v}nXcbZ9UU2O2; z>kr)z0tzTy+oKt=t~y`zM@3wxqCWq`{V3$Urxsvy?W;&8L`x#HVx)km=0jSl0jz=z zbW}on+#SAay2|gQBu@9o2r*v&B)~@Z8xEs=NHBbp-dfbtElHO(zc9Aa&z&f!l$i zQX>vv$uw{y9U%h4j1bWql5*73dM*9NUIUcKo$Le#)GaOheN(f3N+h>QdQ(#|L2yzV z_b;tIuD!C%krkVxj@x5Iicd)gAKFf?_S@OKox?u$4>)XRKq69vGrI?rB=G*TYyOkt zX3P&~l!LL}5Pt7^)z?Ua4gMC{N<%}_Peb#D8YC_XHV>o*i5ej(`}}n0*1EFg+Fi67 ztzAeksG%R%lOO8LU~%Um`478&A;F=B{#Z{wxicfmotxy!`oFYIYUum_VY9eXJ~NN} z0UYYd2miJGtJJi+^k0xLrQpsSY}9iaf%OM8ZnsVf^N0f4<5j2h^_-d4$HLO6;?JW{ zE0fiNB)`q3Z!+q!TS~N&PJCN4G$ssmN@uNsWk&OJl;95}Wwbx@31aIo2`jM?i& ze@1ibuPP_I+~YNQ!4Gb?QokV7`S=O>0F%hQFGka*>Nb4f_k{h9P;#2$AcJi zkg^j9*uw11`!EcULfJGU2nSjr_M%vbHy?=PaHv7%+eYBKGTELx@Et42h4)S6n*Gec zg_L=!C^)sxfISe0gaNgW?x@#XDFu}$!lZA>4%gYFpB

  • fefkl**U_CLaunoEl`x<59JQptJ zu@t@??|4=6@RWA@`zb;J^g-cbHZgzBlP$<15_Y`}KnlE~*s=a%;xGani2H_bb4*9+ z{TRa$i{wv+*!ZHjB-39MOJ|VtJc-vb$|?9isV_UtWAn{EZf;CuZODI-Rf-9_XklO) z`XU>4Da6n>kY@#3nsneM+2c&z?oFFFrFW4RA;Z(Yrty^5sK0%2>51Ky#Rm<)cBS?u)~+tknq7v*(lcs>V_|P ztsD^?!_|!x%+vCW;nIA_MfOEtH><<0SGkwL-k}gt@UF1@CG~@pSWnv@!1{h*!-fM_ zXZ?%N^ZT{G)!?nSyJ8>M+!%L0`AnQ1sx#j`S{A$J>UT+fAw(A#G<4v-?YL5UckL|* z3maR)@yc$DYWs!~hbUZ+jyjKk#r1)+`u>g{-3TY&apag7&r*nCAmlK&o(%OhcMx8_ z5h>|#t84i2QQj8s0=1)TtpDpaq+5>}&b%lLaNx}rNQ6<)jKD7pr|RW>(8oUjI&4PH z{du;Ht_S_;fuPu5&u!F@dSYU((sWrGdr;WWWv8r2c+}+cz+j8g%>I)*RqRM)=stwm zTS;6@M`haRh9FfYLiZ)=<87RS5x9X?2X#z2v54ulj8e?>2ZY9WM`Gn2s_9u8oOTS_ zZ&8O_bJj`b7L`k+;`|M6kQwnoWgKgZD*I^VI&-DG*vbjsfGdU^Bs93pNNxQapcp6QlSz*$2 z3>ZJSv2stDQ93>b4^l1WEgncl!Tvdk`QKb>+OT2*I3ul4xDTJMu#I3(r@SCqMq=4OOS_1<6a}Q2wcReGCOWneJ zn&(ZcwV$G$Y&;^UdqFY6w;&&e8a#AfUc67?ZHwQxFAmg^Mc_IOI%8X6 z`GLBs1xyL<( z-J-_44WtD(l!eKyoHY{bu(inJUKa)QhC6Yh?#1S??DCB-c$$kc#pb+(9gAvkgnEbH z^>K=0g0(q?zv9RO)I+1Q{E#bbIH9NqP~Z7n%@ehkaFrytuIPd!ea^BjCA4Ewcl z_y=Hb)~dv=U{Q^?rsN&QsuV^ejoQRX0DF&=_1?!3dq>}~ubPVv#aIzPsy$}F4e zd3!+yTaSTwYQX6d-DlJ30{sbI81R?`rUU#xIxwr@7cpV@ zse$WD!KV+b+a6>fnwXZ;oS^51i|%G`!rxPUFH3iyR#1IDoCbEeUjF~;^S`P}x)tU( z8v9cwtbvqFg`x^WktT$FFY~xedzqyeFl6{q5N?xK6@yAOh*-VpbF82=3Xyj=)DRiBr4Gr57!%ePSxL3MLOAJUlOg;I@ids=3_zDmycp_!g1sV_kj84 z@!I=;QHm(qVCGX+9A-U&J!~>w=Wllf(fhaP%pX)tX&0NLvI}PtPJ|JIv`|-Xx>x=H zyhC|ERecQ1D`MBAN;)SFCNu7U+GJ;OKsTsuDZSsxp;JMzoo|+L>Ua8tqkYy!wx+2v zU(TbuDYuf&n0;fH<5QXjyCN+E{J8eA2m5DNJ5ZNcZ$u$=M(kx? z+kJP~Qz`*&{v3?I8_8+Zdat-p7g>cwf23PpUhO#?jjzZJ4$p>c2O^I6Nfq2%b@4A- z`42@99CvOI*OuYBkdYAsd3)rGvYJUByX&HlKiT7%8M0n}4!R+T3MLq|Qu$ z4l<;nv$Aa&f*PV(9H1$g@lT*N&d0ZP>=?2 zLYVz2w+#+z7`^IU@MuWL9Lx5`VN}2f@`~5@{Wfdx(6&(=+9bt-%YqSqyw+1ID*y*CU^HKDn#~jh<<6v$1BT7Ee#Age1rchTR?7AObt_Rjv^t!g zyKfJjXj+=Jv8`-C1-@9m7=}8TM93X}Aw&vRU>;TnXu96G|AD+$VoEgDPCkMnqNg1e zI-dg`&P9~DX2J*tI@BB`xgtw){NymXB2Tmxud-8}9?7NWXHO5B(Seuk)oJgpXN<%5 z4S2$#(ka#idO2|lIUv#CcQL(TL-N2Lt|%QY!Q&>1?M*{c6Ks5HY-~Jnaiu8_eCgaU zSg-Rxo4yT>k|gN2(@ip4`%Bfi*9FHwgu!LYoiXGW2zBDhRomV`OnEHMb^NJSsIMW< zk!xUWcC%k!s~jcvq?wO{qlgn<JOpX}H12 z4wbP2DnKylfJO*XEL!-zHT#+8=3J1ee-uW%*#zVAT2-s_x6~VV^x@!ZpB@`sS6lib#q!RIje-SZ$n)%&81ZOA|JJu5wGLm&Xnyu}FLZP&xpX%Y z#F+wwRhmLLKmdW_WiXlHdl`-^zmjBN0uY~YubM=9O4+x1u;h&XYnBPFCI(ax*|wW! zE1_&=G=ctutTXNIl*c{sxzC&1?qrXR5g1|C{nW7jqWKRiF8lWCA34n7>>q{kcjtTm z^31;ekJ^7MVKB7s&UgP`NzS-1JB$+vGq*grHxb&(KDc`O5B^_WqZXfv9|prSlvoXw z{Q^cuX`IHR3GkJpH${`2UJSF&4iBC}F{5{e3X1N!Whf^)DCsTg5X>ILl}cizMsonR z;z@z>wsaTHARx(jru;gSU8N(moi}kNG#sDPhDssBI3=iKOcoQ~>iusJa=MXiU*!nn zPk4psK9giXUr98)pDY;?0vzl-kqb#oI~tjk<%+1HONtiLT|n?olI6rRsu8O($k$P$ z0B8J?(cv+eLDToBhKb;q4vY$80B(|v*dDr>}k;IAk8T&4>dhV`@;$b|# z3@46LJ)6CT(j0j)&<&?N&-Z8lL6F*eXlSq!8LRc#*}CE_G*B{gA>PNKRIK5l8Zd(I zP$3n<84{vFoB++)wM67a*x8hD<9mhI7pzT8Axy@FN09DInl;gx&re%g2@xr9cmqWx z5E+&#R2iUUHZxxad$;s)P zsM?4k2T4e&`c;=x;eb5~{DTx{YlFd`tA>tvk^-U_$APP=#R3Refruor<<0WRI?8q& z`q;N*_{tJI)q7L44Q@~aZ>_EGySm8uyQsbi?PRa{ny{iS20iHB#`$!8-a$Y_iZ5QC zB%!~pH z`f25u7Cv{bZUI0e@4ZWWtiDaJC^kKZ)AZh)$+xTUp%ufyz-8193$<6Ms+UzvhBM zFNmZ|X|1Kc2Eq4!Mjja-lGc_1|K=b2oGvLnEfUCqQb1kLO=E))<-4>8zFL0*%@s>% zuB|9atBE7cBLH7LwuCCh>z87f+wZCHVU7}s(*m(^`sgw0+JREQJemY!DvQ1{2S$kN z=o>(43c65inqjthSz*BHER-79SZINR(?+F;nM>Lyq1ghAUScty(l8nb&J0gQVXFe1SHhP*c$()8*5YR zjoY_W+A+x;hCVyi%A>%K#p^jX*t|N1jIirl0+N1*f%VNp=T&GL*IX8)iqS(6oZ$jR z`H;<$Xqe<{3AAuQmq$|6niya{_c^a~riXZ%WVmZwLOcn0pbq5x^LgjSr&V5@a(let zj^=MkmH=NF|0_pYa12xbH>rsDS1sc6jAS50Dtu5N2V_I=Xb?6I3r5TEA2aVlP*gs_ z;gU6JFJ?b=WO263C{0An=#l75Dg)GYHPWFn;wAJ(AJ6eR_L?>ZjPRyPa}>E?$OH%; zj)7*E#l>2~1)b7U@GklnOWS4nMkL%@59`GZF#z4NU_Y~$nV$#bf=Bl?Kn2*JK?bE?1l z1Q-JwNfKRO=-tP%o>CQGe<>r-otV!C&&=uiWW8C(`Tsa;nSw zuZYsq=ivW}qhR8gE^q4FsUb?wCzbP@Xc!~pUjP^b2Jn~h55V|y$$tU=gR}F$WdA9b z@_wpI_%g@SXZ!z_^DheJ^@it@!++Ou3s%DaP=D+EZ;}7j*^@BRar-6(wr_b|>2 zM-L)oC9FSYmI&-{<9-CC?vuJ7R2S(*jwUNfVq*^KZ;Ag+ z>Yd5ixB&Ju66JWuHl4<4_$6WXGFtdUvdhg&mQU{=K;^PH;TUbO5b7LRIOalvOk(uS z4&F>QD4DhAct~O)nJ(^gfK{z~Pj5;fo@iXyNil&WHUS_y5$NF;gNTVYU;TaLnE5gm zUqcXI!&QgFnOgx^i#afYv?Ga;r}Fv5@#q)v_km-v_f1h?fR-;ny$5*mxj8UG6+}5e zK7Sq&sCMTrb#>bpfXA+cC@m%!5(xnlP6FA{udFg8@DAmvS2Q9qER~4rrX9azV!|3X z+DBhfccO&?=Dw^)y{~r6`}zgltu6t6)AN|vuhgdh?I(@Pot8x8IN_G*ok3IzK@DGX z4;6eP!&gNOQZYAZor=#*#0!mIU%<6NnTFT~i@>FgRsEaYkBEeB2?Yb*-22PSZzx1kPye~#aiw+M|V z)dmaebU3r_d64>6@b~Y`gZrG{hLt$<#Hgwb{sqxg0gV-{eDF?jJ8l?KZ?Iji;%zK; z2gYUv+Y_9XR_7ckLgqB7sg@ybuh?%D)kQ?KJVrlH zx~Xn&Cz|kaPuQUcbPkxp;oCFnr27pGr*!ZNN?c9N_*D5%u6~yO>G(y*JMTtv>Spju zIS64bV$&f6D{ijT0n@LD)Lid9ulNX9SML*bYf zUK$pUV(!2oX(cKf=;CF&%;XhAvBI9t!uyYUcI}&kVBJJ4qo&@{5=54s9Cx z2===M2Pat65zHnGUVNwFeHM6r@fPwZU(ex^XaN?A4V}ohWAkth<>?*)%n?&PVev9`e6<-v80VdYFQlX*P0}=hs~3fL|K+bAEV!f0#=3(Y*d}EM)O) zHX&T;ZSfCZm>s5hjrIRqid{RIqWd)fA~W_@OQ)el*g2*K9%<+zj7e|4WIrm zyuq`|6m7?0+yljQ^~FG0^>!7>5nVud~Hc!ki_(& z9nu|?6)TaWG)u^A7uhGnB_>}EarZ5qZ}OA%clZD-VnPlMlEO65Bwit!KLUuL-sN5e zU#6juv7i`Gww^4uO@F1r*pG*{f3M1udL#Jj-5Sh`3IMw^vrKLr5~dHxbsQd$$kBNp zC>eIbe95AOMc^Diyt^oK=mUt)VVs;TZ_^`0k({dwgqBs3ythi#T-I$o(+qc`ChQMb z1tg%7G9e9A`O`#UF5mDHIm{Xl;~|j3JV+HL8?QTs+P6e|p~ii6zdoMfsrg%gUeEL{J5Svve5bZ%fhWM6o9Zm>j#r|;~L=ygDE zP> zw4xX5Q{JZ)TE_{`U`Fe)+U%-yV2MHw5hIDnH?ckowmEnHZpmiBotRnnokPl~#h*>% zmhX!Y5ocKDhZYgZWR~e`*smijvm#11Y>%sP6Vm0eX7KQN^#Rtk4Z_CLX!+e6eq`e_-{(R0a}?!N z{h}4Vt+A|Sf!bLs@m$9gCOr3a-{vG6<70e)FF-90DuTIfVx0@g=;^YVI0p$kuCfu zV?TbQ&Y1|gp3x50*$@jF?EwH_nh6Q|;rMw#pa}I_oKg~ZQX<%QnaqGq0*>p`-X8#K zcTLev=gu!op^$Mm&M!LrI8+!kOu=o-*9nxO&h`UG2R`CALXF29Hw*>Mj>82vF?m-n zn7+#xT)_1GY}0Cl0L|G@Nr+63yPLy4Jbb?aY@F+M;N6`S2wu80q=l45+cgCwTYE^T ztXhl>W>c*r6&H)aB`mcG#N+)Ti+G-HOs9)8wUpdw>k!4k20!TMuTivt9x!T*#xBRq z2dC4)s?4g?_P$RoEq|9k9no2uh$WK)nD_3a$AfP5pkZbh$2V%NK@^LA(dea4oH_zp z*sI`-YEMm1mzBhmv}}l?s7j}IB)Il2)2aJ~XZiv2ZSp%xkt5y*&WjF7W|`+)eO`f3j!p<|S;6a4}5s!QvbFp7N^6 zQh*R7GvNgXcH4@Zfd$J|h*!s!`w;2ljw>?wm}*Z2i~3Q_HZ^iP*oAyQ=*@6HM0%fn zM@4#Zo_v>cz&7U7=?(ulPS;w)>#X!}K;+}8a&Gwa2f&Rue6`*A2OvZhkyCBo|9C*x z-GwA}?{v*KM!CUoTW9N&KuF8BfKhPIVcBw?Zd!S}F)6tFa)%l8v_Jmo0M2h}0egniV&5l${Vs@WGdqc-%or{>UVb6nk(8?opn3p31?n#DQd{moej{b z-K!pLyoi`Z%eJpq{Ppf^`b=fbyK_5!51{<;V-G;-`qcFcq6v-)#$WZke%c-ZA@;mh zZ*$+#z{q00jSApuIzkCuq{6db!dwnbvb+q4JN1n#|2N2Wj zkpoLp|4A`1%|d3wD_C!LPO}eSY3JV*lXm%gVzoTJS$c?+%7n z{w7M8amKx;SHl`Ct-{i}r&oQ!36mA&Pcg&cZGhKQOSFAaES##^^k)oK^ zn==QKXU7?8Y?^oU8H#mEBBE+g{9O{c*h~a#!(oU#{%Bn@jaqtH^s|neh`i!1q0~V% zWV5)8Ph{opAcU`A0w*({sxZ-{ZfGZ9L>01^m)ED#B062r4m?RaHG9m}+{mmbkVNfY z?Ltdxqm8%JN%4E&NHkuwE?ZjqzQZKa)82`;Wb|ZEg~tlO=%`IV_y))6a$;XEf9+u$ zJTy0^iXq5b#5ogJZ?RVG_&WybIW2jel}ze`@OZxEanJ$h)(_yezE034Re7xlx!9a! zhp&Wt-F2s;3tV~6ud9yyd3l;ep?YJ5Xfr}q6}XRoayxvBuX~XG`>efBrhd3`RkN35 z)y5uS#Jr*mu0L+L;>e-LKX|>TC(P=rL04)?Tp1ay)35D@w+4K;Mkfc4KIhZeCrk)= z>n@ODUhzfZqWNq7Rwr4J=+}N|t)uB^GyH6rv6xv_c@PmXO{f!aD6oSs#z~{=Spg9n zL3-{<;Ts%%dMGEhYD`0r!<;A+5?y~B!V-Q0HlXoW3qkOeegJtKDNo^g_oP68J>beo zyT`RR7XWO9t+I4ICCSn*D?2jqen)|f77dl>Gj=%A4`9q(?kicQauJ>L84mW)*U8<7 z(ObyjC#c3T4-Ks%`$R>^{-yd9>Ox%4hKYJ0zkC--A+cc^I^ZJU1Br@mZCg)^IpW&Z z!)A;Gvy=pc$E&6bB~=zemKi~G9aoC&miq_bEbLifYNDPxSLJSs2gxp;&z+u*+<_m% zN9=fosd#c8_j5;=rYzuNlkZR}4V*VvDeI2SW$@{U_mRt3j3T%+?QPFDnur+Kk1<+MHS15Z3e_dA^1w%taFr?$97B1M`#qT~z^piOV&4XB}`_dW1qf!;%sM1W!%L@5)Xs)-ld@%q3WPlm$8dVL& z2IIW}r0E4}!GU+uIgl1Vnu`KPr*U~5`?zlahi3{6Xwh)rasl*<{sc~vhJA5V+Het; zN;c}+_YW> zztgKY`a*OW&5FrvLj1vAGL9<{Z8wmHd`|hA(8FQq?UZEhN!kOy@7s@FjU^a}eFmAi z3N2&dw`#r2ye^FR01@jNZGfdO@Jf$^Sh`8;*ZnzW!u0Lom#%1jryZS=bNiD1X9Fl{ff2bVP9jvcYQBK=Bcj`i)r=lESHe6Fdf9VAw zd{}1ZZ-(oyAVruS260)+m6@BZ9k`WzK~h~{YluOTPoG?*&^Qy3N^l{%M&Tutk~sxVtv>YS?#5_a z6`i_Q1h>(BJYxD|^jj9q9z;F(QVx<@6Er6gd8Nzw8!U@@X|BG4l*M*Pre4N9t}PjoE~Q5wn0l-V>MRtEZqW&vmg!op_0Sks@`##&|(X8P5C zwST3}7;`>-fV7H7y$Np>QAo-&1=(MdQ<)%^40QRzs&oGV9Rop9qblx{vRbPy0NjyJ zBroq2db$~qhQk`P8)X6=Fk%6&x$^m15iZFre_O%5@TOUh=~7GE#FKK{y=0a9?m-3(sPgKwXC~nh1u4c7Iavc zAR<^d77mW#rJsm-Wr*+|L=T!7+*`-}KrRP{sN2M`aur^i8w%}{zrU4)wNV?KMc}hg zrQ#>9a1-$J2~f(pN!szGQ+6?_u-T{)2+i6y>Bn;2Rjr|)ZH){xU=bZEqqoQ;BnrMK zbT*cwtrj~lwAic*V zCK-=T)h3yu5H4Tr%V^YV&)yW(*T@|c*Y=qSO$`k$1;SK?OeBkx$beKwlaW&hC@dli zGX+AzAb_(5V{FooPW*%Xql>sWcA3mnDx1+FqoIuJsDtL%wECrWL>zo%qN`zNh^q6V zY~Y9ExK~n$qJB!>`Z{LcMCWlwDjZQ)7%%V|1Df?kQ+1OefZu_-y*1(Mk5eyY@h{Ujb=WySK^H`t-Ks~ zbAIBtE8@5)U=g#WR>jcIO0?b1o=nty8r8-I-IXmE`1a;9cvmX_l#v`#9W*zMK{2i7 zP1sKXZSR8Sl>Y&UIJE0fD7zReEjYQ&%?~0YN$_4A?zqJUK>?ZgwWJMSoS-5uq10Tr z9=CnY;Rt~DNZI2psrm=POF4T7<8EdrXQS>&8rCsgVB-N`ZV)n6OyoN{j1xDM0q%8I ze?%IH!s2_A3>{9mXcH*4-F{5_tXnB}eGwwDWk zWGpknDMU&*6Ig0+fBM z)=iaw^oO>-;|e&h-`P5@vY5@CGVW`{~6dWE* zLe^vzTDb2u<;p9`$m~JocJ5_MEPP)+rmLZp>9Ako`MWoG82=Ria5cco~polv5fN`dld^6Mj&uogil%(J2Z3)`W1m zNn(CW8vqD?E3bIAAln`Q(EZg2A474L@qe6P3b8|t>bgUjqK3CinoA6guw+~ zEDD@Ea3U91J~jF-#@1t%clAtNRPibzil=X=i9GNcPB508&Rr`E3V;$UXZ1lT;D(tC zmgz$XM;DsDSKoBuWX&Nfb(tOU!TMQ;JblpbUx;8IraP1|PiAZ>4^uf?F;g!bcQBbS z<=xQBrymaYK9$}+mpPREe^rJrree1KcRptLf4TGM#D`7?MQ0Dwk34f7%{sm(HTb+MliJpA^R@LYd z)=7N-UxoZzDc}x?I=}0oxpPQ*Cg17KoQk45nL9_g`6mPvq(rU*q?-a!PFbqTaI#jS z9W;%ECwN=8en~xj;<#v(4{Hg5#*z(=JJ^Xt3DO@fBT`DtrMN@`o@T{JZfN5`mF#Aqf=(_6g`9UW$+Xd4_);Wdh(NGJ;-IG9yzkIGI=6kx`O@?(FQS7re;|hOF5f4 zM0yQId~?Okg^zs)eEF4Um3TkehR|tv@u;Ap0yXdwSVYeKbiF7OsQxYmZLi)}F?F69 zQ_gl{#)7kD<@z32bGJrNL8iW1vy64dNg5ZQPS+efJ8-+QGTaP zC-sZ~qov~L#c*J2oD{;GmgLfe172F;j3oi(;Z0PIPGNR6+>GUe3bXeEh>!E=f&Z|7c0r6rTtX9~$L zuJ`L*COL>C6iT1VhRx3;_;4O!)JBeU+udCIVc`#;0Un1~u|;1(k9Gr|+Y$t({}J^4 z(I7rJuvgp<*K1;Az!tw1HR9xBazA2o(fnI=%oJ@q`wyan273S7*8y+g4j;HcqfSq$Lr9P#0;tTI1kM8#={_05{My+zHPhMZ( zDN7t~vJ_GZj(vuo9Vkk<5oobcuiA!z;J}1sjCa1n)RlCL`m(z3)}5TDnL&r;Q}d3; zD2<_*+l()*<_TjXKs5w0zZV^J5(ly0@&KAQ+BpQb)1Fk)UmyF`w_C1TVUG zbtkY2GmC|*2?(v(HKP&uv(shlSUnn_!j0)V@u~kFzW~mOu-uAES93Iy;ulvCTHgv= zQx?HZZ2nBC|(M{?dj~M%+2_FkZsZ zKe9q_?zHA-GeSI$+wqez_^Hdd>R`+<(jz_+3JrQ`pMqFlu3+p`yn^uqaRiK7s_K2z zDINw;eh);TC^b^m6U;B|UYt%+etWi;5sEoz)t+Id>lTjD#z6k{@)`CuyrE2MB)S4f z=ZgCQ?^^mB7Q9_Ag_TvOwfk;TC?nft_$Wsi*$3$(1MsI5du;BB3zl{KE{G8}O^qZ$ z$7Fcc4_t*Rf?C51Y~51xgG!ok(W~q11(Qkz_Z?nF#nT8OvdrmecVtTYG?rH8K_*Nh zlw;$Wps)$gM7=c9G^kag9Uc#V!^PjUKI2m6JKU@`z{XpCQL5z7YTCcVekp+>v+@&R z!6&J_7rX~Nqw1@2Uxj$u1suS$!PX>l|4029_|xkX*G|5n5-6;X*Gc3(vQhuWBt_~? z&=P7PQZBzb<~+eA{+YV)dG`x(%$z2S*&u^6NNAE$4D@)KE3+TwJn@%~&( z{y`9g$CjBA`Bu9g2(|t!#mCZLNu*qeb?Q6!{&#;oMv9-}7=Khfe_1Z-L1Ub=XoeD0 zxu}uDH-@3L3$*u}x3K)2OGzMqJZ7y<78^qmsm2Izq*WeR=gxe4Iz$GG;LYn0Gfj~) ze@(&v0cv+8(2rCV&>+RzC>0or3Xp;K^^f_)VB)D6X|CgD2nH!p;l2khf7gfm48Sv{ zhmX$omfy}Rx0sA9G_lB*P;+^!+n@&y)E8?TWa;Sn2Jn?qqjmEB#7mBb5>?RP8dlt` zGhfb((kVT2yzf{wfI~2M?zv;0GLl1GU18BNaS400H8gz9JkQ##vOy79S`yXEC0 zQ&LjX58hxU`(9TV=%%OM66x;lT=8)YugQ%g! z$)mo7_Sy}{nMOBvumZl{*H9Eya%qPW@t+B#uOolrYHiafWWl&17gz9*qdp1nyiPRu z0`(7+Myu-B{n+=636;-Z@kUouv%KntjX`^IJkb91T!=*X0w#@|4k<*R zzfWDNbZZy<1K8uVqAcmBEEI~Fa2r2F_wLrV@D+=_USVNBN#pO=La)x!9O*ZIGi^r3 zHQ?SOS-HrWuVyWl^=8DfvN^yr9n1UP{tFqusq>d3Nnj9tvbms(+be7VLaPOe^U%!J zNWSzFyI0#-uxSjy5TfgwyPYASw1l#oPh+Qt=;-G+C)=*#HD*q~hHRwn0A;1f7{DIW z7VyCfe*pjeh~g5#g|FK>KLCJ33!t3+S`$I6@l5Hsll?e911K&X zw}LqW*=i1f#(bT$rLbyKv^+nqMKRa5bNSZVfuZpcxfHjW*xOI6)jcHsYqwI-i#P)Z zxrsdELv#g7;~Bo>;R~O4FPtw7>a9;#HXCn-(qCZ0c0 zX-Qcp^hf<*53ORR?O#8l;Zfz^OuL=z<9G<8GWB8wvSKfCa*vVN?v)eEJRa%>m8u(Q zs0Y!2bZ19TC-3?s9a^6+cx+pPJ4i%b2s=$wi@ANj06fQkeZH6QOhSdbiCXp*}kY0TI!cLcY%Fy??KW7(DAH@qa&c z_To@{sep`_iil+2y^=0XWoLK#!M>tlfb>bM!bRUKC?YXRR-aCn{Fd1NSJ!ujHMw-{ zCJ=fHJwOP(cWHqD(t9t`LI>$cm9F$Iy+n!zq@xIe(iG_(1f=&O5_%C3Ve39|zkBa< z-tYR(&$(tY*F4WNxo6#L-D{2M=YW1+Msx20qLD@ z(R&uU-pobs^(1e$)r>53BRS5R@zjz$*!s3vSlMPu*xjr@iWIv7lJWaA7bZQCPG}Hb zY2{GgjN~#7VA6HWZ1ec!c?4qgw?>#FLvSF0ZlsoJcb$?$ji%HhtEZskgx#v~6HadQ za`#3*hQ{rVzKoO%>``<{XO(bjLFn*Y7xVr82#>IC1goR?;LQIsZ~C{%)y*`y=pxfFvz;kBfpNEp} zPg0RDQ?I&zYao2ZUxQF!z7{hxs~hdCB`xKL~&E{dOD~IG@lf|Qjm{!Vxe&2suPi zn^sQ~V{AG`Jx6G1?h%u+`5Kqn_|g(jG75%ttG07>SV;;bfBKaJ-=2hJUiuC`S0ZrP z&jcLr)JC1km`ONJlv-Md$02~`7@Qp>9SKz+SeI$f|4+afRMdw;Yi{QP7D?2+p{kg) zF-rqs&Y*Yf1}yE7|>l>M1E@UstQ`qqG*f$2;j70s=FHy&2VkzPr#i zWDB`G?#4rm?q*4K9jsp&y%g-zkff^-Ep^xFwyEJMBel>8+Y!gO?~z8W@4a{gYO66! z)L`zGN|((G@G2zn+-{kMC%%-mAi5!SO>ZpO#MRI3*1^lN)9F`OOzybFbRl!aqO5Lu@z@w-5yH8B~Q(fhoQt$WK@DDi}C2beh#-t z*~TRc$2)nGFe{F8Dn>|p?|{mx8y6)m2NFEg>QU??-8%KbMz`9Y?_yn5MLUyx5dbvB zqtc)M$MKn&79?{f33<>iub0d8lCS9P zKxgAfk(zZ+$&HU*<$104#)$%?N_UsiKzWT`l&or=AJ<9g-WTum3>UIQ#B_e@&{}jp zx^E%CJd zC6YR^1@I@9H7wqYWq4)USee{G;wSQ{u#Ia*IBhbF?;nwl$f=zjatJC2c|Ioy!#87!Hw zO|0?9`in6-xdTc6+C)VE+C+(j#rc^ki}*iwg|{xE@d&f&t%G}x;=8xpsNJYbWHxEs zn51Zd>R0!_!g(N$Pu+{p!l-&q75_DhbgO@xMfhA++tGPexJt{8;ja`PI?z^_@woPW zWY99RJ+bJ_dATRct)Gldi@JpWw8lI}ydz1trl#p{T`53w(@Q5OCs@YYM)!g?qgosM z?)QH7-@zyp#a^(ejTR6ppRKg>SB3P3KTf=O#8! z<_GgVJCGu+&a(#Z>WDqXV%viprIU5|QGyD?Yyh+0@buTXe_4fzm2MqAX^=|po2w38d^CNqa_`j}xS2e)W@A_|l6zJCvr%l2 zZ9YIBpC^O5jsDsCwb)x)MBkNMO@GN(NKLuLTawZG^$A_|$|NQ?L&MN+zi=%uap@2= z@PlGFFE8*bG#u5(Eke*9^k{-{O8(o^=?aHLcmc07l@`5HI673*T>3m-t;U%5Skz3s zjnLfl9Vh>QUmn&VfSF6R5HPZv=#TjasHe6{JljP(3dh8h0f1(TPnG!DxYuSh)N`OS z6^?_j`;rv5$U)0*aPi{Qi`a5+vuo4JTm43iYE*)+vKn z6&;yHz2XaQ7x$*Ix53&MZ&Kq*0R>QY-;>0)C(NYajoSJsJaa{XLb@FUOXM#b>1SVI z*7XuC+b>9;PJvi)&MD3vTCZ&eh;T$3`zPpLX{(x;;^G^R#k|30_E)&Ei$v(P7kA@< z#&keuMZr{x_(?_5_s13%6@mP;MYtX`tv6h!Z|C-&&=4Qiu@}8)yV+x zLTHO>(&nM`OWJG{?DPZ4N)Dw^ujxi{OYgN)qHT6seGY#Ov6-3d&&SalU5fyAZcPcQ ztNUUu1WqKcj95RT+ElFiMO+(99~8Eb^e8(5)Yt-8yx7RbNK%J&SH5?vLAPiS`K1hN zkl3Un;FvGHcfEkoaGy~wH<%DTb+@lB$6iHq3f~Il+%G(ntJJI7zS0{~b{i7iU`p!e z#5Jfz8bSz8YL>5OJYp9#F3Md&S#J|`$v`+_C>bTvex=by#bam=90rSMMLB zFV-_oQpu}wUP-M{P?m@%*Cn?buMpb#_OurMVTOZ`;xYG^ zaa+ZlW0c;mzC{sQIO&Qllh0%)Yh30xWmPQY;eN#Du5SR~h|($CUSLU{jUh(i5C5i4 z+U+#lUbVrODV23Gh>i4X=P_p)8F=yPz^{Wg%Gg#trlS-BLtxx@@}ST)VSMdOO@Ns( z0H?M~%n50?toeFz?=c1F4MZjs5iEx~jnU3j)136%MKn=3CQM2yt{pe#ajN59>D{eK zO6A*`oOuOOJBb(1=Dj+Q3f^7ZyAwz+x%u2;x9$=qk0n3o&78Zhp>2NtJA3|@B5EJF z(H=NyN?{tVBFi$QQGxblCMxyw#G|#Ue7Fc{_3`K;@r3H7{dlBG|3JtD0VqbERz?J# z`r)k%()_vOc>$rL8Q?9bvu~}x_r|$HyC#AsYZ_9ae#(xYO4Vu27ZoU>3Ac$$x7%gJ zwEuAW{r=hpGPM(8?HV3MZ{t>AM6uOs0D+PBVTn`UY~`_c*4Me>i1{cK;B{T1zNH65 z2E4dr(Xh8!fFCb4rDjat?p(P5cdrK}6^HPq!Le^TCvZ4{_KWm#4}5eg*8}gVB$_HM zGfbGL_>$lnv2yrN_f%@9RRxZm<1P%hJuRuE5gKxyowEe0)8ohDy`kF}h5by?d?TIjC15ng+A)zCj&;XnMP=A2-DgsA?A+vUQ9P_b3bWObQrA zL@$}meG9oHe*7|Q{wSpwc>c<9j<2pJxtSQ8Edg3U$oXAVZ#bp}jTXzc3Pj&=zLY11 zxz>~L!c#d+Q!tjjDs5|y~mGUg=Lt*AIob}NDn1Ke@2#3lC~ zXrPsYmkj-N$S3Ho7#WvEM+x>- zPv`c8@|etAUYkEqba=bsZEEBlFCJKOllMCKc&3{nk_4c>iJ!JM9Hp?Go0MQk+&|Zn zCWt%&c<@W*Rl)D0(3QDl1d8b^E?Zd7=93D^_a_s2;&GV(7W;H)EAI+8h#e%MH1Eab zv4msIoo7?$`IgU)X9gjx!9G8sTY_sj0JHSvH~iakbGQ6euO{ecw;f=>nV37)yGuDw z0_2@n)5>XFcA`^x90&YRrvomRjJWsITC|Fwl_ymtmO|pQF(bQJaDN~57l&}*g3x%! zR2p#{C#U=!a_E8IvWzpW&UeOd37+XS939?Q;RjGj+I~s)Tj|R*6P;qQxP|1V)N$`G z@kx{8nt4jOs?3Q&jMN3eizy~HG>9@yE-GSF>JF<G}a30EKLtgOGpxP=Uyr5Ihvad*fGCEmQWAqKI?=qlN1oJlwDp^ zuw3&+%W~gicRr8>yQY#g+UZP>Sr7YuE`mI&Ye9!mn9Og;g@F&CODBhjjx|a5T0ys1 zvm0rcpT0v=^kbeToAE(OE>%ip?x~3C%_wRAs3fZ7DIMl}t%jDkY|N8-YYX~Q!ZnQ? zaaRW^Df$v38abcbZ*PdZP;C>TqIwRJa-@6`O-kEMDCK~Hm~ynCNcact2W0XtLG1d< z@oTEmjAD!);loWD@K-ew4Ttwp($LN@4Ok*6ayNlnjzvjcVO48S-oP&E41*qNAj_gG zV^7+H5}D!P0iv^BsEV3FL5f7ngWF(>Ed5w)#bY&10x#k>Z+UxE`Bck93TSDJ8#g?P)NlE*24eWP>5z;Q+QE?=|$hMR*zrZCN-&R-l~#E zd$%5sjjWInN>c3kU8FuUO>=KVf~xIZ@zo@?%n8jK2q5LW9}={`;|0}=MW6DntDlpt z)@SZgmjbTrB~op=iw|HWx(9%F=zgp$)3z6_VQprHlztH5D-CyLAoT;#RLq*Zp1+2X z!g26%y!oUw`r7Dbm*5xSPp`-(HhngwaFH!mOCCGn`#BR%l; z7LC{}y|)>Kzsa)4?;UqtC}(!PW>X@QgOY5y`unhTwEOdY8LFjd#z|Xl6<-HeqS7~I zXqo02dsOfx##!mMTNnq9UuBD<)cv0~+78Cc0jM?v1Z&qpPU&LosPV@hNO_96s@LVZgZGpIVn z9-p;2P^;D8@7oAj9A{=xw~_tWu9-aV=q^{x&u9KSms*DHB;~?D-x@H)zjv6L~l7yh9$7>j=?`&whF7kk~aD>mt4(szxUMR7U%QWt<|O|q9G zH`9aVsrtqxJHaE;KPmRA3nwRi>B4{pNfRWene8`IGc@XoW##EaX2cUU${Zc-$8!66 zrvvr0L8^r5&`G1{h12if3iYeo8Pw#Q5ge5gUIPOF&W4o!A*jRYvr4t4WbUK~&ixWS z*`M`f-1*@FMv_5B>REQAghtv~Q}M9j-Y465bRNyI4OLFxJ?q}dy(sp>ct+1TT-bK} zq}_MAB;B0am(`Dh-?(CT-o+-MSAuRfz?9mffh&6g8E@Z zDiQA;Z{=44d~qACj^F3v7&=*#m2`xk6*!K%h|(_+n+D%~bCk2jcm zli`g(=280*4i(9W9PMn@yNz{Q^?~?z(nPUQY>{T zU@lOB+cV4xxPxe^AIzJv_qrF$p|;M-j=zI)1wai2{gLY?HniAgk|LXGl%5Os=QKrq zG)`LF#HNBB_vv3Txt1gMXR1~m4E2kzhm=LxR-<)%&Y}OrhX>YM6k@);4U}$kv-g>_*2Z0rQAEk27Y6Wy6jtKG$7E63{sXj5zGHZ|gh~RVlwO zdm*+@{!H#akvzv#*%(k#7G+^5xWk+jttB9*`Xhv!DJ$OKm*KJMw1J0>RhENe42)P3v@`;ly z>Sz3-9$2Ao7(-QKE1hUiyL2a3i7>7SXUKZWP&Vp|j)XlnJsSUmAr%T8P76onez||K z7PL#d?{Yzi#~WmNaQTZMmeWXpSB8eL@ana{ZfCGys+$PycJagdttZt9Y)TR(jr>nS zBmq(}1N>w$BwibJ!5Q<9)iB$C0+ReLpS`H+3)#a~9G>3Tnv?zMc2iX|$Wn>y%t_Cf zmBli~Hve6zwRRM^S?+4+!5><+y+XFvK^ivc*YxM%k}E6h{v+*agi9iM!Ww2S6-+X2 z^0zxE;>|>p;&z2}XJ59z9rTpt@|%RjI<&C);*YYuL46*|1K*Mdgb9?WLW#47HX7VE zQ_A@|v_nEhhlZ9ZrDqlvCg1hJoj}ViWYQCVZ2l0_9QIZlO;{l>D{bD7W&lrHB2ddf z*0=H5Q)Gh=AAoA3J)OC&c;p*o4oJ+i(aklr^d=l}o&dtxGSzu68bX7$SQ|Avns0GW zB^xqv)s73?zC0pU%nDw5h6sKsP!_IR*1*eO)1Bgl|Ilg zg1Hw~5CwA{P?H{*d+#!Ny=t0A%N5_o#!4>wmyLH^eJ_q215gWuk*aBB2C{X3oG(Vc zD27}_l3h!xD34?7rRKlVA6|4sMu8AmDQrzpfNAk*69Dg+6ul# zz+tE|&l_E)vX@}o5Yuq9FI^0vVPDpRlvQ{KTCO_`D?-CLP7SqSf;TW6?^P zq#_eE$ov*cjpSe2Qt>+L0$$Fs8BSDPd>~KBtvc$=bDJmT@9B3fyH}2JGXcdSB zD*2u|^FQ6h0U{nA^eXW8`5ka4km|`>`6kZ_(XDR(&GHAhO94#VHT2LSVqsmqNlemt#8allx9Vg66xo$ zyKCA@cm)H6WshcvNLU&}=$kdZ3m z7^GOBJ-qgp-^l`!O_43yv3;8g>4{^=KL1FtVi!0Q5mTU|_vFV#Q5U{}mu&*ewT3+G z(Z{}!3zfq-sncsXPiRogNX|?kV|0~k$%=KW1ubQb+mgZT6B<>}DfjA-`8vz3kzm9E zQGM__XFV<%RSgWcdmS&G`5r!quRQdyKg0khn>m41O2!|#nzA5d`WV$CZzzS+HF$q5 z+=oqb{;pFtSsPuaAI1f<5oKIprvK4yBSehqHI0cGFUEa!p^uKJ`1Ac62gP<>Cp}1( z>iM&+r|)T8Zck9-YDefbTz#;)Q_r4H54GjULNpnE#w5k0JUNB>!nXv7L+qablFMHl zgVh)GWf!d%GK1ywm6soEt7L>Bn+e>F*i2U3PxIFqu=o!C!A8YusYIbUNQ;GOHN%Tm z+O3Ul&9}axC&M)h;{)R{JugK~TpP3-_4-7f6cy#tM@*T5==R!P)~5m)n>9yrI*pZ! z`XjsOFw1QGoKxlL4NM<2-Z3M^4)}W#{V7Z&VDyY7(ifHZ@C(aje4hExn?Z&%m^{Uv zTgH&4nqw+y~ePPkKKbpK?+n6pC@e@rUzMEIyhb7q-nP?S&;!RVDr> z25^V#jZzeL3(DeF0K52q0+8IZ)(bcV0k#u{VPhp&#VJqa#>P#h+)v!um)I#&b;8wW z353-@7MGhmcAwN1N-^tNE3yYafqN^Ryb!v!uQpbTYC8m>#t-UioJ!Xw8-z9dHV2Lt z{mlaR?-)qs-Fu$?$nlfn5tB9-rBN4oTjgf1*W0A|@Bf=moS(3O*g8g@CK#7%Mwq&AebqWu$?lr#BEYw@@DfEu`IdTt zB#n?xFmPQJikidfTP!&{F)bTMSA9+h9juY8cjeoXOE02dt^=te)SI8|e8}nz?ZG!j6RYJ@mw2CV)rtfE7v8~`Sd>^Ye zp4^2yeVT;sQtv^20|Dk_<{vE$10k#$WUfd_$T-ea_1+^aWwP5H+CH^fn3-Jq+jr@$HQ7z{@9#yu7hlq5auwMj<(@Nws=RX0LS$pt9r)y)fT9VS{Clx8xsF zZckT>@^a+bQ#cH#0FyQ_cU^8}>eOb4V?Ya~?z@eL zAQh{i9oT$$|3AEHq6HsWo^49W-4CqFkt6J4sjVhxA3NT{IaiiTO#P)x%~n%Em4ZOX zyc;JG`r%&X?>?9xYRKB$EGIUe&=#A2QoIec!eA&8x|^v3Z#VeNBFlyG)oH_BoEjA)qTA1cuOeA!x2M1@neQv;Q%K$~N7K2j zs87MRNvhl5&;`7Y5s0F82R4fsZw}yR;~OxLmMOpDkGV1xB;OM7 zXjF^@%co&zURq6r?RA#q930uzbP&tD@vjK>FP;0--OM(5KUqvGxqnrC?L( zM4l(xbwVrrUCQr(1SJ;iI0QIH&OC^ItE|0wg~)Z+&W6HZUQJRWsZz%G&OG?LcWAsw zIlqoQ4CmFdEzxeT>+lD3L2yav-Bkk8W}YBEAE%Ggdkk8%h=;v%$5T@Yf57I+INhpk z!H2ebLtQ$SKvUK(fcz3coGd&*Zx*qbEu0x;9|c(EFI+PMXbCFEV7+~ad*D^0vPlA0 zC*8Hv$j@$B6Z_Y3iJ5CZb%O?oWuTALApnG19G{(>ShYIc#rTy*zB}MFT;al)B2@NB%!}1kp$pmeA0y zg!)Y59^>2=W4BM7co9*GQPdsnea}QqRmMA>NJ)_kx-K_baSx>}3*e($90cIq-~)(N zKWDxq57>$V^91fY_d668HkJzfYEMT@`fGi2xx)KQLOWP19TB;lN$3=aDx zhRqoekRU@&qu9h>6e(wz<9~6vU+F%`xONX5g*#CxaAz8$jTdvOaD5}x%Iu|L4AmFU zk*a@?NgmTOaGCBb$ze|cw_XQp%@=h1SO%teSyc-JnYgK$#V|#*j*9~krs>^`{68jS zbtzgIy;lo>Z?nv34n0mgf?MSK6xg)ABaa1td%K{c3$stL9H)Tb^JF>Y9ZOpSVR6|p zHsa)}zy}d^ymjREIIA;jG^FvWJXYT7!`tzL&P{vuRUiX?;=S4>goC)zd6HBaB%co z_SSWxbMYItQTJD4;NM}4x2}IT{xdap*nh78JGIXLJHda=Ch-65!49Lkb^V`@@aN+H E0i*Y|MF0Q* literal 0 HcmV?d00001 diff --git a/app_python/requirements.txt b/app_python/requirements.txt new file mode 100644 index 0000000000..22ac75b399 --- /dev/null +++ b/app_python/requirements.txt @@ -0,0 +1 @@ +Flask==3.1.0 diff --git a/app_python/tests/__init__.py b/app_python/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From a091b21a29fda5bb83945157d124f9581cdd340a Mon Sep 17 00:00:00 2001 From: saddogsec Date: Wed, 4 Feb 2026 14:02:04 +0300 Subject: [PATCH 02/21] containerized devops info service --- .dockerignore | 11 +++++++++++ Dockerfile | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..ecf40d9869 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +**/__pycache__/ +*.py[cod] +*$py.class +**/.env +**/.venv +**/env/ +**/venv/ +.git/ +.gitignore +tests/ +docs/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..54cdd93979 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +FROM python:3.12-slim AS builder + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 + +WORKDIR /app + +COPY app_python/requirements.txt . + +RUN pip install --no-cache-dir --upgrade pip && \ + pip install --no-cache-dir -r requirements.txt + +FROM python:3.12-slim + +WORKDIR /app + +RUN groupadd -r appuser && useradd -r -g appuser appuser + +COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages +COPY --from=builder /usr/local/bin /usr/local/bin + +COPY app_python/app.py . + +RUN chown -R appuser:appuser /app + +USER appuser + +EXPOSE 5000 + +ENV HOST=0.0.0.0 \ + PORT=5000 + +CMD ["python", "app.py"] + From cd691bfd6afa0f3880959a261e1a79db3d277c9e Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Wed, 4 Feb 2026 12:14:54 +0000 Subject: [PATCH 03/21] add LAB02.md documentation --- app_python/docs/LAB02.md | 174 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 app_python/docs/LAB02.md diff --git a/app_python/docs/LAB02.md b/app_python/docs/LAB02.md new file mode 100644 index 0000000000..86e6ac50d7 --- /dev/null +++ b/app_python/docs/LAB02.md @@ -0,0 +1,174 @@ +# Lab 2 — Docker Containerization + +## Docker Best Practices Applied +- **Specific Base Image:** Using python:3.12-slim specifying the version ensures predictable environment +``` +FROM python:3.12-slim AS builder +... +FROM python:3.12-slim +``` +- **Layer Ordering:** Dockerfile is written with such layer, that Docker won't change layers, unless it's neccessary. So changing code in app.py, wont require to reinstall dependencies, unless the dependencies changes. +``` +# Dependencies install layer +FROM python:3.12-slim AS builder +... +COPY app_python/requirements.txt . + +RUN pip install --no-cache-dir --upgrade pip && \ + pip install --no-cache-dir -r requirements.txt + +# Running programm +FROM python:3.12-slim +... +CMD ["python", "app.py"] +``` +- **Non-Root User:** Using non-root user decreases security risks of breakout, and possibility of it. +``` +RUN groupadd -r appuser && useradd -r -g appuser appuser +... +RUN chown -R appuser:appuser /app +... +USER appuser +... + +``` +- **Copying only necessary:** Dockerfile don't copy any files, which excessive for running app.py, so image remain small in size. +``` +COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages +COPY --from=builder /usr/local/bin /usr/local/bin + +COPY app_python/app.py . +``` +## Image Information & Decisions +- **Base image:** python:3.12-slim used, to decrease the image size. +- **Image size:** final image size is 199mb, which mostly comes from basic `python:3.12-slim` image size +- **Layer structure explanation:** - If any action at some layer starts to produce different result, all layers below computed again, so current layer order first import requirements, which changes not frequently. Then creates user and uses it instead of root, this is almost-never changing layers, but requirements install frequently needs root privileges, so user creation happens after. Then it's just copying actual code and running it, this part changing almost every time, so those layers are the last +- **Optimization choices:** follow best practices, use small slim base image, copy only neccessary files, use proper layer ordering. + +## Build & Run Process +- **Complete terminal output from build process:** +``` +$ docker build -t devops-info-service . +DEPRECATED: The legacy builder is deprecated and will be removed in a future release. + Install the buildx component to build images with BuildKit: + https://docs.docker.com/go/buildx/ + +Sending build context to Docker daemon 927.7kB +Step 1/16 : FROM python:3.12-slim AS builder + ---> 87b49ee9d18d +Step 2/16 : ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 + ---> Using cache + ---> 07011a084c7f +Step 3/16 : WORKDIR /app + ---> Using cache + ---> 77152fff0ae8 +Step 4/16 : COPY app_python/requirements.txt . + ---> Using cache + ---> 55913bacbad6 +Step 5/16 : RUN pip install --no-cache-dir --upgrade pip && pip install --no-cache-dir -r requirements.txt + ---> Using cache + ---> c326bfd9e275 +Step 6/16 : FROM python:3.12-slim + ---> 87b49ee9d18d +Step 7/16 : WORKDIR /app + ---> Using cache + ---> 27090590b024 +Step 8/16 : RUN groupadd -r appuser && useradd -r -g appuser appuser + ---> Using cache + ---> c42c4931ec5a +Step 9/16 : COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages + ---> Using cache + ---> fb1db854b117 +Step 10/16 : COPY --from=builder /usr/local/bin /usr/local/bin + ---> Using cache + ---> cb02a27cc5be +Step 11/16 : COPY app_python/app.py . + ---> Using cache + ---> 137688dba132 +Step 12/16 : RUN chown -R appuser:appuser /app + ---> Using cache + ---> 11a49be0286d +Step 13/16 : USER appuser + ---> Using cache + ---> 6939ead36931 +Step 14/16 : EXPOSE 5000 + ---> Using cache + ---> 8fc6c2ddeea1 +Step 15/16 : ENV HOST=0.0.0.0 PORT=5000 + ---> Using cache + ---> ee8d4cbbdd7b +Step 16/16 : CMD ["python", "app.py"] + ---> Using cache + ---> e1e286cbcbbe +Successfully built e1e286cbcbbe +Successfully tagged devops-info-service:latest + +``` +- **Terminal output showing container running:** +``` +docker ps +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +3da1dbdf4144 devops-info-service:1.0.0 "python app.py" 4 seconds ago Up 3 seconds 5000/tcp sad_proskuriakova +``` +- **Terminal output from testing endpoints (curl/httpie):** +``` +$ curl -s http://localhost:5000/ | jq . +{ + "endpoints": [ + { + "description": "Service information", + "method": "GET", + "path": "/" + }, + { + "description": "Health check", + "method": "GET", + "path": "/health" + } + ], + "request": { + "client_ip": "172.17.0.1", + "method": "GET", + "path": "/", + "user_agent": "curl/8.18.0" + }, + "runtime": { + "current_time": "2026-02-04T12:09:53.157Z", + "timezone": "UTC", + "uptime_human": "0 hours, 0 minutes", + "uptime_seconds": 45 + }, + "service": { + "description": "DevOps course info service", + "framework": "Flask", + "name": "devops-info-service", + "version": "1.0.0" + }, + "system": { + "architecture": "x86_64", + "cpu_count": 8, + "hostname": "292ee90a8d4c", + "platform": "Linux", + "platform_version": "Linux-6.17.13-hardened1-2-hardened-x86_64-with-glibc2.41", + "python_version": "3.12.12" + } +} + +$ curl -s http://localhost:5000/health | jq . +{ + "status": "healthy", + "timestamp": "2026-02-04T12:09:58.563Z", + "uptime_seconds": 51 +} +``` +- **Docker Hub repository URL:** https://hub.docker.com/repository/docker/saddogsec/devops-info-service + +## Technical Analysis +- **Why does your Dockerfile work the way it does?** Because water is wet, sky is blue, and people who made Docker, made that it works the way it does +- **What would happen if you changed the layer order?** Depends on how. One good idea is to move user creation above requirements install, which after some tweaks make image more hardened, but introduce more complexity. Moving requirements install below the copying app file, would force to compute again requirements install layer, even if requirements havent changed. +- **What security considerations did you implement?** Use non-root user for running the app. +- **How does .dockerignore improve your build?** It ensures that unneccessary files wont be copied into image, reducing image size. + +## Challenges & Solutions +- **Issues encountered during implementation. How you debugged and resolved them** No issues were encountered during implementation. +- **What you learned from the process** It's not my first time doing this, so actually nothing new. From fd0249d6831d6dfcafc4f5b27ebfb782884d2a85 Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Wed, 4 Feb 2026 12:27:13 +0000 Subject: [PATCH 04/21] Add docker section to README.md --- app_python/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app_python/README.md b/app_python/README.md index bb8575ca03..2223f678ed 100644 --- a/app_python/README.md +++ b/app_python/README.md @@ -37,3 +37,16 @@ PORT=8080 python app.py `DEBUG` - Enable Flask debug logging (False by default) +## Docker +- **Build image:** +``` +docker build -t . +``` +- **Get image from dockerhub:** +``` +docker pull saddogsec/devops-info-service:1.0.0 +``` +- **Run the image** +``` +docker run -p 5000:5000 saddogsec/devops-info-service:1.0.0 +``` From 83bdc109173d3c1569c796993e570556db344b0c Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 18:27:02 +0000 Subject: [PATCH 05/21] Add pytest --- app_python/tests/pytest.py | 40 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 app_python/tests/pytest.py diff --git a/app_python/tests/pytest.py b/app_python/tests/pytest.py new file mode 100644 index 0000000000..38360f95e7 --- /dev/null +++ b/app_python/tests/pytest.py @@ -0,0 +1,40 @@ +import pytest +import json +from datetime import datetime, timezone +from unittest.mock import patch, MagicMock +from app import create_app, iso_utc_z, get_uptime + +@pytest.fixture +def client(): + app = create_app() + app.config['TESTING'] = True + with app.test_client() as client: + yield client + +def test_index_endpoint(client): + response = client.get('/') + assert response.status_code == 200 + data = json.loads(response.data) + assert data['service']['name'] == 'devops-info-service' + assert 'system' in data + assert 'runtime' in data + +def test_health_endpoint(client): + response = client.get('/health') + assert response.status_code == 200 + data = json.loads(response.data) + assert data['status'] == 'healthy' + assert 'uptime_seconds' in data + +def test_404_not_found(client): + response = client.get('/nonexistent') + assert response.status_code == 404 + data = json.loads(response.data) + assert data['error'] == 'Not Found' + +def test_iso_utc_z(): + from app import iso_utc_z + dt = datetime(2023, 1, 1, 12, 0, 0, tzinfo=timezone.utc) + result = iso_utc_z(dt) + assert result.endswith('Z') + assert 'T' in result From d5ab0420eb90de776aebde930eff2d345c1054aa Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 18:47:43 +0000 Subject: [PATCH 06/21] Create python-ci.yml --- .github/workflows/python-ci.yml | 52 +++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .github/workflows/python-ci.yml diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml new file mode 100644 index 0000000000..10fd77dd97 --- /dev/null +++ b/.github/workflows/python-ci.yml @@ -0,0 +1,52 @@ +name: Python CI + +on: [push] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.13 + uses: actions/setup-python@v4 + with: + python-version: "3.13" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install flake8 pytest + - name: Lint with flake8 + run: | + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + flake8 . --count --exit-zero --max-complexity=10 --statistics + - name: Test with pytest + run: pytest app_python/tests/pytest.py -v + + docker: + needs: test + # if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Extract version + id: version + run: | + VERSION=$(grep '^APP_VERSION' app_python/app.py | cut -d'"' -f2) + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ secrets.DOCKERHUB_USERNAME }}/devops-info-service:${{ steps.version.outputs.version }},${{ secrets.DOCKERHUB_USERNAME }}/devops-info-service:latest From 6316b0b5aee62c9a3da27504b327342a5401893b Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 18:49:38 +0000 Subject: [PATCH 07/21] Add missing requirements to python-ci.yml --- .github/workflows/python-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 10fd77dd97..80c478cd23 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -14,7 +14,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install flake8 pytest + pip install flake8 pytest flask - name: Lint with flake8 run: | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics From a99aeaadba2ad2402050beb9177860aa11329e07 Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:17:59 +0000 Subject: [PATCH 08/21] Add vulnerable dependencies scan to python-ci.yml --- .github/workflows/python-ci.yml | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 80c478cd23..4ced3b6905 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -22,8 +22,37 @@ jobs: - name: Test with pytest run: pytest app_python/tests/pytest.py -v +security: + name: Security Scan + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.13' + cache: 'pip' + cache-dependency-path: 'app_python/requirements.txt' + + - name: Install dependencies + run: | + cd app_python + pip install --upgrade pip + pip install -r requirements.txt + + - name: Run Snyk to check for vulnerabilities + uses: snyk/actions/python@master + continue-on-error: true + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + with: + args: --severity-threshold=high --file=app_python/requirements.txt + docker: - needs: test + needs: [test, security] # if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: From 67d2a8f7f6017b6252bad99cedcc7307cc00bb4a Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:20:18 +0000 Subject: [PATCH 09/21] Update python-ci.yml --- .github/workflows/python-ci.yml | 56 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 4ced3b6905..80902321ed 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -22,34 +22,34 @@ jobs: - name: Test with pytest run: pytest app_python/tests/pytest.py -v -security: - name: Security Scan - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.13' - cache: 'pip' - cache-dependency-path: 'app_python/requirements.txt' - - - name: Install dependencies - run: | - cd app_python - pip install --upgrade pip - pip install -r requirements.txt - - - name: Run Snyk to check for vulnerabilities - uses: snyk/actions/python@master - continue-on-error: true - env: - SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} - with: - args: --severity-threshold=high --file=app_python/requirements.txt + security: + name: Security Scan + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.13' + cache: 'pip' + cache-dependency-path: 'app_python/requirements.txt' + + - name: Install dependencies + run: | + cd app_python + pip install --upgrade pip + pip install -r requirements.txt + + - name: Run Snyk to check for vulnerabilities + uses: snyk/actions/python@master + continue-on-error: true + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + with: + args: --severity-threshold=high --file=app_python/requirements.txt docker: needs: [test, security] From cbe7f9edf0f90a09b6ceafff1855873daec586d9 Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:22:41 +0000 Subject: [PATCH 10/21] Update required dependencies for snyk in python-ci.yml --- .github/workflows/python-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 80902321ed..ee8851ee4a 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -42,6 +42,7 @@ jobs: cd app_python pip install --upgrade pip pip install -r requirements.txt + pip install flask - name: Run Snyk to check for vulnerabilities uses: snyk/actions/python@master From 9bc47719362e93a994e930780a05fe112c010d87 Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:33:49 +0000 Subject: [PATCH 11/21] Update python-ci.yml --- .github/workflows/python-ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index ee8851ee4a..6a1017c4c1 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -42,7 +42,6 @@ jobs: cd app_python pip install --upgrade pip pip install -r requirements.txt - pip install flask - name: Run Snyk to check for vulnerabilities uses: snyk/actions/python@master @@ -50,7 +49,7 @@ jobs: env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: - args: --severity-threshold=high --file=app_python/requirements.txt + args: test --severity-threshold=high --file=requirements.txt --package-manager=pip docker: needs: [test, security] From e918b2d5190e8b0533834649ee0ed55be5e1698c Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:41:33 +0000 Subject: [PATCH 12/21] Update python-ci.yml --- .github/workflows/python-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 6a1017c4c1..0c41edff0b 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -44,6 +44,7 @@ jobs: pip install -r requirements.txt - name: Run Snyk to check for vulnerabilities + timeout-minutes: 2 uses: snyk/actions/python@master continue-on-error: true env: @@ -53,7 +54,7 @@ jobs: docker: needs: [test, security] - # if: github.ref == 'refs/heads/main' + if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From b9a4b8ad9cb9c911e582ac0b2f8b8f2dd29cb70b Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:50:18 +0000 Subject: [PATCH 13/21] Update python-ci.yml --- .github/workflows/python-ci.yml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 0c41edff0b..b22d2e0b97 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -25,7 +25,10 @@ jobs: security: name: Security Scan runs-on: ubuntu-latest - + defaults: + run: + working-directory: app_python + steps: - name: Checkout code uses: actions/checkout@v4 @@ -35,22 +38,20 @@ jobs: with: python-version: '3.13' cache: 'pip' - cache-dependency-path: 'app_python/requirements.txt' + cache-dependency-path: 'requirements.txt' - name: Install dependencies run: | - cd app_python pip install --upgrade pip pip install -r requirements.txt - + + - name: Set up Snyk + uses: snyk/actions/setup@master + - name: Run Snyk to check for vulnerabilities - timeout-minutes: 2 - uses: snyk/actions/python@master - continue-on-error: true env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} - with: - args: test --severity-threshold=high --file=requirements.txt --package-manager=pip + run: snyk test --package-manager=pip --file=requirements.txt --severity-threshold=high docker: needs: [test, security] From 8408a9ddde32400bd3f561dc06c1ef5b577bde83 Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:51:34 +0000 Subject: [PATCH 14/21] Update python-ci.yml --- .github/workflows/python-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index b22d2e0b97..f70821c0dd 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -38,7 +38,7 @@ jobs: with: python-version: '3.13' cache: 'pip' - cache-dependency-path: 'requirements.txt' + cache-dependency-path: 'app_python/requirements.txt' - name: Install dependencies run: | From fe3a206b5b1e26eadf7198c67b480292f9164970 Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:58:00 +0000 Subject: [PATCH 15/21] Add requirements-dev.txt --- app_python/requirements-dev.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 app_python/requirements-dev.txt diff --git a/app_python/requirements-dev.txt b/app_python/requirements-dev.txt new file mode 100644 index 0000000000..62c1591451 --- /dev/null +++ b/app_python/requirements-dev.txt @@ -0,0 +1,3 @@ +Flask==3.1.0 +pytest==8.3.4 +flake8=7.3.0 From 6e78109ba7a5af4315354fb82890eccafe4937ba Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 19:59:46 +0000 Subject: [PATCH 16/21] Update python-ci.yml --- .github/workflows/python-ci.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index f70821c0dd..539d97cd40 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -7,20 +7,32 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: Set up Python 3.13 uses: actions/setup-python@v4 with: python-version: "3.13" + cache: 'pip' + cache-dependency-path: | + app_python/requirements.txt + app_python/requirements-dev.txt + - name: Install dependencies + working-directory: app_python run: | python -m pip install --upgrade pip - pip install flake8 pytest flask + pip install -r requirements-dev.txt + - name: Lint with flake8 + working-directory: app_python run: | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics flake8 . --count --exit-zero --max-complexity=10 --statistics + - name: Test with pytest - run: pytest app_python/tests/pytest.py -v + working-directory: app_python + run: pytest tests/pytest.py -v + security: name: Security Scan From 676109ea446299de21845651f0244c945fa6025a Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:00:44 +0000 Subject: [PATCH 17/21] Update requirements-dev.txt --- app_python/requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app_python/requirements-dev.txt b/app_python/requirements-dev.txt index 62c1591451..86009df6cc 100644 --- a/app_python/requirements-dev.txt +++ b/app_python/requirements-dev.txt @@ -1,3 +1,3 @@ Flask==3.1.0 pytest==8.3.4 -flake8=7.3.0 +flake8==7.3.0 From ca31ae79fcfff3c0bf9d138ac638ae69fd6f8f0f Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:14:07 +0000 Subject: [PATCH 18/21] Update python-ci.yml --- .github/workflows/python-ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 539d97cd40..9a4c7dfb87 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -1,6 +1,12 @@ name: Python CI -on: [push] +on: + push: + branches: [master, main, lab03] + paths: ['app_python/**', '.github/workflows/python-ci.yml'] + pull_request: + branches: [master, main] + paths: ['app_python/**', '.github/workflows/python-ci.yml'] jobs: test: From 49cf97b77ada47e815488c2c76233811a6caf715 Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:21:27 +0000 Subject: [PATCH 19/21] add ci badge to README.md --- app_python/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app_python/README.md b/app_python/README.md index 2223f678ed..e04efee564 100644 --- a/app_python/README.md +++ b/app_python/README.md @@ -1,5 +1,5 @@ # DevOps Info Service - +[![Python CI](https://github.com/saddogsec/DevOps-Core-Course/actions/workflows/python-ci.yml/badge.svg)](...) ## Overview This service reports: - Service metadata (name, version, framework) From 9f02b7cb399ba6bb2e4ec0248cfdfc9b5bab2f2e Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:36:04 +0000 Subject: [PATCH 20/21] Create LAB03.md --- app_python/docs/LAB03.md | 184 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 app_python/docs/LAB03.md diff --git a/app_python/docs/LAB03.md b/app_python/docs/LAB03.md new file mode 100644 index 0000000000..9b913b13c7 --- /dev/null +++ b/app_python/docs/LAB03.md @@ -0,0 +1,184 @@ +# Lab 03 — Continuous Integration & Automation + +## 1. Testing Strategy & Framework + +### Framework Selection: pytest + +The testing framework **pytest** was chosen over alternatives (unittest, nose) for the following reasons: + +- **Modern Pythonic syntax**: Uses simple `assert` statements instead of verbose `assertEqual()` methods +- **Powerful fixtures**: Clean test setup/teardown and dependency injection +- **FastAPI integration**: Works seamlessly with FastAPI's TestClient without server startup +- **Plugin ecosystem**: Excellent support for coverage, parallel execution, and reporting +- **Industry standard**: Most widely used in modern Python projects + +### Test Coverage + +4 tests were made to test both existing endpoints and error handling at invalid endpoint covering most of service functionality + +### Test Execution + +```bash +$ pytest app_python/tests/pytest.py -v +=============================================================================================== test session starts ================================================================================================ +... +app_python/tests/pytest.py::test_index_endpoint PASSED [ 25%] +app_python/tests/pytest.py::test_health_endpoint PASSED [ 50%] +app_python/tests/pytest.py::test_404_not_found PASSED [ 75%] +app_python/tests/pytest.py::test_iso_utc_z PASSED [100%] + +================================================================================================ 4 passed in 0.10s ================================================================================================= +``` + +--- + +## 2. GitHub Actions CI Pipeline + +### Workflow File Location + +`.github/workflows/python-ci.yml` + +### Workflow Architecture + +**3 Jobs with smart dependencies:** + +1. **Test and Lint** (ubuntu-latest) + - Python 3.13 setup with pip caching + - Install dependencies + flake8 + pytest + - Run flake8 + - Run pytest + +2. **Security Scan** (runs in parallel) + - Snyk vulnerability scanning + - Check only for HIGH/CRITICAL CVEs + - Report if any dependencies failed + +3. **Docker Build and Push** (depends on both previous jobs) + - Authenticate to Docker Hub + - Build image with caching + - Tag and push + +### Trigger Configuration + +```yaml +on: + push: + branches: [master, main, lab03] + paths: ['app_python/**', '.github/workflows/python-ci.yml'] + pull_request: + branches: [master, main] + paths: ['app_python/**', '.github/workflows/python-ci.yml'] +``` + +**Rationale**: Path filtering prevents unnecessary runs on documentation changes. + +### Docker Image Versioning + +**Strategy**: SemVer versioning + +**Why SemVer over CalVer?** +- Carries more information about changes than CalVer +- Am assuming rare updates for this software + +**Tags per image**: +- `latest` - Points to most recent build +- `1.0.0` - SemVer tag + +--- + +## 3. CI Best Practices & Optimizations + +### Practice 1: Status Badge + +Added to `app_python/README.md`: + +[![Python CI](https://github.com/saddogsec/DevOps-Core-Course/actions/workflows/python-ci.yml/badge.svg)](...) + +Provides real-time visibility of pipeline status (passing/failing). + +### Practice 2: Dependency Caching + +Caching and requirements-dev.txt used to decrease pipeline execution time + +```yaml +cache: 'pip' +cache-dependency-path: | + app_python/requirements.txt + app_python/requirements-dev.txt +``` + +### Practice 3: Security Scanning with Snyk + +Dedicated job scans `requirements.txt` for vulnerabilities: + +```yaml +- name: Run Snyk to check for vulnerabilities + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + run: snyk test --package-manager=pip --file=requirements.txt --severity-threshold=high +``` + +### Practice 4: Parallel Job Execution + +Test and security jobs run in parallel instead of sequentially considerably decreasing pipeline execution time. + +### Practice 5: Job Dependencies with Fail-Fast + +```yaml +docker: + needs: [test, security] + if: github.ref == 'refs/heads/master' +``` + +### Practice 6: Secure secret management +Github secrets is used instead of .env or other vulnerable ways to store SNYK_TOKEN and DOCKER_TOKEN +```yaml +env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} +... +with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} +``` +--- + +## 4. Technical Analysis + +### Why This Pipeline Works +It uses standart approach, with multiple parallel tests which all needs to pass before creating deployment artifact +``` +Push → Tests pass? and Security scan completes? → Docker build & push + (required) (required) (only on relevant branches) +``` + +### Layer Caching Impact + +Docker layers are cached by GitHub Actions. On subsequent runs: +- Base image: reused +- Dependencies: reused (if requirements.txt unchanged) +- Application code: rebuilt (changed) +- **Result**: faster builds + +## 5. Key Decisions & Rationale + +### Decision 1: CalVer vs SemVer Versioning + +**Chosen**: SemVer versioning + +**Why SemVer over CalVer?** +- Easy to identify whenever something important changed + +--- + +### Decision 2: Snyk Severity Threshold + +**Chosen**: HIGH (fail only on HIGH/CRITICAL) + +**Rationale**: +- MEDIUM/LOW issues are hard to exploit in this software, so they seem irrelevant +- Considering Low issues would extremely limit amount of available libraries to use + +--- + +## 6. Challenges & Solutions +No challenges were present during the lab From 2907974490460aeda1c887279ab4a1be26073329 Mon Sep 17 00:00:00 2001 From: Marsel <143814762+saddogsec@users.noreply.github.com> Date: Thu, 12 Feb 2026 20:38:27 +0000 Subject: [PATCH 21/21] Update python-ci.yml --- .github/workflows/python-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 9a4c7dfb87..b675f16f77 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -73,7 +73,7 @@ jobs: docker: needs: [test, security] - if: github.ref == 'refs/heads/main' + # if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4