From bc26e6c96d31e2327d953e12dd867c8960e08434 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Sun, 25 Jan 2026 19:21:18 +0300 Subject: [PATCH 01/40] feat: implement lab01 devops info service --- app_python/.gitignore | 12 + app_python/README.md | 41 +++ app_python/app.py | 162 +++++++++ app_python/docs/LAB01.md | 341 ++++++++++++++++++ .../docs/screenshots/01-main-endpoint.png | Bin 0 -> 45712 bytes .../docs/screenshots/02-health-check.png | Bin 0 -> 11296 bytes .../docs/screenshots/03-formatted-output.png | Bin 0 -> 55725 bytes app_python/requirements.txt | 2 + app_python/tests/__init__.py | 0 9 files changed, 558 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.png create mode 100644 app_python/docs/screenshots/02-health-check.png create mode 100644 app_python/docs/screenshots/03-formatted-output.png 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..4de420a8f7 --- /dev/null +++ b/app_python/.gitignore @@ -0,0 +1,12 @@ +# Python +__pycache__/ +*.py[cod] +venv/ +*.log + +# IDE +.vscode/ +.idea/ + +# OS +.DS_Store \ No newline at end of file diff --git a/app_python/README.md b/app_python/README.md new file mode 100644 index 0000000000..32d32ac023 --- /dev/null +++ b/app_python/README.md @@ -0,0 +1,41 @@ +# devops-info-service + +## Overview +`devops-info-service` is a lightweight HTTP service built with **FastAPI** that returns comprehensive runtime and system information. It exposes: +- service metadata (name, version, description, framework), +- system details (hostname, OS/platform, architecture, CPU count, Python version), +- runtime data (uptime, current UTC time), +- request details (client IP, user-agent, method, path), +- a list of available endpoints. + +## Prerequisites +- **Python:** 3.10+ (recommended 3.11+) +- **Dependencies:** listed in `requirements.txt` + +## Installation + +``` +python -m venv venv +source venv/bin/activate +pip install -r requirements.txt +``` + +## Running the Application +``` +python app.py +# Or with custom config +PORT=8080 python app.py +``` + +## API Endpoints +- `GET /` - Service and system information +- `GET /health` - Health check + +## Configuration + +The application is configured using environment variables. + +| Variable | Default | Description | Example | +|---------|---------|-------------|---------| +| `HOST` | `127.0.0.1` | Host interface to bind the server to | `0.0.0.0` | +| `PORT` | `8000` | Port the server listens on | `8080` | \ No newline at end of file diff --git a/app_python/app.py b/app_python/app.py new file mode 100644 index 0000000000..a1e16fe273 --- /dev/null +++ b/app_python/app.py @@ -0,0 +1,162 @@ +""" +DevOps Info Service +Main application module +""" +import logging +import os +import platform +import socket +from datetime import datetime, timezone + +import uvicorn +from fastapi import FastAPI, Request, status +from fastapi.responses import JSONResponse +from starlette.exceptions import HTTPException + +app = FastAPI() + +# Configuration +HOST = os.getenv("HOST", "0.0.0.0") +PORT = int(os.getenv("PORT", 5000)) +DEBUG = os.getenv("DEBUG", "False").lower() == "true" + +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger(__name__) + +# Application start time +start_time = datetime.now() + + +def get_service_info(): + """Get information about service.""" + logger.debug('Getting info about the service.') + return { + "name": "devops-info-service", + "version": "1.0.0", + "description": "DevOps course info service", + "framework": "FastAPI", + } + + +def get_system_info(): + """Get information about system.""" + logger.debug('Getting info about the system.') + return { + "hostname": socket.gethostname(), + "platform": platform.system(), + "platformVersion": platform.version(), + "architecture": platform.machine(), + "cpu_count": os.cpu_count(), + "python_version": platform.python_version(), + } + + +def get_uptime(): + """Get uptime.""" + logger.debug('Getting uptime.') + delta = datetime.now() - start_time + seconds = int(delta.total_seconds()) + hours = seconds // 3600 + minutes = (seconds % 3600) // 60 + return {"seconds": seconds, "human": f"{hours} hours, {minutes} minutes"} + + +def get_runtime_info(): + """Get information about runtime.""" + logger.debug('Getting runtime info.') + uptime = get_uptime() + uptime_seconds, uptime_human = uptime["seconds"], uptime["human"] + current_time = datetime.now(timezone.utc) + + return { + "uptime_seconds": uptime_seconds, + "uptime_human": uptime_human, + "current_time": current_time, + "timezone": "UTC", + } + + +def get_request_info(request: Request): + """Get information about request.""" + logger.debug('Getting info about request.') + return { + "client_ip": request.client.host, + "user_agent": request.headers.get("user-agent"), + "method": request.method, + "path": request.url.path, + } + + +def get_endpoints(): + """Get all existing ednpoints.""" + logger.debug('Getting list of all endpoints.') + return [ + {"path": "/", "method": "GET", "description": "Service information"}, + {"path": "/health", "method": "GET", "description": "Health check"}, + ] + + +@app.get("/", status_code=status.HTTP_200_OK) +async def root(request: Request): + """Main endpoint - service and system information.""" + logger.debug(f'Request: {request.method} {request.url.path}') + return { + "service": get_service_info(), + "system": get_system_info(), + "runtime": get_runtime_info(), + "request": get_request_info(request), + "endpoints": get_endpoints(), + } + + +@app.get("/health", status_code=status.HTTP_200_OK) +async def health(request: Request): + """Endpoint to check health.""" + logger.debug(f'Request: {request.method} {request.url.path}') + return { + "status": "healthy", + "timestamp": datetime.now(timezone.utc), + "uptime_seconds": get_uptime()["seconds"], + } + + +@app.exception_handler(HTTPException) +async def http_exception_handler(request: Request, exc: HTTPException): + """Exception 404 (Not found) that endpoint does not exists.""" + if exc.status_code == 404: + return JSONResponse( + status_code=404, + content={ + "error": "Not Found", + "message": "Endpoint does not exist", + }, + ) + return JSONResponse( + status_code=exc.status_code, + content={ + "error": "HTTP Error", + "message": exc.detail if exc.detail else "Request failed", + }, + ) + + +@app.exception_handler(Exception) +async def unhandled_exception_handler(request: Request, exc: Exception): + """Exception 500 (Internal Server Error) - For any unhandled errors.""" + return JSONResponse( + status_code=500, + content={ + "error": "Internal Server Error", + "message": "An unexpected error occurred", + }, + ) + + +if __name__ == "__main__": + """The entry point.""" + logger.info('Application starting...') + + uvicorn.run("app:app", host=HOST, port=PORT, reload=True) diff --git a/app_python/docs/LAB01.md b/app_python/docs/LAB01.md new file mode 100644 index 0000000000..3c073f4777 --- /dev/null +++ b/app_python/docs/LAB01.md @@ -0,0 +1,341 @@ +# 1. Framework selection. +## Choice +I have chose FastAPI because I have had an experience with it and have no experience with other frameworks. + +## Comparison with Alternatives + +| Criteria | FastAPI (chosen) | Flask | Django (DRF) | +|---------|-----------------|-------|--------------| +| Primary use | APIs / microservices | Lightweight web apps & APIs | Full-stack apps & large APIs | +| Performance model | ASGI (async-ready) | WSGI (sync by default) | WSGI/ASGI (heavier stack) | +| Built-in API docs | Yes (Swagger/OpenAPI) | No (manual/add-ons) | Yes (via DRF) | +| Validation / typing | Strong (type hints + Pydantic) | Manual or extensions | Strong (serializers) | +| Boilerplate | Low | Very low | Higher | +| Learning curve | Low–medium | Low | Medium–high | +| Best fit for this lab | Excellent | Good | Overkill | + +--- + +# 2. Best Practices Applied +## Clean Code Organization + +### 1) Clear Function Names +The code uses descriptive, intention-revealing function names that clearly communicate what each block returns: + +```python +def get_service_info(): + """Get information about service.""" + ... + +def get_system_info(): + """Get information about system.""" + ... + +def get_runtime_info(): + """Get information about runtime.""" + ... + +def get_request_info(request: Request): + """Get information about request.""" + ... +``` +**Why it matters**: Clear naming improves readability, reduces the need for extra comments, and makes the code easier to maintain and extend. + +### 2) Proper imports grouping +Imports are organized by category (standard library first, then third-party libraries), which is the common Python convention: +```python +import logging +import os +import platform +import socket +from datetime import datetime, timezone + +import uvicorn +from fastapi import FastAPI, Request, status +from fastapi.responses import JSONResponse +from starlette.exceptions import HTTPException +``` +**Why it matters**: Grouped imports make dependencies easier to understand at a glance, help keep the file structured, and align with typical linting rules. + +### 3) Comments only where needed +Instead of excessive inline comments, the code relies on clear names and short docstrings: +```python +""" +DevOps Info Service +Main application module +""" + +def get_uptime(): + """Get uptime.""" + ... +``` +**Why it matters**: Too many comments can become outdated. Minimal documentation plus clean naming keeps the codebase readable and accurate. + +### 4) Follow PEP 8 +The implementation follows common PEP 8 practices: +- consistent indentation and spacing, +- snake_case for variables and function names, +- configuration/constants placed near the top of the module (HOST, PORT, DEBUG), +- readable multi-line formatting for long calls: +```python +""" +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" +) +``` +**Why it matters**: PEP 8 improves consistency, supports teamwork, and makes the code compatible with linters/formatters such as `flake8`, `ruff`, and `black`. + +## Error Handling +The service implements centralized error handling using FastAPI/Starlette exception handlers. This ensures that errors are returned in a consistent JSON format and that clients receive meaningful messages instead of raw stack traces. + +### HTTP errors (e.g., 404 Not Found) +A dedicated handler processes HTTP-related exceptions and customizes the response for missing endpoints. + +```python +from starlette.exceptions import HTTPException + +@app.exception_handler(HTTPException) +async def http_exception_handler(request: Request, exc: HTTPException): + if exc.status_code == 404: + return JSONResponse( + status_code=404, + content={ + "error": "Not Found", + "message": "Endpoint does not exist", + }, + ) + + return JSONResponse( + status_code=exc.status_code, + content={ + "error": "HTTP Error", + "message": exc.detail if exc.detail else "Request failed", + }, + ) +``` +**Why it matters**: +- Provides a clear and user-friendly message for invalid routes. +- Keeps error responses consistent across the API. +- Avoids exposing internal implementation details to the client. + +### Unhandled exceptions (500 Internal Server Error) +A global handler catches any unexpected exceptions and returns a safe, standardized response. + +```python +@app.exception_handler(Exception) +async def unhandled_exception_handler(request: Request, exc: Exception): + return JSONResponse( + status_code=500, + content={ + "error": "Internal Server Error", + "message": "An unexpected error occurred", + }, + ) +``` +**Why it matters**: +- Prevents server crashes from unhandled errors. +- Ensures clients always receive valid JSON (important for automation/scripts). +- Helps keep production behavior predictable while preserving the option to log the exception internally. + +## 3. Logging +The service includes basic logging configuration to improve observability and simplify debugging. Logs are useful both during development (troubleshooting requests and behavior) and in production (monitoring, incident investigation). + +### Logging setup +A global logging configuration is defined at startup with a consistent log format: +```python +import logging + +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" +) +logger = logging.getLogger(__name__) +``` +**Why it matters**: +- Provides timestamps and log levels for easier troubleshooting. +- A consistent format makes logs easier to parse in log aggregators (e.g., ELK, Loki). +- Centralized config avoids inconsistent logging across modules. + +### Startup logging +The application logs an informational message when it starts: +```python +if __name__ == "__main__": + logger.info("Application starting...") + uvicorn.run("app:app", host=HOST, port=PORT, reload=True) +``` +**Why it matters**: +- Confirms that the service started successfully. +- Helps identify restarts and uptime issues. + +### Request logging (debug level) +Each endpoint logs basic request information (method and path): +```python +@app.get("/", status_code=status.HTTP_200_OK) +async def root(request: Request): + logger.debug(f"Request: {request.method} {request.url.path}") + ... +``` +**Why it matters**: +- Helps trace API usage during development. +- Useful for debugging routing problems and unexpected client behavior. + +## 4. Dependencies (requirements.txt) +The project keeps dependencies minimal and focused on what is required to run a FastAPI service in production. +### requirements.txt +``` +fastapi>=0.110 +uvicorn[standard]>=0.27 +``` +**Why it matters**: +- Faster builds & simpler setup: fewer packages mean faster installation and fewer moving parts. +- Lower risk of conflicts: minimal dependencies reduce version incompatibilities and “dependency hell”. +- Better security posture: fewer third-party libraries reduce the overall attack surface. +- More predictable deployments: only installing what the service truly needs improves reproducibility across environments (local, CI, Docker, VM). + +## 5. Git Ignore (.gitignore) + +A `.gitignore` file is used to prevent committing temporary, machine-specific, or sensitive files into the repository. + +### Recommended `.gitignore` +```gitignore +# Python +__pycache__/ +*.py[cod] +venv/ +*.log + +# IDE +.vscode/ +.idea/ + +# OS +.DS_Store +``` +**Why it matters**: +- Keeps the repository clean: avoids committing generated files (`__pycache__`, build outputs, logs). +- Improves portability: prevents OS- and IDE-specific files from polluting the project and causing noisy diffs. +- Protects secrets: ensures configuration files like `.env` (which may contain API keys or credentials) are not accidentally pushed. +- Reduces merge conflicts: fewer irrelevant files tracked by Git means fewer conflicts between contributors. + +# 3. API Documentation +The service exposes two endpoints: the main information endpoint and a health check endpoint. +## Request/response examples +### GET `/` — Service and System Information +**Description:** +Returns comprehensive metadata about the service, system, runtime, request details, and available endpoints. +**Request example:** +```bash +curl -i http://127.0.0.1:5000/ +``` +**Response example (200 OK):** +```json +{ + "service": { + "name": "devops-info-service", + "version": "1.0.0", + "description": "DevOps course info service", + "framework": "Flask" + }, + "system": { + "hostname": "my-laptop", + "platform": "Linux", + "platform_version": "Ubuntu 24.04", + "architecture": "x86_64", + "cpu_count": 8, + "python_version": "3.13.1" + }, + "runtime": { + "uptime_seconds": 3600, + "uptime_human": "1 hour, 0 minutes", + "current_time": "2026-01-07T14:30:00.000Z", + "timezone": "UTC" + }, + "request": { + "client_ip": "127.0.0.1", + "user_agent": "curl/7.81.0", + "method": "GET", + "path": "/" + }, + "endpoints": [ + {"path": "/", "method": "GET", "description": "Service information"}, + {"path": "/health", "method": "GET", "description": "Health check"} + ] +} +``` +### GET /health — Health Check +**Description:** +Returns a simple status response to confirm the service is running.**Request example:** +```bash +curl -i http://127.0.0.1:5000/health +``` +**Response example (200 OK):** +```json +{ + "status": "healthy", + "timestamp": "2024-01-15T14:30:00.000Z", + "uptime_seconds": 3600 +} +``` +## Testing commands +### Basic tests +```bash +curl http://127.0.0.1:5000/ +curl http://127.0.0.1:5000/health +``` +### Test 404 handling (unknown endpoint) +```bash +curl -i http://127.0.0.1:5000/does-not-exist +``` +Expected response (404): +```json +{ + "error": "Not Found", + "message": "Endpoint does not exist" +} +``` + +# 4. Testing Evidence +Check screenshots. + +# 5. Challenges & Solutions +I have no problems in this lab. + +# GitHub Community +**Why Stars Matter:** + +**Discovery & Bookmarking:** +- Stars help you bookmark interesting projects for later reference +- Star count indicates project popularity and community trust +- Starred repos appear in your GitHub profile, showing your interests + +**Open Source Signal:** +- Stars encourage maintainers (shows appreciation) +- High star count attracts more contributors +- Helps projects gain visibility in GitHub search and recommendations + +**Professional Context:** +- Shows you follow best practices and quality projects +- Indicates awareness of industry tools and trends + +**Why Following Matters:** + +**Networking:** +- See what other developers are working on +- Discover new projects through their activity +- Build professional connections beyond the classroom + +**Learning:** +- Learn from others' code and commits +- See how experienced developers solve problems +- Get inspiration for your own projects + +**Collaboration:** +- Stay updated on classmates' work +- Easier to find team members for future projects +- Build a supportive learning community + +**Career Growth:** +- Follow thought leaders in your technology stack +- See trending projects in real-time +- Build visibility in the developer community \ No newline at end of file diff --git a/app_python/docs/screenshots/01-main-endpoint.png b/app_python/docs/screenshots/01-main-endpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..2b5ad4b17fe1c5d8a4dfb28c9437474f4aff5f03 GIT binary patch literal 45712 zcmbTd2Q-{r*9I&hdP&rXAW@?WL3E;bQNv(#2~na(7li1&MUNJ3l;~YV9lf_P5@d8S z3`YHDCeQo6-?!dx{r_73tYtCxeeQFgv(GtuUwdDd2yIOz62b?BSXfvjD$4RYSXelM zSXj4*@o`aCkjzL8)UR7^I!Z6FK%)=0P+xHDWHn^5uxjFnE-mh$z7x188@XX&k@lc} zZuL8VwZ_7#WmS=v)q8KYdqv`I1u>n!xRHO)uB}Q`6gFeR!649IKbQ!3y~X))CX}1A z_xEUBk`6&DkJIh;!a5pT$;yzQ~2VQRgHSc0$UNwtvYvLxx-lrr5zlX#Q zTqPSgxbW{B8%0|e%iPaD>`EH+7{VlnC&0$WhL18Y>H{JPrkzXQH~s>!_B*5rtjWf7 z)pf?4{!U}dI#)~ymq!58aBf5+23v*QTM3TEA1Tz{X2N=k?skQQ#TbP5$K{vYTp_B$Xq- zare{2v8&~=6uygEzHe@e7nRU+9^_W;^&4;GM%u>a=D=`fR#tLpDF@OmaDQwN7I+QI z^u|m+I+6%a@c1=tAfoD8AK6lMA%=`SI3pE5b@fLtwpZI4J)1}r@OepM~&%T8ow zCkGT^3bi4(yhbhXZV`^4yF*HvnUBhKxAYkvydHQ_Z@a>G{flo1dPWy0#~|s$;_SCZ zH_|4HJT8&u2@end#><-^F8lf>&+ivSZv4%m^mTaKZ=tFhH{+=f(TwN$i~`-c zo;>o`M}gO4@YCxRXi`cF74mZx@_~4xA!BOp`y;ybv`!dy?McaA#pAO-(kg>=0UPx2 z4>Qhpk#k^p3*&hYydxLsiBtsy7)hOjSdk50VUX~ZM_MZv?K)(){Pl9$5lid+u_1O< z-b-3T=YVa~Al_PT^a3o)!$va>9Xd}O5(ll<`EE8k{fa(BlliS;!<}#TI#U`uul77O z9h`lpGS$H$(r~5gPXyL}Cw74iJhT!Jo%QYzJb2ahOlP83`;Mu`2V#w}DVuZWW9YUG zu54rS#D{E6)W_PEo(uvn-C6G7y_TJl@isqTgVf0_GOFSYUpf7p`dk{>!0i2J)(-v>a2X|i<_Nb+(o$dWg*8LOm?itr~SB+wMPw`teB1S1D2QOAmrKT#^5mkZh*%af=636SGv$KUD>c;}F z_X=*t5(Y%t^JhQ*0^h8QfE{Av)(uC#0h3R!b{*EmslQKFrF334%ne*z9{`_?{magJ z{&<4dQ-SAN@Y%+WnRVlFs$bR4iO2Jbw$Kgim>K381dLL@Vmv2M5#6Xyy-NbF zcYJK&|0lO_I}m#Iz_dZOvFmF}JCc39r?_=^XWj88&G=wS04Yk`Cjr;~@QyPP@SIjU6Z6@{X@uE16BzAUx-@3I_~i^e zJwU_|0XeUwO}j}`N!&fdK!o9#5Kbw>2L&>y7;y`Dz|McxZov-XKMM1UC3ry`9I)pU zA??AxR^G8)zWc2u_o6vhP`3ck=#*i@E01^Yx{UAO{TQD5Tpnuw`NLyF8fUO6#NrQ& zb5o@axdKZ}pxlgp=ch&9T$MeH$&ATfxPccrUIPv{RgHu2&ITJu zgKSFY-YPv@>caTof&n7A$+fW*_!}EO>U__8@9MM^DGuL@*-~cPA3X090k_gXUz4{4 zEFF3c_(JbB6mS0eXR0LVsWv`8YwtWg9s2#-ws1+2Zz|82u}Nx8P^xD=Xmbt|6UM{8 z7e@7*j@=-o(*lpldE+H0G}(XlMN|?s18L@}_8U$1yMI#P zd(b0W{hl+0%qndJTy0xxzm? zr+N8BeF72$Q$ZTKpI_P_^Zd_J0?+9d*~qUJz1kWX+|Q7V@gf181JHVJzLkrT6?T*d zBs-q<`CpSFTSKl%U$5D&-<9-(>0d;mLV@z+keUBk52LVLomrSy=LJNEn|e<$;YB`w z-9t*BSH_U-LW*p^W0XIa+R<#(Nzclv8yj8gfp=ryfGm5*-W^0;l<$6 zy4~*Xwfhq8hE~-e-gV8u((n!rM5X28tHedb=^$OlRnGJxomv2!j*pK^7=xr&3Y z?XHJ&YurF&*@1FoV~c~C&`aB-0Yv9z+KnX)$DK5xPlD-YA9^J&`uur(bF-*8%&+5T zrUxjhQMCI58Cc72jx6%B%2~iv^fNe6GvEcR_H308j0Z9A>0A-B14r*K{rMSKYr^L{ z;?Vnz3{c9Bb>)gYclL>CJ7C}LDcuG!lLefRz{9F^i5Ku4GfqmO$s8no1+j832nJ&g4lNMhF#BYjzpIs=7NlGD3rp9US3 zWS{!jlf>w!J8!y90-w6sxv*v*cAn6?7Dn1YSl6{~4&bCnS#P=dk#&gcXezC0n&a6} zsJt2Q`kmwgOvGVX_|_G$E6q6=ZkalY(eM#jb*RFX8F*B_jzAY%*g zWEbcdKV4>@4xMhBe{@Z-LC5pe;>hfr9D}_zw<*yF9jCsXh8?@$4)uL#r!&lqAv+6R zbyeTV#(1@wD7JNycIbM+f}a5;J~Fy{}M^C0FvR%JhtkdUApJ8Frw$G|MxPo~*; z3S{5PL&Sabs37EPXh@{NF9%aZqM_IlD|(M%HThr@*uI{zpK*tbSF(VDK|gj3m~M7+ zuLQk&=vK^wvBlWKR(MTCZ;F8Dtlo#eK63N&4gt@I0%a|0(oJ3exN{}I#&YM#-)-mh zwXPs|DRw8^Mba=xCKH9Eem9?FLy_6=lg3VnRO@~EY2-2r#Vzi5d;z@Mbb8Tokh#q8 zc{J{+kPxfa!Ago@=lP5+17=_amge2jFZ08xXFi1Jl(O{q_uJ-xvUViyo$f=Dphvy| zaT#9OTd52!8{zxB6O|t5Oa%*T?f2px!MmtUb4D`7xxv*r`MVHvef4vb_HFHG5Z~1# zpHRW)%f_1%=bMLu>ySCuye6){tTT)1k<4#2Gz*$uZ5kXVPsVsJd*ZM9`Csna!_li zL<+$nn8k(ZtRUL_?`-dLMce+(X!=y=QfVz3v0E51ErMQ-KTXd+;@nh$>5SjZ-HLJf z+pLL@Cxlk)RelJK7{~g-_5Q(7xfy~pqSx~G4dyv4!%~j)d~8}fJ3F>d`PdJ91~mWa z@16?Q16+Y?G&(J&!u>#uxy*0R#3SggMod324pEajb(5YOy|c)*pFN~@(`mRa5_qBO zsp;E!LuAGp*KtV1DtP4WNs4*!s{D@NcLUnatEEn!+*5Bo;fc&aMkFHVHtl2j@#p6b zK-*jlHXiR(7NMXYK8qgvG<;iZn|k1^!mxK8+J+z-%=L!Qq{FUoq%a-6E~0K8H&qWd z?+Z+93^-&=Vyv7G9*P@cy!geJ+Ssuqg?IjER2;|)O+WKP-mGNCkKJ(Jwn0A{6cshi zD~%}C8ng@eeN#PFM>ZH|%Q$3sGu^+@-?=b)+vm9R>JZ8mxD|KFfSfK-_$?yEeY2Ld zjTs;o&9r;D1a*1b^m)#KU;EqZkEcr5v<*dlG~rWoS6}@GDE*WJj(5KBJYPA=266}P zhKK0v$w^=KZ-f000UMH@9TU|nE~4$R=K=_h_t~cd06MV!Qh@>(;`nA+_|&_kw$DR& zUuo(jz|NX)>2(dG(@uKB#l%K>qoiS_nU_S zuAyo-`T;);wMMKk7UC_V9v&x&A{BY6%N1|%=z7I92kNP`L313$LFR1n0P=Gf@jYNguZ-;0Qfo$|I z@>5hVJOgU3D_vjp2TNo2v^f@P4{moylMVEwO43CvPz%Q2P$9hd37ju9HUOc!A)SG()AE3bGxR(EKJA* z8*_mZ>z@Gc%j?Ex`j*h6Z07{KdT}IUnwNh$kM_!OV4GS;i(JrZ&J_H+y7Y~wK7Hrc z*Wl>6o4~BdMnh-TdzwyN>mG3{z|4dF@LA9$Q;T?* zBXa9C#qhWpv-1ry?~BRU;Gf6Hl+*Ia>*UHV!vMVwKJw~Mp4~27V?G&n&_yw_9*32- zM^zW42Xrztca?sXua{qi!&6Cl2uFMBzQ4aRTzE9>yIw0FkJGd49(3$nn=;Q;*a0OC#a?R>&e}5`cJ{ z;>z{a>9#4qEtHQ)(qJBV1i6vbuUm3A9dD)&*e=foQD(Oa$qTu6zxPjvG0%IxGv;~5 zN-r5MQYn!-H`4<4%Wb=UnGX3SXS+`0eGJOW1b1b5Nsk7CZtpkyL|y8TT@+zI0Nz-2 zayt87zw|zsa9(Q0jD*-=_xO1F82h=ncv4al1u~fL?6xk}u_at7z%<~fQQ9WgPltOm|QB@%Izb>fj$(Kw5%$@sO=&~K^)Aj0c`rn&Xs^)7Sr6k;_fi!4=k&X{|+txf4g!gwtXm_o%o8It)`b=9J7J2R_*J_Y#&yt_^@&m z+3T0lafnl3-nVM+v2QCN$(7@ekNM6|IFRwrxK%IA!#cSFCX<@{(Pc?g(T>m>p z4$lMAU`i)XF?YJ~Uo#G;o1{*bDeoIZ%jaP(np^)s7Y)z5Q6;XdtgL|_KSKZZh;?6K z{l6_1LV}v(pdL5df@8v3i7t7R&Bo9-$9c!kK0a^lOr~S4dk~IxGg6v^i&#m8xcxB_ ze<4_%;JkTXA-l@OczO=im{gmTL`HT4Sxn*kq?4Zt^#5(Nrm*o5dHoZ~gtI;6S8Lnq zykOaSPQ24K&pvY&=W>L%9R92c80#)(1|fp0=8CF>GuTG6JXF64bszw0kWF;3ufEDt2>=0TN!1(3~Z%$r+K;|=wJ^r?UN$in!|5RZmKG2?RfSSB5!=7VGUre zx|g=mUPk$QT8`og$JchxtvyGRzet35XoD3?(m2UPl#dGX@w>Y4X1=2xYfW0?(M%m{ zV(fbKAJ$Wu;C-5z$aPkBvPOkpr$>nkDD&6n4a8CkOB%IMglg;1og6SjUU1V7r1Pm= zk9QP*Ru6hHA)C0YUL@RE+r+!|VPko-3rZ!urEpsYGrLFI@L*c8+`a%!avpNqeF?6} zx5Ya=kAKe`)iSulMYPTMhL0HeyM@!Rw_UuAK9-|kc0@5Mn6Gl-Y>Y5F}vV_rQ2 zNsi8kbzlG3N^p$ky4{}}v>9agFifK7NIrtkds1z&dGIk`5A{%2(bDj3sqK$?yP26h zvJ2CEvN+Ck2Qy=NQ#1a8#|yTWRw}BVp$TVK*c?2Rtb57fDiXd4EosTim37LMT#>dR zgf*e-Ckl~A-98SLvZ#eO;!!da9onvHH4M_(I!j6VfcNjjqn<{LR1DU%cJge&xukGu zEaHIDJv+1VVSng{-*x(VzA|?M;T4=ZV7v*a^B#fidjWAr#s?~gY+I6yWoyzUfM;rjxsdszm`N%+&Jp`XpJ#*&&5E6A{ZQ!VU z>B&;@?wyL(FOBX@2U}Mo(lUL~CaB%Vi-9z_K3**@6EE0TzjU9cTnXEq0z{AQWV8Dd zj$rT*&_Yx48I=Vrwr#(b{~Mb_OGf)%KwfKLXt2{GL~S*)Jx3bhKJsi3Rm}FHB7)x;+%!hf~kExMVm0}ZZ{kbeJtu;<{*ZNSXd66HBtTY{5LY}9C{hkGB zXYnb|rlwI(H|*>btUWb!|D$%*-ZA@mQ>L#ni^T!9u#mG?!7?rMV6@69q7ZOL4!yQm zR^-FuR3>hQ#uE_j6E9YLl_v?}2Q3P6Mwfp;$QM$tP4mkJkZH@iL}=$>n1YmdTtGPw zCv18MNfTYSr)=buxA*e4)5V0F5%iSRi)*<*bbb2Bw6(M}4bDV2=GYscM3_lCm`PZB zo_Y1>-6PbI*E!jd4f?3FM;drJn)trHw(0%gst}-l;PqP)3dau<5n^O~yH5qZRkGY> zW^2wiHj#o$#;v#yjC19UpSjPI`449sJkpqp{Z%Ois=qra`YOF6G6$5Cbv5k+hqTenhs z2o_qIb;j;J+swjbvo0FZUi>{Q(Zu8)_WfFJ-KIJa2{zT7BBUTeyg1dmSvBuGi4@*Y<%A$oiK;J)GSoUATZh7 zXEdBu?aC=Prb#ykTuEW$Yh2{VA#GdY3|K*){cVC%U#tb^Tn9`gja6#$Gu5QO&kDen zFuC!4zBT&cY9!Hj-un^lMZ(PwJ{JjdCZ=Vv97BA>O^p<^_mos%75oW(THS9 zJyw$}-lrM_{IJ?Yy^S~ZN{G}uExo~`kI8w{;!SEPNBn=fJB*8RFd2vC0reWI!|08@9gIlhJ<<%Xw$Wetasc&&nAAF1Htm`k>4x_peS|LC>Z z^u%ZNQje{lS|Jv)bYYJ4j}d#{`h_3XQet|QidN?DNm_VwF|Hgb@`lljc_rG8@lImn z+R4Nnb)W6mqQ!PI6BR_a@nQHw^N%8o8md-x?tUdmB?{)wKieBf6{g1kV=SMiIuLdB zjg=^azA8=G5W;olRjt&buj@1a;6#u(4_33OhcdS?FQ68|{eE=f zOG%SN1fad{Y@CNT`0W-m#XV6J%gIlr8mCK^aRD$RSe z`T5>f>|OVlU!jL_4LB~XPMbF0mYkXaj~h+tjZ-o}yq*D3pu4u2#ylke!QqO*&$ zJgb-PA;ZM}&4MV{ULjR@G9eYK7a44=VWh80q%iogo7D7BGj-S1rwmV9y$CSkF!Mzg zPhe692txVEx}}d+(j}b74SrnAy?7zu=66PylAW`6Sl&Wj8sFvUT=v$A1@bPXvWqbPAX!?Zd6-ja0`O}i;dmvEHR9df_xvA7fUb?-Q|}TCmcm*!Aqzw| z1`&0*;}9d^DfaZe9fJ&&Y zRyWpEw!)3S0U_I60Yc`l(YO%K9-s<%KZ*aWAmllOBK30?edd-j)(^)GOlr{eC|ZGE z?l*&4he>m5@) z-d`r7g1k(_bmWfNmd2UN^C?Obrmps;zPEoq;Ye`I2A37J`BZPc)^N=nJp#QANV-KD zj)6-}0e#HrkKZ-7zDliQu;|(PWpVpnxOYNIXz43FU1x}*yzXAcezMyRW+r{7-X+{98x0Y}ad26BuX z!NoCJ1x#$>>+=c#i42v&Ao)C^|74&4?G^r$kfI>iuCg$7QfWy)(~?m{Z?W~>0JV@n z1d}gafJeF~HR4YJ_6lhx&eX$j+3FpzQ+Q7usjcrw#~2Fc`L6J{@Vc62oEFgAd*Q5j z!Q8kV1b+&N-)}?XyP$F*rfy;_+mbywW{#CY|M!)fky_z0BY7G=+sa}nr;*U{56lxk zQ7-&dUedkia94t`u@%2qB`N+c z`L;CXvEDvg+J=n&1G0UxTFdpp3bDMyrG)CfURKEnkvsXxTWxyky@nb9l|e|$dl|V# zPL;Hsoyv+-R>`i`-MJO-s&Z!F&>U0s{j?29k3C|a0jTEzW{dTdgxk(cp$KT5s{tjc zFWZsKoBTk1#5>8*ifn59&R(Y#t0{c~f~*w9n{NGupQE%ua0!`QDYZ+ZVEn1HAgZ>*gLv zm*dqWRkyh#w5!x3H0~Z#_Y?H(9j)mseDTfuN*DXi%Ke(HFKfuxH)g_1EgPvzbGz^N z=KFsN#2f@xS^$}s+(xa?rCjqfMd@2#_YVRcOjExX?}vMrY=rF-gGEq&ATMk&8lUjFmAVG+L_xNfA5a(|(=GMbWcJ{9YPw=rjKGC*_E7ilh9 zUs($ucaOj~c1@Po{|*pdA{*lR!a4Xd=Avpg!9*op;(q=w)mNa@v@8ktA<$>1*nSmZCBm6Z43*<0sMO?<6B^^q8i+3mws&eW`A!A^$9*^j0hy8guY@voirwww`pmsrA{`|$2u zbgVmlY^Een)E(T8vx6LEIW? zy{L*gQDCFRjc%eT%AcE5wauI|^O^}5&o0D&hBi)am=u}mP+i2p8eX(9e;kQk_uZqe z(Js651(nJE;JWaXJb#ZfuwssD;u_|e41`FPt* zf5Iy8{`=<#^%Q;$(^c7@9y4H^6^+O_k6_C?w`cRE1~u)0cZXXI@i|%6jhftB^c8uG zEW_PwZcEqlj(OO;G-RQvMW_bovg+Vb2Ae#B;P6nC=_I=tLS=ZG5 z;0b_k2F3U;f8i17Q|dpO*gD@Vgw(seoLf&vL!r5e0X#wVUqd6ojw_X!0kCbapgqX0 zdt>WQ5Lj+I%k^R#Y4uWy=f>F@5wF?DZ-C)2*`NM1w^ET%z^>RXoomsIKhlEg5;)iV2 zMXegg)4^YmLOaKzb*2xAAs*kiX7g|$_Q`t{i#Mwl2f?!fEdcq-l+b3}$%)mzl$uJe z<)i%AW~d!j{+8eIxtUWbq<$*n&C6dMjV3gbzdfxP!``C7eVFw_@}Suyl5P1wF@n4# zmue0pi&wMpg)cQ?2rk{>1F0KMx4RWd2#80fh2L35{rHryvE*Ey!?ZMI-|;0*!|KbA z*E+qLVeweg3!}vdPf01^ZY$j{eJ2DWbYm9o3$I@cuAbK@m)wKX=Kp`!CAisiwc->SzL7_1 z3@#?{luZ<1|Ijny&**Fy4)zB-EtQZ2hXxyYB=0_bwOqqWGXZ|e7$_dK{eGmPlo__m zhk6Z`c}2|sg1W~2T2qN?sp^*PnW-jx0pf2M@3hg5Nws{^?3Z}(Tp)=6-$W0Vr*Yr> zjbG)X^fjkA(%m|)C|vFbar$s!6; ztxPySacFY@wpsyjqTGb>~7(C_F}N2|AG$} z4urGYo5!o2iB*ChnSXqt8KRT<{B{SGxRoMwx z_?$6SskLEOf(tyEoxE&HX%slIJ%FQgD!_En`fCZ6oo?QbDUV=6td-+BMbP$;uZxJ; z4?yL7>(NA{*Sn5KMuO5!4!PfCgZ_a0`BPY$;nmce@mEL81gD6Ntkq-I>@Hknj-BqCe=^VMZ7`?r=iA*9yBQOV!u^me$%TB$q{#$?~&n1Ur; zi^(Q}4PAt|{$18OIUPcZ$P1;;Nm`VWatW4+b4_#yxTnj!c+Wd6rPazKMQYtVTW_O8 zxWU?7p3{H89r0GenRau+Glxonx>gboh*^g@FvTXAOE zpS{tHEEfOtB@SR^m^9+PCp4w=;H(2fs`d5P$sp$C1-AoKyosAcB zY3SXRDZ}G-_o9?uocS@BA^QmJg|VC(cIbwm!;2~aI`f|!nvWPIc3fEEBe{v7Dr;cZ8W03J3d96HKW-N?%@m@$TD09F^a-iObxPp#>FR3H@y9xwl-J z(ZxkytqNLYmG1RLZ7@*L+=7T;A!a-6~wgZ z@{s=*C-nbH-u$H^l4)H9xtO1S{Y!o{;o{PvDUJ|(ea>oWQ>VI=ELoUIzD;4i;fU$eJn6{`SP!pvf8GZjaF}Bxwo8vJ?5P`-2yobPc^QFfA zr(|^Xl(A6|b5gN*ot}3S2O3@$vX59qqc{eOO#@6fE&*v-SkHKKXg3SFQ98E2jmOi} zNNqnA?%PZUCjHXD9s7Ir{Asdz-yzuMVxXRR;g!1Okyx6dtd1uyrXLw;%aW23{j1g8 zU3Ihu)Y9@hWmc5tr8gIQhc*7IzeCQy|Mnk~nGf(v+WqA#x)lD+c-d5U6K4xDQzz{< z3>;2zMD*6yT1E8@#h+T)JuRN4MQ1qws1`P7%tL6Ca#;4{tb7b4E?nNn+BmY|OArt9 zpIV7?ZK1NYnX-q=aZ7*8DtU%-o3_6OE6R}l&Pv~JS-t*rk#HQ!|M&f{fAcaqdSoy( zFB7Y`*t1X7{fyN?$rfbom=^na?`@q!xVITlcsJ*s`z;lWql7k@@x1a{b1kMD9R6I9 zvG+2tlir;xqSU(^=)MwHEu?()HxKEuX>P;GQ*ucB2H`5Rt?j<8GPtI%6*;zT#DVfc zy#W6T)jBI9U+vUOizbtHU&YJo4?boImvzdvLHR57EUXJ3zpT4gTed#x{rHxpDSi>(*f5!e9*2$E z_aVS~(UE{${i7(ra{-m#b?svpr2lKf-50`Ip1&)A_Ho zJQ!R85JzVouI+BBn|Y((D)dCo!IOV?|82wZk-`{Mk!Z<_BGAmL-ns-cojjl+<8XC> z-;dvjKjj~#l&EOs-0q->pvsdB`8-UMW9QI+%6nMuB4QAA%tb68nSXhY6jTC_(^K{N zA-OI7oXdOt-u3CGYq>HMCsQlezx~qGk{s}`i($!+Wx>(w>b?>R@qA7<(lrb}GDD9n zhz<=Ra)vdR!WDJeR4!aTsox2_D;sj_6I63i>6UZfw>Vz&NnNGMr;_Edb+*`SVu$w6 z6=LP0Ty+x~)Vl^b%6ZDU7Gpj<5lR2WZB^n^)b>*-d(OeEp+8UE>d`PkvQX~DDgx0E zb^*gBcIWT*H(O#mZ3W_MJ^pV!p1SO zs0xIaYogxHli||2&Oq~<4i?&a4P=k`0=78i!Kmd6*Fhb}>>_JT^8FL;=Qcji(hX!o zV?9|M6o*CQH_UF^Ol{{?O1!0gHt`|mhnX2?`G{c|!K?H+f`%FOle5tNE^fP1_T`%( z(yxX3MtxGw@y`sE(IrdnDnmf#c@yRs}kx1yuD_j>hw1>-iN|OJX{C&u0dZ5W>ZKtEBFk8-4%T(_G|YRBn%dSwDeyo9<(h`_*7l(q-ecqD9j`i7bZX^@KO01$j0y z+Qr4yx9xAUO^C1ixMJh?rnt0I4XSA}%yQO?$!G)Z6!hP_X<`*M)p8-_Oz#;|O=UzT zQ_BybP%i!8ijGaajT+Mtb8^pjcNLB(M$daMBaaYWYCL&@hWN&cO-B#f2ULw!M{Z?! zx(5}`-s!Wik<8DwQ}9@+)wosVd0Dcxg3U#GFq)X$<50=ovAd7QV{u*#+BjAfARosZ zy*gpGZekdyeLswRC1oyU^<$eGjRfn0@t;Qng65p-BoKBKbW7d!32|clDHhUtiBRou zg8V#~S;Bu`9_Pp^&g|VN&}ka~<=ie9%T~4Au99nqXDgLz2HegJt<8+EG-mtiozm-} zvgsf35D0YTQn+{@ltukaOk2m9_MRl;2=ZB^y|0gR&%LK8@~n_~ z_&0_Si(;V&zSgTg%?3tQCurI-4_$l)U*s-KJ@0F$lLGqixd@_Y9y!BcNMzk$`|99i zcGx~iv3^LIyNF)8hR$#;)G!F8{NazdUr+BnzhfHst#a$gP;)Fru)wf|NL{mVwycnh z2f)0EC0BI|#|B--pvm4BYbp9J+E`MQOi6mAlT#H}XF1xQnbdqjyxKlc) zfMWKyXJ!078EY$@?57MAt;O)u5sT#P4>>-rVrq$*=4~j!<7ux!ZGaL$e;}!TJt_u5 z=6-u1to6h#PD6@#O8cGN$Q+(M-Ex(FPubYxNPFpoh2y%z zzYKNqS>o$?o_q%hx74dzw`&?%i~5ovmVJt%TmBLY{x1;s2%iQDjNaSF)_`(Q~q6rOr&OX9i3w z#9#8K565SQSU0em1R6MQ{K4t*+@7nJ8(RD+!MFZeqj>jSX;mkg=gnB42?F(x3??~a z$SMr+-Sz%Kf_WJGx2co-1WM;gsa>Y}mnru3OvnLv`%|jR23c%qRSC}Lh^CAPe!w9*Awk1DUGnLZWn4r_Wp(bRXR zbf`ltFQz*&XP8R;k=?_vi-)CuiEDm6l)B&(7@kx4Op6!%VTtfXBU8Fj68)40(;$%Kbp56Fa?&Yd!_zUs6EbcpUu^BT1d`LTUqU1n z&-Cbu2fiz5h&5Kjr++>VFi>K8?da+Ply=Q32P^&6(%ho8yVBqhwh!)7s%G@OplfxU zKdPB+@YNdMV}7Dm&b)~qSD9_!uXg~@C8G7^-g8ijYi`w`|0^Hps(;2nAam-LxPlVc zOOhTjagk-VDA$pr;!f+Q%~F;@7g61v;EnPnQ)`p&1fZ~(=?{-o&SWdQ}lvMC*4 zF`CFBd4=OQD0#QlL;;?d6y8t^G+9V#Gdr*~b`_-J;Q53?IegyDL%$fCO&w7j3?8dR zkPPFu=xmDoQ6*jpTr|gze+oqLLQH_}nh5SHY+4j{DV=px%8ir1i$B4`In-ekPH>*S zwgKMnaHK6r9Z5OTc?#Yd#C?t4e^?@u?@|92r)|-*;+)&Yr8Xt2&{nQ|TMMF^*T1ni zNfn?4=bJgWLg&7Xo#kaK9vSQncS4u!WeyD(mkh9J2Spm%Hf{4vrMA7<{8UtnO*T26 z>%p?f=s)3~2BM(dR-1%VeN4xB=EpXQP-PWi;@_L8Ot$pfXQS5gIi-~o5Wnva8H**@ z2@-uV$SnCOfo)c}=BiP$dbz>vYR|&zw3PlR8; zMspOU%6ZvN-!oc}bw;%C6ZWR*4}U4hT>5XSs=kv5{}x``>Kru&uA6+71}jE{j(Y!G zA0D^KZ1w>YLOiUel8VH|O!6B`xIZej3Y6#g3T__?)+ba^m3^XtWw)LrffIp$Q1XKGw0VF%Lx;zH&ET7a z>YaVon%DLPsBB#F&1++rD}JjkDlz?( zuQKxLB6L^kUD)tUvvNaX{ZT$e1zY3tGEK(<14Q5lj-hZ=H$JOzVQait8l9TXc0s1* z^F;8>20JEB68|5FHo<~iX8(}d&_xJk5$9`Q_a!L~C7X42h< zbjuy|C-r{spSZ)Q_893XBGx$H5sEk#UE?WMX6_rzcd!ZO>qbqxDw;Ip>(INcpY| zL5R^6&QLH`u(6Y^Mz(1h$&=6>$EFi|aJ`A}U7XzIt4~gLYd+y_7@hj6J*upiw7%C= z<~UMTwu6rtELfY*Dl6_RpA^-(ElEGRUW$Eyaajh>#k3C9(4s)X#<5s7G6Ak>WALV% z2dt;&8Bk4cCe*o6A?Mg?ro)$HRDXnWW*+H|!d0cI;?KBVs?MlSxwT3ODVzjyQ5XRo zvlU%Tz9SPHJx-^btU}G49YyW3PyE&a9cE;^J{QKtG`8*g&DAgM2PGjFuQEp?4@PkMJX&mRHzQ)^N zJp*uJtUCc(#<=T>0ji6)PWxs0Vc+Z3L4IgOq4D60i26Ggj71L|LoLxg|#_-iLE z{;pjTkj;)Wc~87NNB8tP2e@N!uOa;_{ShgOoR4Dh0EGE~;}Tm8j?YK68lzoCYow~k zBJHjG5Cdrte=XaQ;%z5pf(3sa9YdgzpWE;ZbY)P*wcM2GfyW4hur(uI3k@H;5F%^^ z8PgS`lMrO`r=>|{ZnShv4*0BmZ17GgDt~JHoEs_spc^X z&|!*_C1pjp@N@D{ocj7H&i`#yHmQqFgIr^fEEN? zyE<~6>y)4i zUZ`azGxV!xL_AV{`Zi*M$-9yOw9tK|qkYCO#JHDDo5wBR_zA$9YtI@5D{Jsrm zWpPGeRWRr_N@Jk9{x^~ckK9}&B<=?D?RZUl&bFjKK~B~a5l zZm#`mHT6DzijshM-mT<#>yYt*tYGPdc8ym|EdN-yttb2`y*0pDb~#Gt?y0NYKN+lehzoe_I>MW%(B~(8K&g;xc+5= zpOF^?KUF2|NN4NY#S8ILU)sadD<2vPIelA=ocKSZZ8<(Wig#(Zb)CzTw|T_A^FBXP zNW$)U7*hR0+z{XOLn!$3WBYKSXM1;=FYcMK{|wknk?uYLrtWUaboBh|8IA!K4KyO5jh%3biHmx*IL~Ru|L+_{~M^R!p(7A zbUzYU{tZ+21q+}fnEVT?OZLAd5*XpsdlkWFWwafxsA>HaR>MoW~ODT+hP7&tn2by6c*^664fFu*$T_#MS` zA*xb$o>?H2K?p17SX9l+Px;_KlINiK!u5iw7g;UwRv`~K<@j>^kBM`+kH42RU7Xh1 z&K)sEH=cQrRBP@qmHn-}X+?d~{nq?El$<(keSg{1DAB{40dzW$Ry(ZfX*)M89#F&e z?bO!Mg1H{ThZa-?yI~aJr9V9$Zu=D)Ch9B>EYf-$Uf}6K#(no5VnRpP09_PLUW?Ad z6^|;0-$j>?7JCcOq&^QHs@!JR%C#Bk*OHZ{+VocLBLrxawjd|j$>cpa*u#&X$F;tV zqWWX@sC0D3cNT^|sf+IjQCT`-Bm|73RjKm7d$1x&tyx&oxEBP37F0V+^>!T7Jpqp% z4!Bl9q=ct*n(WeamkjFqmGGEd1rgLl=z;;z#_ZExa5Bw7nSU%8qL6@~nQ%PZA0FC| zqWA6);qrn>sO%p^I)je!8%Lx%)_r3=oVd7gKvw& zgY(t~VW4>#rV462Z!$2dY{Z>U_+HG8q}gkYcwf#+$B*A4pA76UR{%DWYu`-PM|v1b z5^+LWc7B`(D5}8!^>DF)poXsSw{QkG(@fPlxV`Z37)wukYrXi|*3-y%>?I310!@Fh2xG z9$tLs<7d(%=0x3sm^&pKA2V>Nh@X>H1uTDmbH6*;EZsbIDy9#o=&d0|prKza=69*!+$cZ1ke#74lqWAt9B2sT2OUjK*Y%O9CVZDoaMRd{xneApINcSDYyO6WH zyN6dN(NsHSPD$=-(=6vO$?@fgJ9y$5MprS{+VyN_TI@%f>4l|uREy3EQM*+AO+(6e z?<_7mMY?{z*b8QDetprQJ2U$>Yti#;ve9Y9 zYOho=*XAzFT(PABA;ga7$h|p{)o8iycgM;A<8;1KwL+D$&1#;gkyGfdI~LXnu-9%^`>qvO!8CSuQ2J2xY>O|FSG!a3;@ zVA8U~7)$FSn}2Z8l?kjX#6-=uD7i{;dDcS8n8%wfA)lXW(g9_$awb4ZA$A6q9xjzU zjjQn|f%q}qAsqXTtA)N^q7BB+05}Ma;~vdsiZ`WGgr8ypcsVJwbYuFgw!hD@ftf8@ zxPHr>_}KBkp_IoGoeR)jJA)C}q6*cCXwN%@6R@RZ*5?WMBhz236ky0&P0{k>4HqB) z55E~j&(m|v%^;%Oy&bD7OOCry3WMu}0zg=deTwOZYiS|ChVN}#_~%zte$$8jvF=E3 z-8;^(v3m(FTmc5n^QwoA9~TVBodflJe3h-G!JbKJ@#y<(R~hhZeZvfgE+qrZZO#>; z5buYBNc zPieyA8d+i8$drMaDxcSs4l1o^s$8OEt)*c2n#h?_R$r>3=q^>2Mnq)QFLTCE;zfOZ zX!)qw>eD^%_G@QreM6_s#}f>##%y4gOCi34&y)eSL zdw1EZL*z7|-WD6n$$(gbT?RK5Efz%!T;aajF-YEhap%(LX!?jaP^Ih&2Sh+Q`tIMo z2cANIg6H4jsxZmlVEO-u{dxgm%0U4Q5cYZKzL(@G%-gq`4LhaosuH?wPd#w-Qf+{& zT57Ec^q1Ve>k^r+QE1OxJR$YI3=x3)W{3bD`rj!&X1P)V3U5&5*G24}_Q_|sH@Wc@E6KTDM?)~CZH#?@gRXD%C2c0$ zKWPIUR2T)@eq(A-Wvcl)v?_c1&xJB-X%6#kn{&|KbIYid-A}Skt=to}Vd&q$xU-&I zMibrZW>FmNLws4X0VI4-HSJh8>)-$05rUY75^{5(hVR;?u5R*~y7$iMl3eT zc~0PGun)@0nLf-2xcq=|rrgiY__;G?{h_!9=%!fm`ed=GHLx{~uG%ralDfr}m)m3* z(_x30n`(&LR8J}+4p6++!0<|k-?LEi!dcy(TNbzeF>bVpX3K960P zGSvGmll4V~eO6P&!zK6QJB2CEK1-NT7zC1OS4RRYe2G+<-jBwgc5&ZSi|F4X z^BY$k^2YhkR{TULTQ`-@bC07xT})hC{@tQKjs@>of~J^Nv_iv)iGsAmer8>f{Mg3I z00U>_U>4tQr9BC~K)3mUc*y3NUVAW<7LfYLz1kR9*X4se&-tYmLT~7R1_O1LxThkA zcWxA{#&)Z;;XipVP2M;D39%Qe=6orKaa~3Mn`x0GV2?=ukyCJ<+g}+0kUWkd*Y1Nb z%UE_6FWcfYhz4%-4oEmwB+E{HH-F(-*DVZ|b}=#r>^xxL#t3@EOt2K38O)E--&+mZ zT!&I`*P_UH!Fox=FrlFaS}@gTo6v}f1J_+POu;(b{TxrSTPdIm@dV1*sLHGjW zJrWhLo4a|ebb6tN{x+#kC;%P^Zu7X(fHxQPb))Q7>M>#!H(%h*(49Hq7$7{n2>YSG z@!TxyzeUe94!qe=;UIdP3IoqfR&4ypEQB0%Kk6mP`XZjw<+u7m^6bi4TC4b-YMh zSScOHPsnfrNKF>UN!o>K69O83$_0Wk) zoEyq_53P+QY~%sL#@zajr-5fnfu!LDI{Elb%(uHX!O(ldmbee}CBxY1^3YkzN)D^e zT=;k1M^$?jbt$ylZn#>@<*UFdVP_)0H+nCTTPF|EVfHCzW@s>Y@4j6s8e6gXg=G|* zW*C7DmY+^eFsrBzWl1>)HsT}YT2mlw@j1)UBgMl#7q9Qf(*YCeO2;-Mw~=5?Y_w*A z+!N2O3fYj*Lg&!B#$*-pGiOi#?T+qVy=h1#O=~#sIqVOJvfn#xF(RLD80q={X5(E_eZ2f zbRSI8A2o=t^?SR%Nuhy{D|=lS=E$hBkoDo%A8Gb$bK~D9%2w+5YjcDPjov3ywiX~n5i3IAf0(1HJMku2W*I}Z5=_xg{ZV}iy6GPU`$RKOlJ z-0yJ;E?Sdd5D#7Ab05G781dp?{YOUT=aV2ac@Lyir_A5|5M!TA)%^@|dotq@xe3(o zrKdk}bB|LE4oB&nFL_$r+i?f0n%Bla$5{^8HVQ2!sNaf7&&{w@#>e;Cg;q;9a1rW2 z()zTcn^sotUgE$Grus^ta7%_y0fZ!(h4qxI6nCZ?_Y4XluRlmk&e4xqj0$$n!|Fh6 zL5-)^dbUFEtaUUVYhdCi5!60s0`^sTjhgGN3$>+}Qzr0Wl=xO|wWV|z!SOp=07y1% z1F~xL80(#ztN~fJ^IMA_@=xb$6u*B@NwOWls_Q2{iK;05KRcR62Wjq?K>X4;;N&+w zhk13hch3ZSiLc4rNyuMQvYnafa{MUsSLRO^yU#4?!v zhyLOWXN zc_3@W4zaO)SALgr$KzTVepl|VzA`P(RNKBpb3sS@M+4CU*`6LuEG$Lq+d^=8MCSl* zH)JLe7Ql;*f#Ceka5L6d7-ePt+6Rl^!TQ{NIguW@IACuX9ryJ4HY*;9J8y!D-;`rc z$OIwW%@n(1FL{*UgWkKP{?oR0e1lO-1YD=}?C_H}woq9$3d_~ayX^vHH8A42+wiI| z|CF+jB-Qk5nbsQpv|FTIz9U0K_isR?_oTHiZGUua-mEN=Bte+DA>BFH>;CZCa)g3$F3|-FbTiLILm!}nz7`(q~2=6xGw=w$O;9>dTajApoo_skW zWPA>Y%dj7Bs1Y~s2+fxiS(!rXxps7N;dLd9b82#;KSq80U3c%fk}&A2ggR_QD;{W* zC$^SQim<#C=LC4h!i2MO6-!qTdGK}0K8ijuV)vup4^)$iv+pM0K6x`vC#%g%Q3=Fp zE+Nwn0F~-pwsTP2Rr|3y(P5Rh{z@7y@i7l=06jG1vRFR^w0=oWH_QJ7Aa6FHX5}Mi zK|9sx4?A2&&WRbAj?$^gbo6AB51g{b<~g#$BEDR3(3zfmVp?M^N4gkV8mDM@87%Tc zw<6u2fF7JXLlAK5>nw^hwZY2hd!jAV!X)-1|n7geyz&j!=@@{^nO7t%j^Q6Xqofw^AJia zUOcP(VeIZyce6PSI=I!su6uBlYs7=xkh~?yH0<~ZXVcI!l7hw+Opd{S=f8>hEgoen z0c(zDc_Z4T*vyNTJ&6l5!d&mVFMDIvOqP0kfX0M1ho<3AHsMyz-yKa}Cyhm7rR$Ao zUvHoS>i99ow``q~jf$r+F8X`$Je=kiHk>OsQg_rdRJ}A}g<$K(hHQ4P_5m9a`TKrn>m(rqX)v;z$;5N&rJ<@hrC3M|n^0RPLoj zYwACo0ExHbDGL*O8{O4DIo7nuHPj13d$x}zo3jZo0SOKjvU`^vOpO=Qk$*RdO{*HXs8X5Ute>kcYLDSpgi^HIYM zzGXX8k@sS$$7(rK@(3o?ASF}`MizT1?nJF-z+`%uB{-;OsN{b=OEepc5kunPyDxV0{TdFDx+?NIH`>hJ`CmFF}GE!$vA+;Lu7I z^g)U$Hna96{J-rIfYsqs%7C;?jI6N~!z}^1()qFMY1|S%{NJm&CtiW}5euHIpNw3-#Zv zlE_ABST0o(BYdUaGt}j`44iX#4Lg41vJX-?C2H!RI zXc<6;I#@6Bt-GWu&Zn#F3H9g!7tPD4P?Y@f_uZ}jB0Hg^DYC}|lK&JQm5k+d@ODZN zBj)2_`Y#M9dgcoC;9yHGZZ@sF{1_kIVy~j>*3BgVv09^bZ7iY)pecanf9MJV5?Iw#u7GOxDIbLhI4NK_*!7=KUA=#*!ZryqZeQlh+RJ;F!o=zM+=W$aF^LQULjfw|w=Q4M+EGinYIlpi0Y=wY6+&(=<7jhdM z7R}qWtctN9Y92T%mREZ>tOvZ^pL5iXt1il~<#z5JUvMs5JKjmza;#%&CaOh9wp_`n zYxZz3Ozk>C7GrvhU~EScM~KbjYGbdP_qz0&;Vs*C<>Pf`zh}e_Ydu5>!;use^zrLL z959P%FM94Xcqvq?-C}wh(tip?IxNI)9d$KXt=UVvF^b!YbsfW!G1X_a?`a1V3s!4U z7Sm_V#jyEE%C)TBQ{+B57xEXTts!FjS+T`@{j($I&066!z5S+s7;snc!eaT9@QQY< z?z6_1EL4^N;d=Sj?N9qxduCR#z7`FhV#3&p=wt(Sk<7?_-6EHiT)40?=_xik;C8N3 z=HWRGvbK{O9Q7P*J_fD)-1Z>^!Wh&}kS<!gS3z@)gB@Jv)Sgpv$6M-ZciHAp8K9#a^(A^ z)L+aEE^%-=1797o%A8L!JIP!*@}G8W5fQV8NX-CZYF8g!zkH-(PTW_~qvc<#RgPE5 znuH<6Q6ojxWu52qS9l=wN7&WcZ7NGCkRYy8Zzou_VE}m8UUTvux7{$h^l&`M3)5xf zZ(O{xks*_l{0(fv7($WU5JVC~kJu+MJ&k)>N*=5KVi59)KiGsKeGkU+QTkUf8{BSSYr<$FKYYOQ9!FWYwNUgQW@RLJqYn2hPzD`}t z$do_ZY@npP`<-9+F>kK@I)M0Zs95-?mIjl)J*Ez;m?PjDC*79?Z1B- zBy!Bt;w~&s)IElgCV#6LH#)~|{u-_C=fB*PkN@G2p32Iu$QWg&7)6)qA9WYVgPs(H z*Hy5PLS7e9R=9Btfr3~8pBI$#IA7hR%M9xy+;PXMR^EKr96s35`__k)E|O;+m=k4v zB;vPC8;M5|r>h4XVt>n18ikx5dZOCAqvmD|37gA!Qo8!|+0Gl?pe_E=s`fA0qrJ;7 zCq;qJ#S2%EPT=#_gXYn}L!ORtQUe8Pe$N+xZAlTmh$rS`v}I(}Ad1)BrN8wNoM{R4 zqfN)D|Csg)je<%QF{+z;9wz$+tNj9}p?hu6G75mf%4zr-%s&ily1@*%w4^@FN4(j9 z4_Q#X)lj2)W5O{Y%Y4th90~OpxuxyOIpj2?LKyXOSodMLY?=!9u1z_&E7;|sM`juS z{frTPgF57l)UM@}SeN6wG1^5UvEPf@?bR-UbVcWn|x(+F7z22y_;fNTAt3iB8 zZAv2=NIr>9o(^OiZ%Mi=p_|aZu@gdBH$d&ddVaR|D8Htg=;~j@q}RLy`|UVrOYAtP6=E?j|H`QS;cQ+v8fIdOKo_o7 z+CxleW0ee#AmWaJ2sC_GkOgTO`C@t3X-ZMxUEuA8mhrKg^iLqEx1HS0o12l^n%0vBOGT1;&;dWaXV)4fEl!WE#%Vh(+FN^QI zb#VP)%zR>}4}#2}SMH7FmcqHo4%}RM1*y zJB}Gyy1LTBa?`lT36Gv-yr0!uyv(lE{9PkyEW*u&p=vwXOb+0YBo>1t5_Je`__~Lb z?Xv9@_zD<*jE~Sf+~~67=-bc)f>$LTgX`zt)Cj9K3DVzJG2yNcADb=%yjYA3gx-7% z$_cuRRAJ_p-v#(+hilJwc$RAKxfs!|Z{O5~LtY*NrM)3@LmR{?bX`ml!IG=qLNUTVrn{47JhuTpSoCs5v-*xNlbQ!4#?p_ticdcBKIWzljPaNifsLg+anOk8fVo#@Orl;)N|* z8AH=w0R{pd!$j`tZ{^AYiqzvRo&x3DAOxzAhTJ7DK zIR!V!@vFsaI25_tj2+3UJC%j2dTgKZD$A?JfZ^-)a@Dwd$?H%#Iyzbu;NszNpPikZ zpO4S{LdS`xFibM=F98l&+YQ`p`9JPy|Mp4xN2Gm2D8UtQQLri)a9P*J9sjzG)&ZMS z0~{v{0c)XVB@tWzhIeEBIXv+zko95tdl+^C!2VEk0y1l_>hE#>qP5SkQ2`K6S^^5| zRPp6^N@7?qrnirAfBmv}gB{TQ2sW^27U`}o2Fwmz@QU^IOZWn(pxxNC$02-xc=>&% z5$-f!euLaD57m2FWyDtfQnb2wHyKkN(S*A(fb+{A^-sby5*Gt}z3X`pP1mFNEtbiM zR~CS6C)$`6a9V1>y)WL`2W;PKM*a3b%SrWo zvhSdmuHtN@EP&z@<3B#SInS^W9$rS=U9iB5IR9s?0pjEn^&WsTot<9DtrD8$zuvj= z=3lVp!dS0PBaS|b9C#g9Q7_XF=(*LzEA~wVGLP{JyE)Fju_4J$4^vy7Ns!d66Ju%G zWW2lSv*xUl{u=#!|I)9Y9#theRXX5|>k_m`*@2RkEsrIIfHzKhP%Eg4Qakoe&7C~YKK-=cezu1mf z?3Ym6UL{M`8$`6&PP+hJk*DwchGw#v0QS=#tMY3c(0}5F`d#LXfKZX`Ck1P0($>s= zs8QMIt!4Ixvgut65|FVQZ+3H^?$ncZ4gafGW)cQeJ3;wLYM5L7wOL_iY{E$N8l4_Ks+8M zpeJYOi5*tCrSyPXq*Un6KD-v96vz`LAXi5zI%$u4NL}2+p7OE))DsXTD2L3cjcKda zi|V=bj@&DD8VCb8gYh>}W{I!T5aU%mykL|yl7}~n|ugQ9{Ej<3zEtrAXicqq>1#-aM*7`h!`_=>{KvgQhvOyg8 zCu)Cu0fnBGs?WM?)NkHB&A|P!=5fHkfSquK|IH0E^t|s#|Ettvj5XWlnh4SBcS0ue zNIvO)KvHUVRNh}(OLl{$I3!LI3QLq-9ToY**Lv-}dmnBj1@r!gaoUu;T{g$Ko%~+( zYKWTNx%Gs$AjSZ>^048Cn?%qCHtNaa}Fz@)YpUgxOQ>({f zkG3$bA~=64JYJ%IE!yGLMM;vtU~+q2+S}$2+kU~T7gaQq)}G=&Uu^4d{QbK;dWvdd zFClq?OEgiEOZnSC5i)wSNlAGtcs_FE$%_&5#kOrD{}F^QKeFT6_@$3EpY0IPvFbF# zQ3t>?x{{Tm(HNVEZpMEiww*1QgEJb#t7n!>`j}?oy&8wYwnNfkqL;@?P!0+>+a9Ot zxf{!RTOp)iD#VADw1~%bv!ML6bc2399fqdN5^Wudg=7Aunv9|&P{YZh&VGnTZRTWh zA+(m?zf9m&U2(ak4_QgwcxCZ0auzIgIZmg%%WL`fx z!XtzFp+yv)_8ONGuor2yH=Q$rn#>r0QGiACo)-EXtIgChD= zRgyj#P(xzl(ax{BIQxa*R+|ohDyjfFpYX>3Hl@eEpq=c0aPzaV5rEC&gcvjr5AX1< zk5@`8{OmMU9&_Vn)g9Y!_8Ffx;_j*Hxl0BXc+e`bc>`AxlT8AsKW+JDclCMmV6H2Y z3Ui5NcL9LM5WFNBkQDp<$vk5R<3#>`70dZJJmVfdWh=B>i*^@l|V+ga>YQ6!g{ResJKt{IBV zC`)%Nd00pOW{a@HEjmOvM9@BqRXJZ(srfREuFGv420*wfn+wxQ9LOhIX;*rS2KT~~ zjG;}8oh-(+`OHs5ZrB)p`mVYS4Ukw}=_Fb!+<*>Dnj1YZzUFDvVPRc2j&C^j2ZN*+ z*V;au=ja$&v#@26=(=WLT5|CCvO3_nLGzn+_NKr+m1o=zVw)DvHiv3EZrI^&so|%M zXtjg?Fy=<&a88J=1#fY@sT`^-#?`~kY@A#MZY-wsec%Kf18|ef`w+8l8B^DtrsnR7 zHFz`f9${?`*~8c_xLiHJ${Tms|KxH3zg8CN`|cMo?lIlH{rA-kVh2M7K0qA3x;AAH zHhtG6)m;GWAu=~J)Cf(E%t@~bSVwQ)Ly*Qy=SvM{doLXDHMtNUrDy54?dpVNIa)+>BhWF9-NRe{xcY|NDW#M0Bc`Or)wMY`D19x^h3C_plJ>;$$Pufm@ecZGTMc=QtdW7!sJUAOaohHM7o*dC-EUOYD zW%>@@c?h|?c05Zn?jD&|Vt_R$cfA3QqSG%7kLf=3t~IYY%GMiR5H~zKo89)m9S~B(v7O_G8cuaiP(LUE6U52YPt#q|rx?}js zy#Blaa_3FdN#gvnn2~?Tf&1KH*6*_y(l@sPiQz<3>XVUIE`zvvce@o=P!?UcGT^TzP6|&1XH%0a6rW;it5K=9YLmwo%kQ6K|Wq zvB}OIrm1Cvm@qiwen?xTWPwh}%&2MJ$L1z&T_eAuf=BWKO=XgL*c|P_fn~PTfpaM$ zW-bDSl~lr0lpxO^Ub_Nn=Ii=0J%~~OZ!9MD7X-%32Abao+*-&TLX)y4OU{R*C=G0y z1>qxrF(n3M{%!Td&w^2Kt-_RWO8e26$BJ;|L zMPGo%c>bbfX=^L|6IU@5*(W+FTZb+pJ~W8pDIWaz9-{zi)*OK}n`fx1vmMT@7Y@2t ztHUhH7woT|cvogKf+l>+V-cs@j#7H@hCTKV+1{1rtZW~=u&p>TpSNeJW|FiyZMNW$ z2G-)Solc=XPfJby(jfEH-WicUJ30FSn3u%1}A_qqKzu(B{pFC3doTZo+z z%y@skZO}yLFa4;dK{s`f>-NFt6p6>JyIX5dO4ZIZMp|>#<}w;<7p{CNEExo>)Aj* zy!JpOWM3AY5(XVa59ipdsG7b#tm+QQh3g+Iz@t0nvwVjkLV|U}=b?W za$$r)ImH9W=0S+f*>*l9Re8U);*ifb$+B=Jsjc$jC||!3J0mphfF3o?#9E#FXZ><^ ziP~X{`Dd@Zl=q5P4Ko~W^~KvFu73hDLBkUwgTiC5W*S}o8Db8P-!nk>)U#ijVNP|; zX}%|FFJ=f_9XSOt{^KsEht^-mMg`a0d(PCZZx_VRoIQVzRxfAGts(QKnmlY|`jMoC zTx<&IKfL9%?;*?3sEK4UHQiRr=`ou2tA6j(eriD`8A9H*$|8B9g<)jQ1r z_n;E3J)!=yVXoe|4pa4`#bo(J2SgkYKd208>5F8>Bsrf<+nL(8Jg7>KeTqCpVcwrK zOr!&O2FJitp_X_bj}_Hv$F}KJII3i~I>SIev*A~y6{vx%rwEPoGbz{-TFBQcoZOlJ zDbW4<)Yd=M(`ulhDD3l0Dkr8|Lp?lQa(E|RsC>Gn)UjpI*gY~;#hCO!FrQP$@rqe* z=y4@v0g)G%OFYwCC`PV{GpV248le0tkAXkph50-4 zy0uJ20!GfcW&^2)ZfEk7dUs6y{a{pQO=V2`E&(%58rx8A=Tj3fwA6I%_*8sN@7aK; zN4))?W_rIJ#X!}gA}zeU-PuE)V@b1Ct(zx}e51q|$te97tsC^=T}|UVqd$&cmsvor zCx8P;@r56#?s!0_9x)!|bNF^g-+ z?->TvVj1`rura-}&dx7!<6#dW7J(ZDkk6 z-KDxWL3L2ip-0T*G`d}|S#ZQ*hAbPSx;QETGxX;=_@Wm$ z3C0LK7jHR2jQH_UFS$B;>g66nayLkiy62(|iRsSfKhB3gVAHWw3?xJUu<{5DQmK(j zIwoES_+9AOw;`V5(GXCsvooL>>i+n~HdXEUQYOpJF*USvhum-YQgg*#VPq!I2sbiS zR1xUvQEX!EVjTP_l5AeocC@t3v}ZgEm3tL3&@srmAMC5^x2D>3o^6%F zExW}&?dH5dQP!(%FXSWXIls~5-BhO61CiGtTljC{28?d&O@5f{pz;kDBd~N2;Q-R{ zxf_HIt}W-1WTGA_`Bk-G8ClTnw!`wlM5USEWXSX8*)8$n2OEUdN6q6?{Ib4f0ouy$ zi$z=3#b-RDlb?O_i+6vanZ$Z@FA=UO`XFTNoqM!ZVvV3N^~ z@q+7x=P3@?Ki6Mk7L*Te1NB`M#s?$5ZKfR4CvBfM2t01~!=TWDr%t5hOP60CBz*Sihl09iY7qF+;rUd>&gA0s z`wIt$W8m}s{S6UgJH=GTvur8$W8-B~w+1F#AEr<`46K>0E##q2rHG8U>$%z5SH(PO zM&oAOis`^8U}w@QNWg>M={#Di`LpPrymM*ps+Dx1lu_!U5otPuAW3@jlK1e*E!*Km zzr2mAV{1kIe7jSBu_=t=uakVo#oAoNA4i{aOxHR!(8Ec}HE(44mjbUdC8i7NG?&3c zj+rfBa)Bvn4-Vfyv(yT_z0qyjb=%}9nDoKz4NYl_`$+j=kqiM$LL*EMmI$MZg`PQjxn(XuiMPr)85;B~xjD((B7HGe zBq7gqy!v3qf0nk2VQiR#xjSc=qppwFJk}p21#sNHsbf1>%;YS&z|i<$;XFZ8TIjeD zjY=MTlX7f6z1M8XNhDcbJ;DBhp+7N<^gn*CsBdNW z)Ar?_nyzhQr|pO`eZ_#sC@ATXZ^p831KJb1Zz7alI=mymFr-=j*sN_AF>5cu87}=@ z-m#7@#j_WZThs~qejZ3&44dG8ZOVIrIeKxOL!9IsWW6YCHXEYT&51 zhNYJ2q-;eAvUUP7y9zTIP(&|?GpzUO7t5qg6qZn}ou=kQzUbPSzuA60?YwkhUv&a* zhMz7vEMuE~cuBEtA@5Lpe|Tbe?yBtfT=C(3&7Cs3&Cr&m#ahaucr>%mJx$7W>0c$% zYcqkQcPyJd1l0WrK5vmknLPG8BIvqr(>7H24wU@^-h;QmWcSQy-gteyA|Tnrr3};c z0T_b{TO?lPxBMQ|_Y>0b{5qBo49KIY8JnbQNXAvs(9#O(tRu})EN9~fU{Q+WHrMSh zXwqN%P0HiRrmY4%K8!vuw+~Qx4o6<-M(WxJLl*lR4Gzh=q$GW$(4X6drJpzO24Bal zZc1oLPna6UR5iQb(H-K^o6rZW3znh)$phQo?t{kBPV;Ma}DKTh)V8^=RChquiy;~(=B zfXaUlQ*YVv--z}T_p$p`;&5Wp^2HN6(4Vn$BX4f!OXx_~pku(yds}V`CgI_J44o0< z+w}f5n=<;Lxp0S2nc`K5WqMkAQ4}MAbWL*LYOU*0Enzf4dtoYh%Q1x=2f&R zV8ikO?2xGmS%Eh_Qo+I<6TkfqkRUFiR})uQH9Xf6TiF7O9S!0w0^cksubpiR%5uO; zovuDJ4TdecJqub8y6{y8n{zq)}|4E+z1v>VBk1QbEEqx6$!_dK@w zQA~QMm!b=#`=L$4jsoSfI?u)UPSzj$>oQF>s1JU;RqQxyYUZy%Jg6QhE5?KeSJhmZ zu|@ic^**)Fk6&?G+1Ydr_j4sQy=8uT=4VIQd6U4|n-P?v3GbiGo@X&5m#W=l8Ebzv zp5rqmn8*5#;+IdT8OArLqq0wy`af(+U58V5I)|1Ne==})M=m-AoxAOvzy(hdVpEQ9 zF{WiGSBkvwa`%7ybhV?AefvbHpkB0pL|wiqGZAhpg-prLk@W9FXnNIfR-?{3X5>FsHJQ8 z_c;uFmX4__J8OS8Rl0#IJ=TTz41hUa<_SQ&=dOG z!Eu{5le4=tdB}4p^Sd+L^~fc^c-%Mt8xXQfe+_DN#!Mqo)vy;o=jhIr?0rGgYYd6Y z^ACS!N+V`@V)cs0tw$#bS}OkB*O^mF)GzUeHsNF3rW*UT9_Lc-Fnfk+6~NWQ zzxL*_u+Aj<)ck0ygjP}H@q<+;}%YjPwX21#RJ(3nkBuq_jeNb~s^lhO{Yn=QnHsRBJ zxaFu{?tWI|b2j7VSiZ}1;I_RmbNDpUbom@SxeM2v9i;ROcwpSJA%;zYxKlE=nqZ`x zoa_Rf<9C)M&1x%mPwP*}4Ql6h?L8e%<{}q&=JqM+myh{A(eHbp9h(^G)lVjMlQH$8 zjBQ6xYjamU>Uhv#shV2E%&K8)d|d5es zx6#6BYm_H1%QL@C+6|hJlAyy)f=O17{1g`KmwaZL;>XAKg#jTlRkN^~4GC$?}@qD}yz`L-a;#cvD~& zVjQz^xvME}RBV&aPVD{GJkwD^NcrUVsk-KY#wO|Zy*$ip!#oqD?dYg=HsdRpSeTBY(Y{qZWZnv0}jeT2xZ2e7i zgY*#U&)?NYwB6NEwYF@GQoiPlcj!OliAmwi2#i9X3gPn;ICkAE_fqE+U^(_B488;Q zU3AZkWA=Rd7C9b*>AE^q#;-@+J!F$OEb~X-M)+$|-OLt`&Mlg8WwR%9@t0`VKkTLw zzmg>=V_`7%hHi<=d9tS(GR+o1uRTA&cp9#Bni-y%`K@E%jCtvwm|fHpq0~-J|%7v)~rl#|W zuYbEev5Y}UHQSxVN98zBUxC30q+zMN}&^n(VQ#y-M>AWvi4iS^8Xy; z@J6|#jU=@V=#@}$Sq$M}{rt?mnO^42n`GdAqW8+&fQAmpzysA#K@i82T5&~0mCKy0 z!OL8!p-4)==`i?OX_wzk=vFmdxB!70c=Hcn(qST9E%>X_zws|ip=Zej2#oYR*Z>{0 zvw-8bvqxB4!-=J<4B+mbP4lU}44}QB?d=D=aju6F(%eN=Ko^0oJ4bpGTUDqXR(4YL z*H6m@?xI5}8r5`EfIfo`lOzmbN)BA(hT;iO61`Qx80HnL{bdr3=UpT%o5hZ#YsDM< zjkCA}IqwY%vc8{yS0R*;rf1TS?ZMx&XlX@NnbFH%RdkMA!_YdzsjhV&L3z& z@VS#|uNx<3!3&Goy=k@HdkS>IaSS1W;Do?UTqic-$yxS3Z^0nO^xXMMn@p8Jrm3SU%#&{gA1hoGB#{%S^)>8i}_W#3207G3a zGK}nRL#Yi%qVdpSWv+fS3=lbKc~Fl64R!5&vpSm7;+0cGtM7MhpVz)LX+2LmbQFQY zXkZbYvJMv_!R7x`4FIgE0m)u(>rIsd%MmT3MZmQHXg7LM5pX?ufC3!(yHOU((`!KY zr&3$P3pz=-2b-gg^Zlnss0H&{DMk- zEw`$Us}!m7c!XPuJSH{(x)Hr?wa>*l9$o>um{wfE6|thy9H8rFscxS5_P3R+H&qSx_igVoVbGIs1Pr{f- zIEdsm+7?hSY;7uew5-=OJpg(`gk`5%+nJ`_5Rt)+yf1hub;a6@!pH`imCvFbu7jJX}+ekso^BZwA z7~5{O^&U5v+}$V_|zz$*}`SjN!v?In5gWW(d@ zF;(ukn}c^u_Fsy*MPu;yL7+bfo7|Vbm)r^TI=J{`avmFhyHDWp{Il8t_hdbVrZVAG zoqR;PhB6m4j=>1?z}8O9 zHjb#lwu0nQ9?>e#jTo-+zxeRS{Qv5Cjq9zTE*qreNt9pw0oRTf+-$=o;DDjfvU(pt zvawBza)zjWteD-hTH?viQ>u&bKs)7w zV6A$MH1K6Vw;S`eeshZ5&bwfj3>$%_3q@IJQwT!P-2%=9Q4UEMBIos1DRvdF;wnv8k*ddb&oQZy%PuMd-3V z67{x$j<(SXI&-q{r`DAh=2h5-`1Bi3Co&OS7_WW#Vr-}UWf%#6KJ%IX z_)fDlH)w!+Y3J(JqX@udqcv*h)}5cMf9^S4iotpfHu}5(8ik31@=W$t=lMZ^*H@#1 zanq|v#74^9yiSE0d4)lT*Fb~Di}7C2&;+GX`BvLhpdO!C{9SVjN(Xe)Ol7u_i@)$l zAV7}*ZWb_k*Ootbb=2<-_XmNT6sw|BXh^`qk$_4Sf*=68vR5EJTJ=g8zy)6a{AhwX zcRJas5ak0?K~0Q;sQpW%KyxA?|cC|F693jB09Y)7-0G zJ6I?Jf+#4`dofg7=!jJ5NS7)SdMJXxrC&s(BZ71Rsi6f_nsjNQCUimzNPr-H_6gqa z`)0nGHEYe^`E_#6T5R^&XTNp7@AI5xqc~D%W`X~7Q0Y2uOOF=+{jVc5`2k!90G!e@ z6}a^BNb6w!9mwctqTx4QSdxDM0@=Uqd2BJ2l|P2X9uq!`(1f z24fjWEumvIyW0S?8~G1)@SX@@xi%LCsck^K~lUAEmU4>R9;`Q7&}hKobU7 z-RSekUFK1$b*h^!(4GNRlx0Km%RCBo$uVPfysh%NdKYRig&jn$8)Um)CUo-aisQ9W z@}hkfubw+C8wLS*0V>M80Z772T+PEEQj!j;EOkM4Dwo3367?mEC%#bW7apS*v5~5I zwEP0}xtwR=YktTi)2ZOGDR5-FK9{?720(Q>+@lV39Id=ROZ07DTx6RMALc-FsQXm4 zq&41CI3vmz*kwGqDpE0R%?FC%@&>-3+T0;u1wXZYWN5Fr3`)lL;J^k9Rc#OJ_2;=F zH+rI+Z~M2C^5oUKq9Vo))u=)(K{fgjeq4v6+_Ah6G0j-4$ePlMlJ5Gfp!+(C)#|LbwOzBZe(U@w2L z+&G|UONy(5o0B*F1SfVVnSSs-FalkS-#(pIJLNz&B&8{6+qL(%%l1$3WYPBf zzBv!rN*0{f(l_VVgx>7`Fvr+Z3IYr~Q>e^SEy~(78*Q<<=#o${SJEHk?GvwK+a=%n zRxT(Q&3iNi|LbPZ1fuh&W*ODW$pI&9iRt1(BG9of6GVmuu-8m&jJ}g(!^#9t>E8r! zNg*`Gz%+2V#a&)Yd3*M}p%~(?&%7DgpPKw9D_&K`YS=oJ4M#E5;J)ot_cjzUeG4#1(kcf zFcZL9adM|>M_>2$KpSf;u`_vD`t)2JEjZdd#sr(-=PSpYsouQj;RDR6W&)*oCC_!` z_MrSJfHlvq4$n(Yq%ZX6^Q_pW^wgj+nWRetP+$^4r#2IQKq59SlQgVR9nwtH5m%s(k z-Dk^W@ND3yVZtxp6&*m&}pW(fEbih+7Ij zkOd!OL#_?MgSG}w9Wpl$z~k*IbSyP#cV!!m7s^N?SFMAiNGXmkD&HK;EmxWJJ4Yfm zkBzWTh#tw2H+u2<6IMC#_Y=-htg}*Db$|j2IF~R3JW`h!9GEs5!r8Yi;$LF$S9=3D zLS$--Dt$CBfb0By6y;5;Ai7$3x1lF_Ct6?lH&>403T4W3VJPl}!^pCd+zx8hU$$q- z{T0$gZWIAjWB+VU{bzLc-vBf&2hiVDZ~eF&|5y+Z0s;QR2v;^nh(=;}BhSvNQ!P9C zsR>`l%5GZFBQ00jhRua(%=Gs%!wsK8-X66sIjgy$#Od#RUSrG8s{+K?8(tiE+u5@n zaY^V{g25ryvD*`!?xY@ZOi1w37(suPsEL)jr&O6d{S;iu^Vm8jCt7uKK|15#w|_j)d; z4Rp>*pR(^7=rZLuw|(-sNSn&sqnDPl51M7}d9*L6VaKD1TYJU1jqlv9Nibw@K}yr_ zJ;R|%P+|CpVr`-9!&U8*hHU;4`_DK=s@|t@)TZ2UOJLMLEi4=-qZgB_moPeJ%qIp2 z5>-9y(JL@UeWrPWX3^6c$@o^$464LIb~Y5Bda`3NGR$HTkogYFp>es{wq0u>D`t@O z7DH$WpL!##O$s0^mTo>6b#~$Q8J4zVbw|^V=5+^-6ftE>N?x1WgGVYnm-MIQP3e+j z0lCDh??{8HCs$nhJ}GCfU#!#i)MzwT5RR2A{7s~a#~nhh11ase(iZ#9kE2zV4FsFY z=A}{FL6IVy3IN@GH9P6F@+k^FYJVPg%$BDsqi2omMNec^HJ_GsnZ3Ua)dPK14ww3i7N#z&1k#l)8D-%-F|MxPWD0XF&v^ES@cfR|U8Ms(CO{i(#_ zFCRB~C#f?z*CZ*;->ADxK8uv7ntx)nB&}q`y~RielTpB=sGzlt;M{`xIFV4hr=c$8 zAAm-7=Aqp~bgo219tAszSiYa*5b^=b5}2onZ%i$^k4_EF`kLy=!H2WFo>OZJrD$YW zbuY&+Af*u(SPZ*H*WYLFh&EHw5(yiu_#htk$z>cz|p>ximuP`SNo6ho?r& z$RQCaEUuBvCy#k6*HsF0ShA5(JiC~f0w9_6FaZBt=hGzz+sfo>SN|pPn1=k#16aNZelBDwZ*x{?ER)UEdEo}QB|El1xox=QQ@F`A4nHbo z*6-1YTF)aIefo0Idj-(7^W5&iMN*4m*C!WW5DXgcbhQ9py|pp#M2Nqm$F_whs=_Ac z8tNPD97;s)JLiYJ7gWC`QC2(VJ9n^4DJbgh(ejY}y$J?X$2?psnUcUX_1vbm#-LO2 zi{_l3+x^e{$K4Ld{K}hZ>S(Rd6weN-^kd>pR-RI@Q`bS(Brdah;W@$JvP9T34&Hu! z_66hk$Kh|CdS7Euc}ECw=`K*X)w8fuoS15QANMVB(3vPXdcxc~ z62pd~cMbmT{~>rEOFtMQfdw49S0ryk(1Y15vSRqQgr1WqEq{khwPZ(!n|(1=EwB0L z%;nq!6z06_6fTv8I|XpKpp7Kr?ne$)0WCDccGfT7B=`rvl?#hKEaoBWy@@%h&i?F4T$!tZBkMM3plVE=H)NI4)4cnd^O}9)5Z?G$Ivv)#C$h2 zP$YxvdC0J8<6GA;zk*8ZAa(7&76oXlNu_7TCQ;p(jv zlGE)`D5##e75Z=aJU^(=7=&82A139==HrT)nE2lfNOJ$c$NS%ybx#GiB7!-O;tgxj z8{|eBtz3tjH{GmMA_?UFEebz)#z1Fd5>2=CQG1eg;ID2VlaJxr{ARr|GoUm3@8~7t zqHV%^XDjo}w3wH?D?=X8m!Y6=VWsW(o{>n+mLK!d;lr{d`JrER4+xyL)l(f(j&J;2 zc++Sq(CRRHl+BocGb9}cWbX>=hs5@CW8~DrXBAP=FXs~472*4Q9umyII-SINtxpK; zVOSHExtrN&mBQ?_0ByO|QB1_h@$U^Hv%MiQed^SYh`}dIB%fIw#c;w`qJPC&vX0H{ zzn0POpW)I)5b2K5!-ny1J~9pKl4nm58GXibnG6jYZ4=9uMt+!9{{KBl{33+r32@)P zU31=Me5c($JxVUP9++K@a#b{8bDzA?(uRjl3QeJ6NRK}!tu1GSEdXSp?6u7p)HJDQ zd$TqQ7zjfm(Y;IhS|}MBNskBgri6t4q3J2QpkU6IZDql4MaD*cjx~sKxRo`;BzoWWGwOa|0b4uKG_6I7}TRLnhapaFP0i1+pgS&ZN?ODIS8_5Bwyic4( zH6rE~RuZ-~4}=ljpRf!z7Fo9P-ae*HbOH^Hf6Vr*Fx2%8+!$fH0mW*J9Q)tOOl}L8 zy*^c~wsB{}Zqyq=AX8^%mEZwW(P2GWV(1y8*Dl50oaoTY9O2xN69#`gj)wK3e*2OY zCmZxot21xWKS;@>?~JJLGftYo_SnrR!6@TIOMqHI3JkvGwpmGpME#mIIkJ0CBAd=zJj^18~nK5UbV z2JiYD`-YAJ8`iwkBu=31yCE%F1jDQ|Iwd=<@(=XNDatV?NPGKGyc(&ut+Jza)eeqI?Zp=oWa;{6?dJzwK@CNFCG zN$6QdBi|8)41U^lqgSlCpXQ~SQ_n?E(7!w2dWtRqxQP?RNksmP%bo1|xtAo?7R^yP z90H7ttJ>+McXXC_FBPdrgqP4ct}|SAZqf{!G>yG%eyHLaTQt?}71<`=XQ+;jg7?(D z7tN}WsTmnW;yBSk@C9ZaH@24z2rQUM2`=WBF!kd)^UR~0)JS;5CL9eQ| zHhg`3Jw73!)lJiQ5g}%_W)ZEKQU*>=?j^` z!hQCaHaOq`rv$;XZ>NNE{4$3C5X2eiHh%HhEpYiPEGP)+&K&Bee}Ib`M=X_47fvQZ z&t8O*DCX6lUg4v*>~Up#D`Hxr&c3B@uiA_G1Jkx!zo|<-@*sHASOz-9VSd*ZOke8D zO>HZ+iQhCO42JWRRc4%g)`FA@>e{gr2&J z`&6hQX+xz&IHop6nsIZ|2eBzBFR@tsgap^Q}JaRa@;d*tk+Y8OH1F3 zeUE%OReK-5`+h^QZ+a-cTU!a=EoW4V3)|7IK{+P-^h24jpAR(*DauN#E{Cxbo@|eV zH$Uc5MJ@K+S$uekW7%37uzyL48;*y-&v4I)O^JJV9oT;?Ke-zWo4uB_Hf!kU0nkSOx4#Rc2VQV)>y-Cm5VF63qr=K<6-x@(g7RN_KWb{n7<&byBj~W%Xc&B{N zvbN0|y~Oud-IYr{xoNLMk-BCl>vB ztG<-a2Otv1ct}i*i<^n`GDHm#AqPQ5-@-vN$L&euft{3erUnrxR-ag5CVUIeqyj3+ zvV*2ix$f*4qgtjB-|VifFswKh77jm5ZV&E(4HHx(T1lBZ3~298Bc7y9zQImKag5=+@Q1aK`r zKk{f45&Bt_DfX@3#vjsgJ`vH7<06}Rg`9@g3?*k;|5Z3VAKuiNX7N>m^Vlq%Y)W0C zG%Y6ySJcy7^Nj=jM_SqUi(c+qJREJ=-0AQ5;(3T%sKc%el*v5bvJ&BK+L|efLwA?@ z#*ZuF4vJCRB-{Pf)jMD!4f)7;f!&sS#TX4=BR)))LJ=zrM=|3%xH|pyTKxejI_cfO zpOhYFynXH@Cx9>HfT$rn;ix#5^q1e#Z&Hzm0GHvjnGjQ-aw-p8YN-+vylWq`(By!r zT4`Phn_7QDokGfpu(J=RCDt&6b%%COt7Te=@QeZ67LztjnGX3$*`5&No$nFT^=;T~ z9CZjzH~_v(qrXecrQYAapFz>qce(d<&_Wz?G%`EDdzRzMLS=R_+IU1peAQlqx!1*V z{IT-g);Lp`tYhM51L1o3GEbDaPoscNVR=S>GXe)BQEAJnGNRO%Np7n_U9Uah_0pu$ zYW2#Uyh)6eOAT%-q8dXKI;dk3Taen_NSc4J-g>^pr@9)om1wEqb8A>oGCfPf^H#&S zn=@lf(mM;?LounJUB;DARwBkG^sHZ&ssrnkbE4&sea(P=Cp&2w9+Jy6!ke98pK|FS z$(pz9!@6YH6M7`x$*zMgn1)qK6;=4?ntaN5)sSwzjhWYbdgsi~8KuKl$KH`f zjD%a%=%(?p_XF*8c^^L7%@=U%XDG|qy^}6r-J-rsLRqyhU?x*WqG2So)#E6P!r{+e zXVt;=_wLN>1%Gymxt&oUvY2guLUh^QRU;YH*Dl##tHz@$inq9fePUSQlOI?zE~0&f zaM2KqWsHSqL-;;+$O{vSVwG^QTI&v0#U#9AM5N+HOS|P#a4S2e{W78@gz>}J!{t6z z1ZD)~N~?q0lt|2w6A6Fok|(nnr5`#_u8QQ~#pBIed<{diIjnVe>SO0=0aEo1%uWr^WZJ3OleeBs1h4{^8YdZ4!AnKdK@r{xM=Qu}&WPjxvq zI@Q^WxUP52BIrUs`sY99Xi^VX7WW$e)3Pk|B2NZ9N3%u6ey?~#-=XE}+!%nor3E^} zEdj^R8d3PO`tsq-^#?mk-c^=x&Y+=?x%O*lo(!?T_l68N1$K#A{b3v|RCA-Q!oV9? zGxxSGJE(^YE%_CstO_m4y|e#Jl|%R*AK*KU*$au+*7{=G4#{sJ$M-^ zJ*R=6&KS43sJg-9JwH$yzeKgv{r14PJou~tY4O6jtk4gS8Q;+bElP|Ph@01|SyauN zS552Y(XW}a8>PHi5;Gs%b;}$5{*Kn!#o$n{ZzJ@Ja9}OwUgA{muC4cKyisQ$C#|2d zhMu~22pkuQ>#fHx)NN!P&m?p{8ROJp+wPI-Ug@ccRew6b`1RGUdvVer;kNOTAzWz; z)4cl5q9UA=LT|?&mu~_b2HB>5US8hnXR}12U{`mynWg2e@h`p{F4d)xKU>9Z)xc)^ zjPL}y68!MvyhP4R#F{2T2k2@X@T1!s9pH|F)8gLO@B=R4_9Akw_b2YvD|)5kQ38Bx z{hqL~LyK-Pgg-q|-I{2rZXE7e3`Kk5}(c$_ZzWZ_8%ktTB!f?3je?R!!sd2eHqd* WC9Q1i55R&_C_GesP{U literal 0 HcmV?d00001 diff --git a/app_python/docs/screenshots/02-health-check.png b/app_python/docs/screenshots/02-health-check.png new file mode 100644 index 0000000000000000000000000000000000000000..321da884509116354b02fdef84398862741ade84 GIT binary patch literal 11296 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 literal 0 HcmV?d00001 diff --git a/app_python/docs/screenshots/03-formatted-output.png b/app_python/docs/screenshots/03-formatted-output.png new file mode 100644 index 0000000000000000000000000000000000000000..bd76d10670db1ebaaa117ef4380dd37987cd0289 GIT binary patch literal 55725 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.110 +uvicorn[standard]>=0.27 \ No newline at end of file diff --git a/app_python/tests/__init__.py b/app_python/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 2601ee15ecd8b90c049f9e844b67718717e5b1c4 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Sun, 25 Jan 2026 20:03:17 +0300 Subject: [PATCH 02/40] fix: minor fixes --- app_python/README.md | 8 ++++---- app_python/app.py | 6 +++--- app_python/docs/LAB01.md | 18 +++++++++--------- app_python/requirements.txt | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app_python/README.md b/app_python/README.md index 32d32ac023..74ffca1c2b 100644 --- a/app_python/README.md +++ b/app_python/README.md @@ -35,7 +35,7 @@ PORT=8080 python app.py The application is configured using environment variables. -| Variable | Default | Description | Example | -|---------|---------|-------------|---------| -| `HOST` | `127.0.0.1` | Host interface to bind the server to | `0.0.0.0` | -| `PORT` | `8000` | Port the server listens on | `8080` | \ No newline at end of file +| Variable | Default | Description | Example | +|---------|---------|-------------|-------------| +| `HOST` | `0.0.0.0` | Host interface to bind the server to | `127.0.0.1` | +| `PORT` | `8000` | Port the server listens on | `8080` | \ No newline at end of file diff --git a/app_python/app.py b/app_python/app.py index a1e16fe273..8cd20e0680 100644 --- a/app_python/app.py +++ b/app_python/app.py @@ -17,7 +17,7 @@ # Configuration HOST = os.getenv("HOST", "0.0.0.0") -PORT = int(os.getenv("PORT", 5000)) +PORT = int(os.getenv("PORT", 8000)) DEBUG = os.getenv("DEBUG", "False").lower() == "true" logging.basicConfig( @@ -47,7 +47,7 @@ def get_system_info(): return { "hostname": socket.gethostname(), "platform": platform.system(), - "platformVersion": platform.version(), + "platform_version": platform.version(), "architecture": platform.machine(), "cpu_count": os.cpu_count(), "python_version": platform.python_version(), @@ -156,7 +156,7 @@ async def unhandled_exception_handler(request: Request, exc: Exception): if __name__ == "__main__": - """The entry point.""" + # The entry point logger.info('Application starting...') uvicorn.run("app:app", host=HOST, port=PORT, reload=True) diff --git a/app_python/docs/LAB01.md b/app_python/docs/LAB01.md index 3c073f4777..1d43f6863d 100644 --- a/app_python/docs/LAB01.md +++ b/app_python/docs/LAB01.md @@ -183,9 +183,9 @@ async def root(request: Request): ## 4. Dependencies (requirements.txt) The project keeps dependencies minimal and focused on what is required to run a FastAPI service in production. ### requirements.txt -``` -fastapi>=0.110 -uvicorn[standard]>=0.27 +```txt +fastapi==0.122.0 +uvicorn[standard]==0.38.0 ``` **Why it matters**: - Faster builds & simpler setup: fewer packages mean faster installation and fewer moving parts. @@ -226,7 +226,7 @@ The service exposes two endpoints: the main information endpoint and a health ch Returns comprehensive metadata about the service, system, runtime, request details, and available endpoints. **Request example:** ```bash -curl -i http://127.0.0.1:5000/ +curl -i http://127.0.0.1:8000/ ``` **Response example (200 OK):** ```json @@ -235,7 +235,7 @@ curl -i http://127.0.0.1:5000/ "name": "devops-info-service", "version": "1.0.0", "description": "DevOps course info service", - "framework": "Flask" + "framework": "FastAPI" }, "system": { "hostname": "my-laptop", @@ -267,7 +267,7 @@ curl -i http://127.0.0.1:5000/ **Description:** Returns a simple status response to confirm the service is running.**Request example:** ```bash -curl -i http://127.0.0.1:5000/health +curl -i http://127.0.0.1:8000/health ``` **Response example (200 OK):** ```json @@ -280,12 +280,12 @@ curl -i http://127.0.0.1:5000/health ## Testing commands ### Basic tests ```bash -curl http://127.0.0.1:5000/ -curl http://127.0.0.1:5000/health +curl http://127.0.0.1:8000/ +curl http://127.0.0.1:8000/health ``` ### Test 404 handling (unknown endpoint) ```bash -curl -i http://127.0.0.1:5000/does-not-exist +curl -i http://127.0.0.1:8000/does-not-exist ``` Expected response (404): ```json diff --git a/app_python/requirements.txt b/app_python/requirements.txt index c0d860c195..94a41a1968 100644 --- a/app_python/requirements.txt +++ b/app_python/requirements.txt @@ -1,2 +1,2 @@ -fastapi>=0.110 -uvicorn[standard]>=0.27 \ No newline at end of file +fastapi==0.122.0 +uvicorn[standard]==0.38.0 From 1bde0adbfa60149fe525a77b1c7e2f0c66b5d5d4 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Sun, 25 Jan 2026 20:34:54 +0300 Subject: [PATCH 03/40] feat: lab01 bonus task completed --- app_go/.gitignore | 18 ++ app_go/README.md | 43 +++ app_go/docs/GO.md | 5 + app_go/docs/LAB01.md | 217 ++++++++++++++ app_go/docs/screenshots/01-main-endpoint.png | Bin 0 -> 44356 bytes app_go/docs/screenshots/02-health-check.png | Bin 0 -> 8540 bytes .../docs/screenshots/03-formatted-output.png | Bin 0 -> 14355 bytes app_go/go.mod | 3 + app_go/main.go | 277 ++++++++++++++++++ 9 files changed, 563 insertions(+) create mode 100644 app_go/.gitignore create mode 100644 app_go/README.md create mode 100644 app_go/docs/GO.md create mode 100644 app_go/docs/LAB01.md create mode 100644 app_go/docs/screenshots/01-main-endpoint.png create mode 100644 app_go/docs/screenshots/02-health-check.png create mode 100644 app_go/docs/screenshots/03-formatted-output.png create mode 100644 app_go/go.mod create mode 100644 app_go/main.go diff --git a/app_go/.gitignore b/app_go/.gitignore new file mode 100644 index 0000000000..d6c75d54e3 --- /dev/null +++ b/app_go/.gitignore @@ -0,0 +1,18 @@ +# Go binaries / build output +devops-info-service +*.exe +*.out +*.test +bin/ +dist/ + +# IDE/editor +.vscode/ +.idea/ + +# OS files +.DS_Store +Thumbs.db + +# Logs +*.log \ No newline at end of file diff --git a/app_go/README.md b/app_go/README.md new file mode 100644 index 0000000000..e53cc9a7e6 --- /dev/null +++ b/app_go/README.md @@ -0,0 +1,43 @@ +# devops-info-service (Go) + +## Overview +`devops-info-service` is a lightweight HTTP service written in Go. It returns: +- service metadata (name, version, description, framework), +- system information (hostname, OS/platform, architecture, CPU count, Go version), +- runtime information (uptime, current UTC time), +- request information (client IP, user-agent, method, path), +- a list of available endpoints. + +This is useful for DevOps labs and basic observability: quick environment inspection and health checks. + +--- + +## Prerequisites +- **Go:** 1.22+ (recommended) +- No external dependencies (standard library only) + +--- + +## Installation +```bash +cd app_go +go mod tidy +``` + +## Running the Application +```bash +go run . +``` + +## API Endpoints +- `GET /` - Service and system information +- `GET /health` - Health check + +## Configuration + +The application is configured using environment variables. + +| Variable | Default | Description | Example | +|---------|---------|-------------|---------| +| `HOST` | `0.0.0.0` | Host interface to bind the server to | `0.0.0.0` | +| `PORT` | `8080` | Port the server listens on | `8080` | \ No newline at end of file diff --git a/app_go/docs/GO.md b/app_go/docs/GO.md new file mode 100644 index 0000000000..39785012a7 --- /dev/null +++ b/app_go/docs/GO.md @@ -0,0 +1,5 @@ +### Why Go? +- **Compiled binary**: produces a single executable (useful for multi-stage Docker builds). +- **Fast startup and low overhead**: good for microservices. +- **Standard library is enough**: `net/http` covers routing and HTTP server without external frameworks. +- **Great DevOps fit**: simple deployment, small runtime requirements. diff --git a/app_go/docs/LAB01.md b/app_go/docs/LAB01.md new file mode 100644 index 0000000000..52920f06bc --- /dev/null +++ b/app_go/docs/LAB01.md @@ -0,0 +1,217 @@ +# Lab 1 (Bonus) — DevOps Info Service in Go + +## 1. Language / Framework Selection + +### Choice +I implemented the bonus service in **Go** using the standard library **net/http** package. + +### Why Go? +- **Compiled binary**: produces a single executable (useful for multi-stage Docker builds). +- **Fast startup and low overhead**: good for microservices. +- **Standard library is enough**: `net/http` covers routing and HTTP server without external frameworks. +- **Great DevOps fit**: simple deployment, small runtime requirements. + +### Comparison with Alternatives + +| Criteria | Go (net/http) (chosen) | Rust | Java (Spring Boot) | C# (ASP.NET Core) | +|---------|--------------------------|------|---------------------|-------------------| +| Build artifact | Single binary | Single binary | JVM app + deps | .NET app + deps | +| Startup time | Fast | Fast | Usually slower | Medium | +| Runtime deps | None | None | JVM required | .NET runtime | +| HTTP stack | stdlib | frameworks (Axum/Actix) | Spring ecosystem | ASP.NET stack | +| Complexity | Low | Medium–high | Medium | Medium | +| Best fit for this lab | Excellent | Good | Overkill | Good | + +--- + +## 2. Best Practices Applied + +### 2.1 Clean Code Organization +- Clear data models (`ServiceInfo`, `Service`, `System`, `RuntimeInfo`, `RequestInfo`, `Endpoint`). +- Helper functions for concerns separation: + - `runtimeInfo()`, `requestInfo()`, `uptime()`, `isoUTCNow()`, `clientIP()`, `writeJSON()`. + +### 2.2 Configuration via Environment Variables +The service is configurable via environment variables: +- `HOST` (default `0.0.0.0`) +- `PORT` (default `8080`) +- `DEBUG` (default `false`) + +Implementation uses a simple helper: +```go +func getenv(key, def string) string { + v := os.Getenv(key) + if v == "" { + return def + } + return v +} +``` + +### 2.3 Logging Middleware +Request logging is implemented as middleware: +```go +func withLogging(logger *log.Logger) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + next.ServeHTTP(w, r) + logger.Printf("%s %s (%s) from %s in %s", + r.Method, r.URL.Path, r.Proto, r.RemoteAddr, time.Since(start)) + }) + } +} +``` + +### 2.4 Error Handling +#### 404 Not Found +Unknown endpoints return a consistent JSON error: +```json +{ + "error": "Not Found", + "message": "Endpoint does not exist" +} +``` +This is implemented via a wrapper that enforces valid paths: +```go +func withNotFound(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/" && r.URL.Path != "/health" { + writeJSON(w, http.StatusNotFound, ErrorResponse{ + Error: "Not Found", + Message: "Endpoint does not exist", + }) + return + } + next.ServeHTTP(w, r) + }) +} +``` +#### 500 Internal Server Error (panic recovery) +A recover middleware prevents crashes and returns a safe JSON response: +```go +func withRecover(logger *log.Logger) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer func() { + if rec := recover(); rec != nil { + logger.Printf("panic recovered: %v", rec) + writeJSON(w, http.StatusInternalServerError, ErrorResponse{ + Error: "Internal Server Error", + Message: "An unexpected error occurred", + }) + } + }() + next.ServeHTTP(w, r) + }) + } +} +``` +### 2.5 Production-Friendly HTTP Server Settings +The service uses `http.Server` with timeouts: +```go +srv := &http.Server{ + Addr: addr, + Handler: handler, + ReadHeaderTimeout: 5 * time.Second, +} +``` +## 3. API Documentation +### 3.1 GET / — Service and System Information +**Description**: Returns service metadata, system info, runtime info, request info, and available endpoints. + +**Request**: +```bash +curl -i http://127.0.0.1:8080/ +``` +**Response (200 OK) example**: +```json +{ + "service": { + "name": "devops-info-service", + "version": "1.0.0", + "description": "DevOps course info service", + "framework": "Go net/http" + }, + "system": { + "hostname": "DESKTOP-KUN1CI4", + "platform": "windows", + "platform_version": "unknown", + "architecture": "amd64", + "cpu_count": 8, + "go_version": "go1.25.6" + }, + "runtime": { + "uptime_seconds": 6, + "uptime_human": "0 hours, 0 minutes", + "current_time": "2026-01-25T17:17:32.248Z", + "timezone": "UTC" + }, + "request": { + "client_ip": "::1", + "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36 Edg/144.0.0.0", + "method": "GET", + "path": "/" + }, + "endpoints": [ + { + "path": "/", + "method": "GET", + "description": "Service information" + }, + { + "path": "/health", + "method": "GET", + "description": "Health check" + } + ] +} +``` +### 3.2 GET /health — Health Check +**Description**: Description: Simple health endpoint used for monitoring and probes. + +**Request**: +```bash +curl -i http://127.0.0.1:8080/health +``` +**Response (200 OK) example**: +```json +{ + "status": "healthy", + "timestamp": "2026-01-25T17:19:02.582Z", + "uptime_seconds": 96 +} +``` +### 3.3 404 Behavior +**Request**: +```bash +curl -i http://127.0.0.1:8080/does-not-exist +``` +**Response (404 Not Found)**: +```json +{ + "error": "Not Found", + "message": "Endpoint does not exist" +} +``` + +## 4. Build & Run Instructions +### 4.1 Run locally (no build) +```bash +go run main.go +``` +### 4.2 Build binary +```bash +go build -o devops-info-service main.go +``` +Run: +```bash +./devops-info-service +``` +### 4.3 Environment variables examples +```bash +HOST=127.0.0.1 PORT=3000 ./devops-info-service +DEBUG=true PORT=8081 ./devops-info-service +``` +## 5. Challenges & Solutions +I don't know how `go` works. diff --git a/app_go/docs/screenshots/01-main-endpoint.png b/app_go/docs/screenshots/01-main-endpoint.png new file mode 100644 index 0000000000000000000000000000000000000000..c0f1b2ed5c567e9a28506ba411e332f351df7a73 GIT binary patch literal 44356 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 literal 0 HcmV?d00001 diff --git a/app_go/docs/screenshots/02-health-check.png b/app_go/docs/screenshots/02-health-check.png new file mode 100644 index 0000000000000000000000000000000000000000..aed7a379187856f47ca59651519055fd113e1221 GIT binary patch literal 8540 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 Date: Sun, 1 Feb 2026 13:39:27 +0300 Subject: [PATCH 04/40] feat: LAB02 done --- app_python/.dockerignore | 22 ++++ app_python/Dockerfile | 14 +++ app_python/README.md | 27 ++++- app_python/docs/LAB02.md | 243 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 app_python/.dockerignore create mode 100644 app_python/Dockerfile create mode 100644 app_python/docs/LAB02.md diff --git a/app_python/.dockerignore b/app_python/.dockerignore new file mode 100644 index 0000000000..44fa25304b --- /dev/null +++ b/app_python/.dockerignore @@ -0,0 +1,22 @@ +# 🐙 Version control +.git +.gitignore + +# 🐍 Python +__pycache__ +*.pyc +*.pyo +venv/ +.venv/ + +# 🔐 Secrets (NEVER include!) +.env +*.pem +secrets/ + +# 📝 Documentation +*.md +docs/ + +# 🧪 Tests (if not needed in container) +tests/ \ No newline at end of file diff --git a/app_python/Dockerfile b/app_python/Dockerfile new file mode 100644 index 0000000000..0364cfd9a7 --- /dev/null +++ b/app_python/Dockerfile @@ -0,0 +1,14 @@ +FROM python:3.12-slim + +RUN useradd --create-home --shell /bin/bash appuser + +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY app.py . + +EXPOSE 8000 + +USER appuser + +CMD ["python", "app.py"] \ No newline at end of file diff --git a/app_python/README.md b/app_python/README.md index 74ffca1c2b..2475567ab9 100644 --- a/app_python/README.md +++ b/app_python/README.md @@ -38,4 +38,29 @@ The application is configured using environment variables. | Variable | Default | Description | Example | |---------|---------|-------------|-------------| | `HOST` | `0.0.0.0` | Host interface to bind the server to | `127.0.0.1` | -| `PORT` | `8000` | Port the server listens on | `8080` | \ No newline at end of file +| `PORT` | `8000` | Port the server listens on | `8080` | + +# Docker + +## Building the image locally +Command pattern: +```bash +docker build -t : +``` + +## Running a container +Command pattern: +```bash +docker run --rm -p : : +``` + +## Pulling from Docker Hub +Command pattern: +```bash +docker pull /: +``` +Then run: +```bash +docker run --rm -p : /: +``` + diff --git a/app_python/docs/LAB02.md b/app_python/docs/LAB02.md new file mode 100644 index 0000000000..977e742f10 --- /dev/null +++ b/app_python/docs/LAB02.md @@ -0,0 +1,243 @@ +# Docker Best Practices Applied + +## 1. Non-root user +**What I did:** +Created a dedicated user (`appuser`) and ran the container as that user. + +**Why it matters**: +Running as root in a container increases the impact of a container escape or a vulnerable dependency. A non-root user reduces privileges and limits potential damage. + +**Dockerfile snippet:** +```dockerfile +RUN useradd --create-home --shell /bin/bash appuser +USER appuser +``` + +## 2. Layer caching +**What I did:** +Copied `requirements.txt` first and installed dependencies before copying the rest of the source code. + +**Why it matters**: +Docker caches layers. Dependencies change less frequently than application code, so separating them allows rebuilds to reuse the cached dependency layer and rebuild faster. + +**Dockerfile snippet:** +```dockerfile +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY app.py . +``` + +## 3. .dockerignore +**What I did:** +Added .dockerignore to exclude local artifacts such as venvs, caches, and IDE folders. + +**Why it matters**: +Docker sends the build context to the daemon. Excluding unnecessary files makes builds faster, reduces image bloat, and prevents leaking local secrets/files into the build. + +**.dockerignore snippet:** +```.dockerignore +# 🐙 Version control +.git +.gitignore + +# 🐍 Python +__pycache__ +*.pyc +*.pyo +venv/ +.venv/ + +# 🔐 Secrets (NEVER include!) +.env +*.pem +secrets/ + +# 📝 Documentation +*.md +docs/ + +# 🧪 Tests (if not needed in container) +tests/ +``` + +## 4. Minimal base image +**What I did:** +Used `python:3.12-slim`. + +**Why it matters**: +Smaller images generally mean fewer packages, fewer vulnerabilities, less bandwidth and faster pulls/deployments. + +**dockerfile snippet:** +```dockerfile +FROM python:3.12-slim +``` + +# Image Information & Decisions +## Base image chosen and justification (why this specific version?) +**Base image**: +`python:3.12-slim` + +**Justification**: +- Python 3.12 matches the project runtime requirements. +- slim variant keeps image smaller and reduces OS packages. +- Official Python images are widely used and well maintained. + +## Final image size and my assessment +**Image size**: +`195MB` + +**My assessment**: +Further optimization is possible (multi-stage build, wheels caching, removing build deps), but for this lab the size is acceptable. + +## Layer structure explanation +1. Base image layer (`python:3.12-slim`) +2. User creation layer +3. `WORKDIR` and `requirements.txt` copy layer +4. pip install dependencies layer (largest and most valuable for caching) +5. Application source copy layer +6. EXPOSE, USER, and CMD metadata layers + +## Optimization choices +- Used dependency-first copying to maximize caching. +- Used `--no-cache-dir` with pip to reduce layer size. +- Used slim base image to reduce OS footprint. +- Added `.dockerignore` to reduce build context. + +# Build & Run Process +## Complete terminal output from build process +```bash + docker build -t python_app:1.0 . +[+] Building 5.4s (12/12) FINISHED docker:desktop-linux + => [internal] load build definition from Dockerfile 0.0s + => => transferring dockerfile: 277B 0.0s + => [internal] load metadata for docker.io/library/python:3.12-slim 3.7s + => [auth] library/python:pull token for registry-1.docker.io 0.0s + => [internal] load .dockerignore 0.0s + => => transferring context: 289B 0.0s + => [1/6] FROM docker.io/library/python:3.12-slim@sha256:5e2dbd4bbdd9c0e67412aea9463906f74a22c60f89e 0.0s + => [internal] load build context 0.1s + => => transferring context: 62.28kB 0.1s + => CACHED [2/6] RUN useradd --create-home --shell /bin/bash appuser 0.0s + => CACHED [3/6] WORKDIR /app 0.0s + => CACHED [4/6] COPY requirements.txt . 0.0s + => CACHED [5/6] RUN pip install --no-cache-dir -r requirements.txt 0.0s + => [6/6] COPY app.py . 0.8s + => exporting to image 0.4s + => => exporting layers 0.3s + => => writing image sha256:a3d1dd41a468a1bb53d02edd846964c240eb160f49fd28e9f6ad90fc15677c52 0.0s + => => naming to docker.io/library/python_app:1.0 0.0s + +View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/djiu836gkk9g7syuakivz5ynt +``` + +## Terminal output showing container running +```bash + docker run --rm -p 8000:8000 python_app:1.0 +2026-01-31 18:29:56,977 - __main__ - INFO - Application starting... +INFO: Will watch for changes in these directories: ['/app'] +INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) +INFO: Started reloader process [1] using WatchFiles +INFO: Started server process [8] +INFO: Waiting for application startup. +INFO: Application startup complete. +``` + +## Terminal output from testing endpoints +```bash +curl http://localhost:8000/ + + StatusCode : 200 +StatusDescription : OK +Content : {"service":{"name":"devops-info-service","version":"1.0.0","description":"DevOps cours + e info service","framework":"FastAPI"},"system":{"hostname":"3a77a23940f7","platform": + "Linux","platform_version":"... +RawContent : HTTP/1.1 200 OK + Content-Length: 755 + Content-Type: application/json + Date: Sat, 31 Jan 2026 18:31:18 GMT + Server: uvicorn + +Forms : {} +Headers : {[Content-Length, 755], [Content-Type, application/json], [Date, Sat, 31 Jan 2026 18:3 + 1:18 GMT], [Server, uvicorn]} Images : {} InputFields : {} Links : {} +ParsedHtml : mshtml.HTMLDocumentClass +RawContentLength : 755 +``` + +```bash +curl http://localhost:8000/health + + +StatusCode : 200 +StatusDescription : OK +Content : {"status":"healthy","timestamp":"2026-01-31T18:31:26.924513+00:00","uptime_seconds":89 + } +RawContent : HTTP/1.1 200 OK + Content-Length: 87 + Content-Type: application/json + Date: Sat, 31 Jan 2026 18:31:26 GMT + Server: uvicorn + + {"status":"healthy","timestamp":"2026-01-31T18:31:26.924513+00:00","uptime_... +Forms : {} +Headers : {[Content-Length, 87], [Content-Type, application/json], [Date, Sat, 31 Jan 2026 18:31 + :26 GMT], [Server, uvicorn]} +Images : {} +InputFields : {} +Links : {} +ParsedHtml : mshtml.HTMLDocumentClass +RawContentLength : 87 +``` + +## Terminal output showing successful push: +```bash +docker push newspec/python_app:1.0 + +The push refers to repository [docker.io/newspec/python_app] +8422fdf98022: Pushed +56a7b3684a2c: Pushed +410b7369101c: Pushed +4e7298e95b69: Pushed +b68196304589: Pushed +343fbb74dfa7: Pushed +cfdc6d123592: Pushed +ff565e4de379: Pushed +e50a58335e13: Pushed +1.0: digest: sha256:9084f1513bc5af085a268ee9e8b165af82f7224e442da0790cf81f07b67ab10e size: 2203 + +``` + +## Docker Hub repository URL +`https://hub.docker.com/repository/docker/newspec/python_app` + +## My tagging strategy +`:1.0`(major/minor) + +# Technical analysis +## Why does your Dockerfile work the way it does? +- The image is based on a minimal Python runtime. +- Dependencies are installed before application code to leverage Docker layer caching. +- The app runs as a non-root user for better security. + +## What would happen if you changed the layer order? +If the Dockerfile copied the entire project (`COPY . .`) before installing requirements, then any code change would invalidate the cache for the dependency install layer. That would force `pip install` to run again on every rebuild, making builds much slower. + +## What security considerations did you implement? +- Non-root execution reduces privilege. +- Smaller base image reduces attack surface. +- `.dockerignore` prevents accidentally shipping local files (including potential secrets) into the image. + +## How does .dockerignore improve your build? +- Reduces build context size (faster build, less IO). +- Avoids copying local venvs and cache files into the image. +- Prevents leaking IDE configs, git history, logs, and other irrelevant files. + +## Challenges & Solutions +# 1. “I cannot open my application” after `docker run` +**Fix**: Published the port with `-p 8000:8000` + +# What I Learned +- Containers need explicit port publishing to be accessible from the host. +- Layer ordering dramatically affects build speed due to caching. +- Running as non-root is a simple but important security improvement. +- .dockerignore is crucial to keep images clean and builds fast. \ No newline at end of file From 26a6262c41cc98767451a8016ba79a51ea54d67d Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Sun, 1 Feb 2026 15:14:18 +0300 Subject: [PATCH 05/40] feat: lab02 bonus task is done --- app_go/.dockerignore | 9 ++ app_go/Dockerfile | 14 +++ app_go/docs/LAB02.md | 215 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+) create mode 100644 app_go/.dockerignore create mode 100644 app_go/Dockerfile create mode 100644 app_go/docs/LAB02.md diff --git a/app_go/.dockerignore b/app_go/.dockerignore new file mode 100644 index 0000000000..52c65fe81d --- /dev/null +++ b/app_go/.dockerignore @@ -0,0 +1,9 @@ +.git +*.md +docs/ +bin/ +dist/ +tmp/ +.idea/ +.vscode/ +.DS_Store \ No newline at end of file diff --git a/app_go/Dockerfile b/app_go/Dockerfile new file mode 100644 index 0000000000..6dd906a964 --- /dev/null +++ b/app_go/Dockerfile @@ -0,0 +1,14 @@ +# 🔨 Stage 1: Builder +FROM golang:1.22-alpine AS builder +WORKDIR /app +COPY go.mod ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 go build -o myapp + +# 🚀 Stage 2: Runtime +FROM gcr.io/distroless/static-debian12:nonroot +WORKDIR /app +COPY --from=builder /app/myapp . +EXPOSE 8080 +CMD ["./myapp"] \ No newline at end of file diff --git a/app_go/docs/LAB02.md b/app_go/docs/LAB02.md new file mode 100644 index 0000000000..ee98527851 --- /dev/null +++ b/app_go/docs/LAB02.md @@ -0,0 +1,215 @@ +# Multi-stage build strategy +## Stage 1 - Builder +**Purpose:** compile the Go application using a full Go toolchain image. + +**Key points:** +- Uses `golang:1.22-alpine` to keep the builder stage smaller than Debian-based images. +- Copies `go.mod` first and runs `go mod download` to maximize Docker layer caching. +- Builds a Linux binary with `CGO_ENABLED=0` (static binary), which allows a minimal runtime image. + +**Dockerfile snippet:** +```dockerfile +FROM golang:1.22-alpine AS builder +WORKDIR /app +COPY go.mod ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 go build -o myapp +``` + +## Stage 2 - Runtime +**Purpose:** run only the compiled binary in a minimal image with a non-root user. + +**Key points:** +- Uses `gcr.io/distroless/static-debian12:nonroot`. +- Distroless images contain only what is required to run the app (no package manager, no shell), reducing image size and attack surface. +- Runs as a **non-root** user (provided by the `:nonroot` tag). + +**Dockerfile snippet:** +```dockerfile +FROM gcr.io/distroless/static-debian12:nonroot +WORKDIR /app +COPY --from=builder /app/myapp . +EXPOSE 8080 +CMD ["./myapp"] +``` + +# Size comparison with analysis (builder vs final image) +## Builder +```bash +docker images newspec/app_go:builder +REPOSITORY TAG IMAGE ID CREATED SIZE +newspec/app_go builder 21b01f8c6103 37 minutes ago 305MB +``` +## Final +```bash +docker images newspec/app_go:1.0 +REPOSITORY TAG IMAGE ID CREATED SIZE +newspec/app_go 1.0 a944205e6030 59 minutes ago 9.32MB +``` +## Analysis +The builder image contains the Go toolchain and build dependencies, so it is significantly larger. +The final image contains only the static binary, which is much smaller and safer. + +# Why multi-stage builds matter for compiled languages + +Compiled languages (like Go, Rust, Java with native images, etc.) typically require a **heavy build environment**: compilers, linkers, SDKs, package managers, and temporary build artifacts. If you ship that same environment as your runtime container, the final image becomes unnecessarily large and less secure. + +Multi-stage builds solve this by separating concerns: + +### 1) Smaller final images (faster pull & deploy) +- The **builder stage** includes the full toolchain (large). +- The **runtime stage** contains only the compiled output (usually just a single binary). +This dramatically reduces image size, which improves: +- CI/CD speed (less time to push/pull) +- Startup speed (faster distribution in clusters) +- Bandwidth/storage usage + +### 2) Better security (smaller attack surface) +The runtime image no longer contains: +- compilers (go, gcc, build tools) +- package managers +- shells and utilities (especially with distroless/scratch) + +Fewer components, so fewer potential vulnerabilities (CVEs) and fewer tools available to an attacker if the container is compromised. + +### 3) Cleaner separation of build vs runtime +Multi-stage builds enforce a clear boundary: +- build dependencies exist only where needed (builder stage) +- runtime image stays minimal and focused on execution + +This makes the container easier to reason about and maintain. + +### 4) Reproducible and cache-friendly builds +When the Dockerfile copies dependency descriptors first (e.g., `go.mod`/`go.sum`) and downloads dependencies before copying source code: +- Docker can reuse cached layers if dependencies are unchanged +- rebuilds after code changes are significantly faster + +### 5) Enables ultra-minimal runtime images +Compiled apps can often run in very small base images: +- `distroless` (secure and minimal) +- `scratch` (almost empty) + +This is usually impossible for interpreted languages without bundling an interpreter runtime. + +**Summary:** For compiled languages, multi-stage builds provide the best of both worlds — a full build environment when you need it, and a minimal secure runtime image when you deploy. + +# Terminal output showing build process +## Builder +```bash +docker build --target builder -t newspec/app_go:builder . +[+] Building 2.4s (12/12) FINISHED docker:desktop-linux + => [internal] load build definition from Dockerfile 0.0s + => => transferring dockerfile: 349B 0.0s + => [internal] load metadata for docker.io/library/golang:1.22-alpine 2.1s + => [auth] library/golang:pull token for registry-1.docker.io 0.0s + => [internal] load .dockerignore 0.1s + => => transferring context: 105B 0.0s + => [builder 1/6] FROM docker.io/library/golang:1.22-alpine@sha256:1699c10032ca2582ec89a24a1312d986a3f094aed3d5c1147b19880afe40e052 0.0s + => [internal] load build context 0.0s + => => transferring context: 146B 0.0s + => CACHED [builder 2/6] WORKDIR /app 0.0s + => CACHED [builder 3/6] COPY go.mod ./ 0.0s + => CACHED [builder 4/6] RUN go mod download 0.0s + => CACHED [builder 5/6] COPY . . 0.0s + => CACHED [builder 6/6] RUN CGO_ENABLED=0 go build -o myapp 0.0s + => exporting to image 0.0s + => => exporting layers 0.0s + => => writing image sha256:21b01f8c61038149b9130afe7881765d625b2eb6622b6b46f42682d26b10ae2b 0.0s + => => naming to docker.io/newspec/app_go:builder 0.0s + +View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/wvw3g1yzoqu1uput2mz8me7zx +``` + +## Final +```bash +docker build -t newspec/app_go:1.0 . +[+] Building 1.5s (15/15) FINISHED docker:desktop-linux + => [internal] load build definition from Dockerfile 0.0s + => => transferring dockerfile: 349B 0.0s + => [internal] load metadata for gcr.io/distroless/static-debian12:nonroot 1.0s + => [internal] load metadata for docker.io/library/golang:1.22-alpine 0.7s + => [internal] load .dockerignore 0.0s + => => transferring context: 105B 0.0s + => [builder 1/6] FROM docker.io/library/golang:1.22-alpine@sha256:1699c10032ca2582ec89a24a1312d986a3f094aed3d5c1147b19880afe40e052 0.0s + => [stage-1 1/3] FROM gcr.io/distroless/static-debian12:nonroot@sha256:cba10d7abd3e203428e86f5b2d7fd5eb7d8987c387864ae4996cf97191b33764 0.0s + => [internal] load build context 0.0s + => => transferring context: 146B 0.0s + => CACHED [builder 2/6] WORKDIR /app 0.0s + => CACHED [builder 3/6] COPY go.mod ./ 0.0s + => CACHED [builder 4/6] RUN go mod download 0.0s + => CACHED [builder 5/6] COPY . . 0.0s + => CACHED [builder 6/6] RUN CGO_ENABLED=0 go build -o myapp 0.0s + => CACHED [stage-1 2/3] WORKDIR /app 0.0s + => CACHED [stage-1 3/3] COPY --from=builder /app/myapp . 0.0s + => exporting to image 0.1s + => => exporting layers 0.0s + => => writing image sha256:c9ff1572d8a13240f00ef7d66683264e0fbf4fa77c12790dc3f3428972819321 0.0s + => => naming to docker.io/newspec/app_go:1.0 0.0s + +View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/nvdyhylzo1hzpemy23lt42ll1 +``` +# Technical explanation of each stage's purpose +### Stage 1 — Builder (Compile Environment) +**Goal:** Produce a Linux executable from Go source code in a controlled build environment. + +**Why this stage exists:** +- Go compilation requires the Go toolchain (compiler, linker) which is large and should not be shipped in the final runtime image. +- The builder image provides everything needed to compile the application. + +**What happens technically:** +1. **Set working directory** + - `WORKDIR /app` defines where source code and build steps run inside the container. + +2. **Copy dependency definition first** + - `COPY go.mod ./` is done before copying the whole source tree. + - This allows Docker to cache the dependency download layer. + - Even if code changes, dependencies may not, so rebuilds are faster. + +3. **Download modules** + - `RUN go mod download` fetches required modules. + - In this project there are no external module dependencies, so Go prints: + `go: no module dependencies to download` + - The step is still good practice and keeps the Dockerfile consistent for future changes. + +4. **Copy application source code** + - `COPY . .` brings in the Go source files. + - This layer changes most often, so it comes after dependency caching steps. + +5. **Compile a static binary** + - `RUN CGO_ENABLED=0 go build -o myapp` + - `CGO_ENABLED=0` disables C bindings so the binary is statically linked. + - A static binary does not require libc or other runtime shared libraries, enabling minimal runtime images. + +**Output of the stage:** a compiled executable (`/app/myapp`). + +--- + +### Stage 2 — Runtime (Execution Environment) +**Goal:** Run only the compiled binary in a minimal and secure container image. + +**Why this stage exists:** +- The runtime stage should not contain compilers, source code, or build tools. +- A smaller runtime image reduces attack surface and improves deployment speed. + +**What happens technically:** +1. **Choose a minimal base image** + - `FROM gcr.io/distroless/static-debian12:nonroot` + - Distroless images contain only the minimum required runtime files. + - The `:nonroot` variant runs as a non-root user by default. + +2. **Set working directory** + - `WORKDIR /app` provides a predictable location for the binary. + +3. **Copy only the build artifact** + - `COPY --from=builder /app/myapp .` + - This copies only the compiled binary from the builder stage. + - No source code, no Go toolchain, no dependency caches are included. + +4. **Run the application** + - `CMD ["./myapp"]` starts the service. + - The application reads `HOST` and `PORT` environment variables: + - defaults: `HOST=0.0.0.0`, `PORT=8080` + - When running the container, port mapping must match the internal listening port (e.g., `-p 8000:8080`). + +**Output of the stage:** a minimal runtime container that executes the Go binary as a non-root user. \ No newline at end of file From 940215538279ae070100593644f5854fffc0b474 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 13:32:17 +0300 Subject: [PATCH 06/40] feat: lab03 task2 workflow ready --- .github/workflows/python-ci.yml | 0 app_python/docs/LAB03.md | 109 ++++++++++++++++++++++++++++++++ app_python/requirements.txt | 2 + app_python/tests/conftest.py | 14 ++++ app_python/tests/test_errors.py | 52 +++++++++++++++ app_python/tests/test_health.py | 18 ++++++ app_python/tests/test_root.py | 70 ++++++++++++++++++++ 7 files changed, 265 insertions(+) create mode 100644 .github/workflows/python-ci.yml create mode 100644 app_python/docs/LAB03.md create mode 100644 app_python/tests/conftest.py create mode 100644 app_python/tests/test_errors.py create mode 100644 app_python/tests/test_health.py create mode 100644 app_python/tests/test_root.py diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app_python/docs/LAB03.md b/app_python/docs/LAB03.md new file mode 100644 index 0000000000..aff1f98b7b --- /dev/null +++ b/app_python/docs/LAB03.md @@ -0,0 +1,109 @@ +# Unit Testing + +## Testing framework choice and why +After reviewing popular Python testing frameworks (such as `unittest` and `pytest`), I chose **pytest** because it makes writing, maintaining, and scaling tests easier and faster for both small and large projects. + +### 1) Less boilerplate, faster to write tests +With `pytest`, you don’t need to create test classes or inherit from special base classes (which is common in `unittest`). +Simple functions named `test_*` are enough, which keeps tests clean and easy to read. + +### 2) Powerful fixture system +`pytest` provides a strong **fixture** mechanism for setting up test data and environments: +- reusable setup/teardown logic; +- flexible scopes (`function`, `module`, `session`); +- dependency injection by simply adding parameters to test functions. + +This reduces duplication and improves test structure. + +### 3) Easy test parametrization +`pytest` makes it simple to run the same test with multiple input datasets using parametrization. +That improves coverage without copying and pasting similar tests. + +### 4) Clear, helpful failure output +When a test fails, `pytest` produces detailed and readable error messages (including smart value comparisons). +This speeds up debugging and helps quickly identify what went wrong. + +### 5) Rich plugin ecosystem and CI integration +`pytest` has a large ecosystem of plugins and integrates well with: +- coverage tools, +- linters, +- CI/CD systems (GitHub Actions, GitLab CI, etc.), +- reporting tools. + +This is useful if the project grows or needs automation. + +### 6) Flexibility and compatibility +`pytest` can also run tests written in the `unittest` style, so it’s easier to adopt gradually. +At the same time, `pytest` offers more modern and flexible features for everyday testing. + +--- + +**Conclusion:** I chose **pytest** because it reduces boilerplate, provides powerful fixtures and parametrization, offers excellent debugging output, and scales well with plugins and CI workflows. + +## Test structure explanation + +All tests are located in `app_python/tests/` and are written with **pytest** using FastAPI’s `TestClient`. + +### Directory layout +```text +app_python/ + app.py + tests/ + conftest.py + test_root.py + test_health.py + test_errors.py +``` + +### What each file contains +- `conftest.py` + - Defines shared pytest fixtures (e.g., `client`) used across multiple test files. + - The `client` fixture creates a `TestClient(app)` so tests can call the API endpoints without running a real server. +- `test_root.py` + - tests the main endpoint `GET /`. + - Verifies: + - HTTP status code is `200` + - JSON response contains required top-level fields (`service`, `system`, `runtime`, `request`, `endpoints`) + - Nested fields exist and have reasonable types/values (e.g., `uptime_seconds` is an `integer`, `timezone` is `"UTC"`) + - The endpoints list contains expected endpoints (`/` and `/health`) +- `test_health.py` + - Tests `GET /health`. + - Verifies: + - HTTP status code is `200` + - JSON response contains required fields (`status`, `timestamp`, `uptime_seconds`) + - status is `"healthy"` and `timestamp` is serialized as an ISO string +- test_errors.py + - Tests custom error handling: + - **500 Internal Server Error**: adds a temporary endpoint that raises `RuntimeError` and checks that the response JSON matches the global exception handler. + - **404 Not Found**: requests a non-existent endpoint and checks the custom 404 JSON. + - **Non-404 HTTPException**: adds a temporary endpoint that raises `HTTPException(418)` and checks the JSON returned by the `HTTPException` handler. + - Temporary test routes are removed in `finally` blocks to avoid affecting other tests. + +### Naming conventions +- Test files are named test_*.py +- Test functions are named test_* +- This allows pytest to automatically discover and run the test suite. + +## How to run tests locally +Use command: +```bash +pytest +``` + +## Terminal output showing all tests passing +```bash +pytest +========================================== test session starts =========================================== +platform win32 -- Python 3.12.4, pytest-8.4.2, pluggy-1.6.0 +rootdir: C:\Users\malov\PycharmProjects\DevOps-Core-Course +plugins: anyio-4.11.0, asyncio-1.3.0, cov-7.0.0 +asyncio: mode=Mode.STRICT, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function +collected 7 items + +app_python\tests\test_errors.py ... [ 42%] +app_python\tests\test_health.py .. [ 71%] +app_python\tests\test_root.py .. [100%] + +=========================================== 7 passed in 0.48s ============================================ +(.venv) PS C:\Users\malov\PycharmProjects\DevOps-Core-Course> +``` \ No newline at end of file diff --git a/app_python/requirements.txt b/app_python/requirements.txt index 94a41a1968..3ea66f4957 100644 --- a/app_python/requirements.txt +++ b/app_python/requirements.txt @@ -1,2 +1,4 @@ fastapi==0.122.0 uvicorn[standard]==0.38.0 +pytest==8.4.2 +flake8==7.3.0 diff --git a/app_python/tests/conftest.py b/app_python/tests/conftest.py new file mode 100644 index 0000000000..d1bf72913b --- /dev/null +++ b/app_python/tests/conftest.py @@ -0,0 +1,14 @@ +import pytest +from fastapi.testclient import TestClient + +from app import app + + +@pytest.fixture() +def client(): + return TestClient(app) + + +@pytest.fixture() +def client_no_raise(): + return TestClient(app, raise_server_exceptions=False) diff --git a/app_python/tests/test_errors.py b/app_python/tests/test_errors.py new file mode 100644 index 0000000000..076f70dff6 --- /dev/null +++ b/app_python/tests/test_errors.py @@ -0,0 +1,52 @@ +from fastapi import HTTPException + +from app import app + + +def test_500_returns_custom_json(client_no_raise): + @app.get("/__test_crash__") + async def __test_crash__(): + raise RuntimeError("boom") + + try: + r = client_no_raise.get("/__test_crash__") + assert r.status_code == 500 + assert r.json() == { + "error": "Internal Server Error", + "message": "An unexpected error occurred", + } + finally: + app.router.routes = [ + route for route in app.router.routes + if getattr(route, "path", None) != "/__test_crash__" + ] + + +def test_http_exception_handler_404_custom_json(client): + r = client.get("/this-endpoint-does-not-exist") + + assert r.status_code == 404 + assert r.json() == { + "error": "Not Found", + "message": "Endpoint does not exist", + } + + +def test_http_exception_handler_non_404_returns_http_error_json(client): + @app.get("/__test_http_418__") + async def __test_http_418__(): + raise HTTPException(status_code=418, detail="I'm a teapot") + + try: + r = client.get("/__test_http_418__") + + assert r.status_code == 418 + assert r.json() == { + "error": "HTTP Error", + "message": "I'm a teapot", + } + finally: + app.router.routes = [ + route for route in app.router.routes + if getattr(route, "path", None) != "/__test_http_418__" + ] diff --git a/app_python/tests/test_health.py b/app_python/tests/test_health.py new file mode 100644 index 0000000000..1d2b4f9dcd --- /dev/null +++ b/app_python/tests/test_health.py @@ -0,0 +1,18 @@ +def test_health_status_code(client): + r = client.get("/health") + assert r.status_code == 200 + + +def test_health_response_structure(client): + r = client.get("/health") + data = r.json() + + for key in ["status", "timestamp", "uptime_seconds"]: + assert key in data, f"Missing health field: {key}" + + assert data["status"] == "healthy" + assert isinstance(data["uptime_seconds"], int) + assert data["uptime_seconds"] >= 0 + + assert isinstance(data["timestamp"], str) + assert "T" in data["timestamp"] diff --git a/app_python/tests/test_root.py b/app_python/tests/test_root.py new file mode 100644 index 0000000000..9ca61460fa --- /dev/null +++ b/app_python/tests/test_root.py @@ -0,0 +1,70 @@ +def test_root_status_code(client): + r = client.get("/") + assert r.status_code == 200 + + +def test_root_json_structure_and_required_fields(client): + r = client.get("/") + data = r.json() + + for key in ["service", "system", "runtime", "request", "endpoints"]: + assert key in data, f"Missing top-level field: {key}" + + service = data["service"] + for key in ["name", "version", "description", "framework"]: + assert key in service, f"Missing service field: {key}" + assert service["name"] == "devops-info-service" + assert service["framework"] == "FastAPI" + + system = data["system"] + for key in [ + "hostname", + "platform", + "platform_version", + "architecture", + "cpu_count", + "python_version", + ]: + assert key in system, f"Missing system field: {key}" + + assert isinstance(system["hostname"], str) and system["hostname"] + assert isinstance(system["platform"], str) and system["platform"] + assert isinstance(system["architecture"], str) and system["architecture"] + assert ((system["cpu_count"] is None) or + isinstance(system["cpu_count"], int)) + + runtime = data["runtime"] + for key in ["uptime_seconds", "uptime_human", "current_time", "timezone"]: + assert key in runtime, f"Missing runtime field: {key}" + + assert isinstance(runtime["uptime_seconds"], int) + assert runtime["uptime_seconds"] >= 0 + assert isinstance(runtime["uptime_human"], str) and runtime["uptime_human"] + assert runtime["timezone"] == "UTC" + + assert isinstance(runtime["current_time"], str) + assert "T" in runtime["current_time"] + + req = data["request"] + for key in ["client_ip", "user_agent", "method", "path"]: + assert key in req, f"Missing request field: {key}" + + assert req["method"] == "GET" + assert req["path"] == "/" + assert isinstance(req["client_ip"], str) and req["client_ip"] + assert ("user_agent" in req) + + endpoints = data["endpoints"] + assert isinstance(endpoints, list) + assert len(endpoints) >= 2 + + paths = {(e.get("path"), e.get("method")) for e in endpoints} + assert ("/", "GET") in paths + assert ("/health", "GET") in paths + + for e in endpoints: + for key in ["path", "method", "description"]: + assert key in e + assert isinstance(e["path"], str) and e["path"].startswith("/") + assert e["method"] in {"GET", "POST", "PUT", "DELETE", "PATCH"} + assert isinstance(e["description"], str) and e["description"] From fe8455c5fa673d5a3f0b1b6d103b4e75ae18981a Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 13:37:08 +0300 Subject: [PATCH 07/40] feat: workflow added --- .github/workflows/python-ci.yml | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index e69de29bb2..d8f42aebe9 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -0,0 +1,48 @@ +name: Python Tests + +"on": + push: + branches: ["lab03"] + paths: + - 'app_python/**' + - '.github/workflows/python-ci.yml' + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + + - name: Install dependencies + run: pip install -r app_python/requirements.txt + + - name: Run linter + run: flake8 + + - name: Run tests + run: pytest + + docker: + needs: test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Generate version + run: echo "VERSION=$(date -u +%Y.%m.%d)" >> $GITHUB_ENV + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: ./app_python + push: true + tags: | + ${{ secrets.DOCKER_USERNAME }}/python_app:${{ env.VERSION }} + ${{ secrets.DOCKER_USERNAME }}/python_app:latest From 6fddd3432f72f1f1482ba53d4de15944c8eec5dd Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 13:39:11 +0300 Subject: [PATCH 08/40] feat: workflow added --- app_python/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/app_python/requirements.txt b/app_python/requirements.txt index 3ea66f4957..170f1dfdce 100644 --- a/app_python/requirements.txt +++ b/app_python/requirements.txt @@ -2,3 +2,4 @@ fastapi==0.122.0 uvicorn[standard]==0.38.0 pytest==8.4.2 flake8==7.3.0 +httpx==0.28.1 From 04fc643662b3e1a9caa917c8a8f8e0cc2247d0b5 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 13:44:05 +0300 Subject: [PATCH 09/40] feat: workflow updated --- .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 d8f42aebe9..e8a898bc27 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -45,4 +45,5 @@ jobs: push: true tags: | ${{ secrets.DOCKER_USERNAME }}/python_app:${{ env.VERSION }} + ${{ secrets.DOCKER_USERNAME }}/python_app:${{ github.sha }} ${{ secrets.DOCKER_USERNAME }}/python_app:latest From 90a3723e5e60e118c4d19bd2b649f36c4cf2c7de Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 13:48:52 +0300 Subject: [PATCH 10/40] fix: minor workflow fix --- .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 e8a898bc27..f58aa9d21d 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -1,6 +1,6 @@ name: Python Tests -"on": +on: push: branches: ["lab03"] paths: From db7c90f59ff2793d416a9b5c11535ed2aa6fef0a Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 13:53:15 +0300 Subject: [PATCH 11/40] fix: change the name of the workflow --- .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 f58aa9d21d..fab1caca82 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -1,4 +1,4 @@ -name: Python Tests +name: Python ci on: push: From 20c09a6b2eb825b9543ebf9fdd70943837f32c3f Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 15:07:05 +0300 Subject: [PATCH 12/40] feat: add caching in workflow --- .github/workflows/python-ci.yml | 4 ++++ app_python/docs/screenshots/green-checkmark.png | Bin 0 -> 9074 bytes 2 files changed, 4 insertions(+) create mode 100644 app_python/docs/screenshots/green-checkmark.png diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index fab1caca82..433c851109 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -13,6 +13,10 @@ jobs: steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 + with: + python-version: 3.12 + cache: "pip" + cache-dependency-path: app_python/requirements.txt - name: Install dependencies run: pip install -r app_python/requirements.txt diff --git a/app_python/docs/screenshots/green-checkmark.png b/app_python/docs/screenshots/green-checkmark.png new file mode 100644 index 0000000000000000000000000000000000000000..6dd752024b40fd48d17aca25109aeb4a8f72ea72 GIT binary patch literal 9074 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 B@0S1o literal 0 HcmV?d00001 From 5be24fabe2e6169a94696f47088137c7a8101340 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 15:13:03 +0300 Subject: [PATCH 13/40] feat: add caching in workflow(check improvement) --- .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 433c851109..0dd36e174a 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -1,5 +1,6 @@ name: Python ci + on: push: branches: ["lab03"] From b257c59d9e9a28d2432a4ef0c4130ad1e730997d Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 15:47:33 +0300 Subject: [PATCH 14/40] feat: snyk added into workflow --- .github/workflows/python-ci.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 0dd36e174a..9b2316c94c 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -3,7 +3,7 @@ name: Python ci on: push: - branches: ["lab03"] + branches: [ "lab03" ] paths: - 'app_python/**' - '.github/workflows/python-ci.yml' @@ -28,6 +28,18 @@ jobs: - name: Run tests run: pytest + security: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Run Snyk (dependencies) + uses: snyk/actions/python@master + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + with: + args: --severity-threshold=high --file + docker: needs: test runs-on: ubuntu-latest From a576f84a472f05d965d603015e7a429f437720bf Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 15:49:35 +0300 Subject: [PATCH 15/40] fix: snyk --- .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 9b2316c94c..7d613a3654 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -38,7 +38,7 @@ jobs: env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: - args: --severity-threshold=high --file + args: --severity-threshold=high docker: needs: test From 8dc6f9f20cb5aed08bb292373308f19c21e97f70 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 17:45:08 +0300 Subject: [PATCH 16/40] fix: snyk added --file path --- .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 7d613a3654..0076df8c00 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -38,7 +38,7 @@ jobs: env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: - args: --severity-threshold=high + args: --severity-threshold=high --file=app_python/requirements.txt docker: needs: test From ba08efb36af77b5525244a9140903b7f456e68d4 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 17:47:55 +0300 Subject: [PATCH 17/40] fix: snyk added dependencies --- .github/workflows/python-ci.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 0076df8c00..43ddae1841 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -33,6 +33,15 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: 3.12 + cache: "pip" + cache-dependency-path: app_python/requirements.txt + + - name: Install dependencies + run: pip install -r app_python/requirements.txt + - name: Run Snyk (dependencies) uses: snyk/actions/python@master env: From 9a4ab4f5a597f7e69d396eb81cc52ff6e2781939 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 17:54:03 +0300 Subject: [PATCH 18/40] fix: snyk --- .github/workflows/python-ci.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 43ddae1841..a53fba0905 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -33,24 +33,26 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: - python-version: 3.12 + python-version: "3.12" cache: "pip" cache-dependency-path: app_python/requirements.txt - name: Install dependencies run: pip install -r app_python/requirements.txt + - name: Setup Snyk CLI + uses: snyk/actions/setup@master + - name: Run Snyk (dependencies) - uses: snyk/actions/python@master + working-directory: app_python env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} - with: - args: --severity-threshold=high --file=app_python/requirements.txt + run: snyk test --severity-threshold=high docker: - needs: test + needs: [test, security] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From b6ec2c981bdf1b4a4d4dfbb5a99d848b8588efcc Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 20:28:08 +0300 Subject: [PATCH 19/40] feat (workflow): docker caching ebable --- .github/workflows/python-ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index a53fba0905..ea61e9b553 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -57,6 +57,9 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub uses: docker/login-action@v3 with: @@ -75,3 +78,5 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/python_app:${{ env.VERSION }} ${{ secrets.DOCKER_USERNAME }}/python_app:${{ github.sha }} ${{ secrets.DOCKER_USERNAME }}/python_app:latest + сgache-from: type=gha + cache-to: type=gha,mode=max From 9272242634e87ac31cde189c86d1b92f6775f85e Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 20:30:16 +0300 Subject: [PATCH 20/40] fix (workflow): docker --- .github/workflows/python-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index ea61e9b553..bf53bffbca 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -70,7 +70,7 @@ jobs: run: echo "VERSION=$(date -u +%Y.%m.%d)" >> $GITHUB_ENV - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: ./app_python push: true @@ -78,5 +78,5 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/python_app:${{ env.VERSION }} ${{ secrets.DOCKER_USERNAME }}/python_app:${{ github.sha }} ${{ secrets.DOCKER_USERNAME }}/python_app:latest - сgache-from: type=gha + сache-from: type=gha cache-to: type=gha,mode=max From 053b9638602052c4f2acba4aedff7587402fa2cf Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 20:33:09 +0300 Subject: [PATCH 21/40] fix (workflow): docker --- .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 bf53bffbca..376eb727b6 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -78,5 +78,5 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/python_app:${{ env.VERSION }} ${{ secrets.DOCKER_USERNAME }}/python_app:${{ github.sha }} ${{ secrets.DOCKER_USERNAME }}/python_app:latest - сache-from: type=gha + cache-from: type=gha cache-to: type=gha,mode=max From a382d1d6da46cdc1d133dbedb98a6f3b56e0a204 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 20:35:25 +0300 Subject: [PATCH 22/40] feat: check how caching works --- .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 376eb727b6..f6edc3c654 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -52,7 +52,7 @@ jobs: run: snyk test --severity-threshold=high docker: - needs: [test, security] + needs: [ test, security ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -80,3 +80,4 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/python_app:latest cache-from: type=gha cache-to: type=gha,mode=max + From 89270d4d939f9b7a35c23aaf524c07cb0422778b Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 20:47:37 +0300 Subject: [PATCH 23/40] cold run --- .github/workflows/python-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index f6edc3c654..3ed6ab94d8 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -80,4 +80,3 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/python_app:latest cache-from: type=gha cache-to: type=gha,mode=max - From ef0c471974d86064123cbefc2084c366d52b7705 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 20:49:20 +0300 Subject: [PATCH 24/40] warm run --- .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 3ed6ab94d8..f6edc3c654 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -80,3 +80,4 @@ jobs: ${{ secrets.DOCKER_USERNAME }}/python_app:latest cache-from: type=gha cache-to: type=gha,mode=max + From 8a8eb351b0271c937cf97670fbc25bc7d7e5fe84 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 22:10:14 +0300 Subject: [PATCH 25/40] feat: lab03 completed --- .github/workflows/python-ci.yml | 8 +- app_python/README.md | 7 + app_python/docs/LAB03.md | 221 +++++++++++------- app_python/docs/screenshots/cache_hit.png | Bin 0 -> 57987 bytes app_python/docs/screenshots/cache_miss.png | Bin 0 -> 58760 bytes .../docs/screenshots/green-checkmark.png | Bin 9074 -> 0 bytes 6 files changed, 155 insertions(+), 81 deletions(-) create mode 100644 app_python/docs/screenshots/cache_hit.png create mode 100644 app_python/docs/screenshots/cache_miss.png delete mode 100644 app_python/docs/screenshots/green-checkmark.png diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index f6edc3c654..c7cd4a5081 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -3,7 +3,12 @@ name: Python ci on: push: - branches: [ "lab03" ] + branches: [ "lab03", "master" ] + paths: + - 'app_python/**' + - '.github/workflows/python-ci.yml' + pull_request: + branches: [ "lab03", "master" ] paths: - 'app_python/**' - '.github/workflows/python-ci.yml' @@ -54,6 +59,7 @@ jobs: docker: needs: [ test, security ] runs-on: ubuntu-latest + if: github.event_name == 'push' && (github.ref == 'refs/heads/lab03' || github.ref == 'refs/heads/master') steps: - uses: actions/checkout@v4 diff --git a/app_python/README.md b/app_python/README.md index 2475567ab9..4eb3540441 100644 --- a/app_python/README.md +++ b/app_python/README.md @@ -1,3 +1,5 @@ +[![Python CI](https://github.com/newspec/DevOps-Core-Course/actions/workflows/python-ci.yml/badge.svg?branch=lab03)](https://github.com/newspec/DevOps-Core-Course/actions/workflows/python-ci.yml?query=branch%3Alab03) + # devops-info-service ## Overview @@ -64,3 +66,8 @@ Then run: docker run --rm -p : /: ``` +# Testing +To run test locally use command: +```bash +pytest +``` diff --git a/app_python/docs/LAB03.md b/app_python/docs/LAB03.md index aff1f98b7b..09c3e39c28 100644 --- a/app_python/docs/LAB03.md +++ b/app_python/docs/LAB03.md @@ -1,96 +1,58 @@ -# Unit Testing +# LAB03 — Unit Testing + CI/CD + Security -## Testing framework choice and why -After reviewing popular Python testing frameworks (such as `unittest` and `pytest`), I chose **pytest** because it makes writing, maintaining, and scaling tests easier and faster for both small and large projects. +## 1. Overview -### 1) Less boilerplate, faster to write tests -With `pytest`, you don’t need to create test classes or inherit from special base classes (which is common in `unittest`). -Simple functions named `test_*` are enough, which keeps tests clean and easy to read. +### Testing framework used and why you chose it -### 2) Powerful fixture system -`pytest` provides a strong **fixture** mechanism for setting up test data and environments: -- reusable setup/teardown logic; -- flexible scopes (`function`, `module`, `session`); -- dependency injection by simply adding parameters to test functions. +I chose **pytest** after comparing common Python testing frameworks (`unittest`, `pytest`, etc.). +Pytest requires less boilerplate, has powerful fixtures and parametrization, produces clear failure +output, and scales well with plugins and CI workflows. -This reduces duplication and improves test structure. +### What endpoints/functionality your tests cover -### 3) Easy test parametrization -`pytest` makes it simple to run the same test with multiple input datasets using parametrization. -That improves coverage without copying and pasting similar tests. +All tests are located in `app_python/tests/` and use FastAPI’s `TestClient`. The test suite covers: -### 4) Clear, helpful failure output -When a test fails, `pytest` produces detailed and readable error messages (including smart value comparisons). -This speeds up debugging and helps quickly identify what went wrong. +- **GET /** + Verifies status code `200`, JSON structure, required top-level + sections (`service`, `system`, `runtime`, `request`, `endpoints`), and important nested + fields/types. +- **GET /health** + Verifies status code `200`, required fields (`status`, `timestamp`, `uptime_seconds`), and basic + format checks. +- **Error cases** + - **404 Not Found** returns the custom + JSON `{ "error": "Not Found", "message": "Endpoint does not exist" }` + - **Non-404 HTTPException** returns `{ "error": "HTTP Error", "message": "" }` + - **500 Internal Server Error** + returns `{ "error": "Internal Server Error", "message": "An unexpected error occurred" }` -### 5) Rich plugin ecosystem and CI integration -`pytest` has a large ecosystem of plugins and integrates well with: -- coverage tools, -- linters, -- CI/CD systems (GitHub Actions, GitLab CI, etc.), -- reporting tools. +### CI workflow trigger configuration (when does it run?) -This is useful if the project grows or needs automation. +The GitHub Actions workflow runs on **push** and **pull requests** to `lab03` and `master`, but only +when changes affect: -### 6) Flexibility and compatibility -`pytest` can also run tests written in the `unittest` style, so it’s easier to adopt gradually. -At the same time, `pytest` offers more modern and flexible features for everyday testing. +- `app_python/**` +- `.github/workflows/python-ci.yml` ---- +This avoids unnecessary CI runs for unrelated edits. Docker images are built and pushed only on * +*push** events (not on pull requests). -**Conclusion:** I chose **pytest** because it reduces boilerplate, provides powerful fixtures and parametrization, offers excellent debugging output, and scales well with plugins and CI workflows. +### Versioning strategy chosen and rationale -## Test structure explanation +I use **CalVer (Calendar Versioning)** with format `YYYY.MM.DD` because this project is updated +frequently and doesn’t require manual git release tags. Date-based versions are simple, +human-readable, and work well for continuous delivery. -All tests are located in `app_python/tests/` and are written with **pytest** using FastAPI’s `TestClient`. +--- -### Directory layout -```text -app_python/ - app.py - tests/ - conftest.py - test_root.py - test_health.py - test_errors.py -``` +## 2. Workflow Evidence -### What each file contains -- `conftest.py` - - Defines shared pytest fixtures (e.g., `client`) used across multiple test files. - - The `client` fixture creates a `TestClient(app)` so tests can call the API endpoints without running a real server. -- `test_root.py` - - tests the main endpoint `GET /`. - - Verifies: - - HTTP status code is `200` - - JSON response contains required top-level fields (`service`, `system`, `runtime`, `request`, `endpoints`) - - Nested fields exist and have reasonable types/values (e.g., `uptime_seconds` is an `integer`, `timezone` is `"UTC"`) - - The endpoints list contains expected endpoints (`/` and `/health`) -- `test_health.py` - - Tests `GET /health`. - - Verifies: - - HTTP status code is `200` - - JSON response contains required fields (`status`, `timestamp`, `uptime_seconds`) - - status is `"healthy"` and `timestamp` is serialized as an ISO string -- test_errors.py - - Tests custom error handling: - - **500 Internal Server Error**: adds a temporary endpoint that raises `RuntimeError` and checks that the response JSON matches the global exception handler. - - **404 Not Found**: requests a non-existent endpoint and checks the custom 404 JSON. - - **Non-404 HTTPException**: adds a temporary endpoint that raises `HTTPException(418)` and checks the JSON returned by the `HTTPException` handler. - - Temporary test routes are removed in `finally` blocks to avoid affecting other tests. - -### Naming conventions -- Test files are named test_*.py -- Test functions are named test_* -- This allows pytest to automatically discover and run the test suite. - -## How to run tests locally -Use command: -```bash -pytest -``` +### ✅ Successful workflow run (GitHub Actions link) + +- https://github.com/newspec/DevOps-Core-Course/actions/runs/21822195126 + +### ✅ Tests passing locally (terminal output) -## Terminal output showing all tests passing ```bash pytest ========================================== test session starts =========================================== @@ -98,12 +60,111 @@ platform win32 -- Python 3.12.4, pytest-8.4.2, pluggy-1.6.0 rootdir: C:\Users\malov\PycharmProjects\DevOps-Core-Course plugins: anyio-4.11.0, asyncio-1.3.0, cov-7.0.0 asyncio: mode=Mode.STRICT, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function -collected 7 items +collected 7 items app_python\tests\test_errors.py ... [ 42%] app_python\tests\test_health.py .. [ 71%] app_python\tests\test_root.py .. [100%] =========================================== 7 passed in 0.48s ============================================ -(.venv) PS C:\Users\malov\PycharmProjects\DevOps-Core-Course> -``` \ No newline at end of file +``` + +### ✅ Docker image on Docker Hub (link to your image) + +- https://hub.docker.com/repository/docker/newspec/python_app/general + +### ✅ Status badge working in README + +Check the top page of README.md + +## 3. Best Practices Implemented + +- **Fail Fast**: If a step fails, the job stops immediately, saving CI time and making failures + obvious. + +- **Job Dependencies** : Docker push depends on successful `test` and `security` jobs, preventing + publishing broken/insecure builds. + +- **Dependency Caching (pip)**: `setup-python` caches pip downloads so installs are faster on + repeated runs. + +- **Docker Layer Caching**: Buildx + GHA cache reuses Docker layers across runs, reducing Docker + build time significantly. + +- **Secrets Management**: Tokens (Docker Hub + Snyk) are stored in GitHub Secrets and never + committed. + +### Caching: time saved (before vs after) + +Measured by comparing two workflow runs: + +- **Cold run (cache miss)**: 80s total + - tests: 14s + - security: 29s + - docker build: 41s + +- **Warm run (cache hit)**: 64s total + - tests: 11s + - security: 22s + - docker build: 30s + +**Improvement**: + +- Total time saved: **16s** +- Docker build time saved: **11s** +- Percent improvement: **~20%** + +Evidence (screenshots): + +- First run (no cache): ![cache_miss.png](screenshots/cache_miss.png) +- Second run (cache hit): ![cache_hit.png](screenshots/cache_hit.png) + +### Snyk: vulnerabilities found? action taken + +Snyk is executed in a separate `security` job using: + +```bash +snyk test --severity-threshold=high +``` + +- If `high` (or above) vulnerabilities are found, the security job fails. +- Because Docker depends on `security`, the image will **not be pushed** until vulnerabilities are + fixed or the threshold is adjusted. + +**Snyk result**: 0 high/critical vulnerabilities (build passed) + +## Key Decisions + +### Versioning Strategy: SemVer or CalVer? Why did you choose it for your app? + +I chose **CalVer** (`YYYY.MM.DD`) because the application is built frequently and does not follow +formal release cycles. Date-based versioning is easy to automate in CI and provides clear +information about when an image was built. + +### Docker Tags: What tags does your CI create? (e.g., latest, version number, etc.) + +The CI publishes the Docker image with these tags: + +- `YYYY.MM.DD` (CalVer date tag) — e.g., `2026.02.09` +- `${{ github.sha }}` (commit SHA tag) — uniquely identifies the build source commit +- `latest` — points to the most recent image build from the `lab03` or `master` branch + +### Workflow Triggers: Why did you choose those triggers? + +The workflow runs on push and pull request to `lab03` and `master` and only when relevant files +change. This avoids running CI for unrelated edits. Docker images are built and pushed only on push +events (not on pull requests) for `lab03` and `master`. + +### Test Coverage: What's tested vs not tested? + +**Tested**: + +- Successful responses for `GET /` and `GET /health` +- Response JSON structure and required fields +- Custom error handling for 404, non-404 `HTTPException`, and 500 errors + +**Not tested**: + +- Performance/load behavior +- External integrations (none in this app) +- Detailed validation of dynamic fields beyond basic format/type checks (e.g., exact timestamps) \ No newline at end of file diff --git a/app_python/docs/screenshots/cache_hit.png b/app_python/docs/screenshots/cache_hit.png new file mode 100644 index 0000000000000000000000000000000000000000..cf23e1e1a94a6dca973a6406e23b24f187a1483b GIT binary patch literal 57987 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 literal 0 HcmV?d00001 diff --git a/app_python/docs/screenshots/cache_miss.png b/app_python/docs/screenshots/cache_miss.png new file mode 100644 index 0000000000000000000000000000000000000000..a03f43a091fd18d8bd3ac17a9ca2455d112fca25 GIT binary patch literal 58760 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 B@0S1o From 55afb8da031104278bd2afaf9de2cacf550c0bd3 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 22:34:54 +0300 Subject: [PATCH 26/40] only go file changed --- .github/workflows/go-ci.yml | 97 +++++++++++++++++++++++++++++++++++++ app_go/README.md | 2 + 2 files changed, 99 insertions(+) create mode 100644 .github/workflows/go-ci.yml diff --git a/.github/workflows/go-ci.yml b/.github/workflows/go-ci.yml new file mode 100644 index 0000000000..8ba9be0578 --- /dev/null +++ b/.github/workflows/go-ci.yml @@ -0,0 +1,97 @@ +name: Go ci + +on: + push: + branches: ["lab03", "master"] + paths: + - "app_go/**" + - ".github/workflows/go-ci.yml" + pull_request: + branches: ["lab03", "master"] + paths: + - "app_go/**" + - ".github/workflows/go-ci.yml" + +jobs: + test: + runs-on: ubuntu-latest + defaults: + run: + working-directory: app_go + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + cache: true + + - name: Go fmt check + run: | + test -z "$(gofmt -l .)" + + - name: Run tests with coverage + run: go test -coverprofile=coverage.out ./... + + - name: Upload coverage artifact + uses: actions/upload-artifact@v4 + with: + name: go-coverage + path: app_go/coverage.out + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v4 + with: + files: app_go/coverage.out + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + lint: + runs-on: ubuntu-latest + defaults: + run: + working-directory: app_go + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: "1.22" + cache: true + + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.61.0 + working-directory: app_go + + docker: + needs: [test, lint] + runs-on: ubuntu-latest + if: github.event_name == 'push' && (github.ref == 'refs/heads/lab03' || github.ref == 'refs/heads/master') + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Generate version + run: echo "VERSION=$(date -u +%Y.%m.%d)" >> $GITHUB_ENV + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: ./app_go + push: true + tags: | + ${{ secrets.DOCKER_USERNAME }}/go_app:${{ env.VERSION }} + ${{ secrets.DOCKER_USERNAME }}/go_app:${{ github.sha }} + ${{ secrets.DOCKER_USERNAME }}/go_app:latest + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/app_go/README.md b/app_go/README.md index e53cc9a7e6..d2b0230888 100644 --- a/app_go/README.md +++ b/app_go/README.md @@ -1,3 +1,5 @@ +[![Go CI](https://github.com/newspec/DevOps-Core-Course/actions/workflows/go-ci.yml/badge.svg?branch=lab03)](https://github.com/newspec/DevOps-Core-Course/actions/workflows/go-ci.yml?query=branch%3Alab03) +[![Coverage](https://codecov.io/gh/newspec/DevOps-Core-Course/branch/lab03/graph/badge.svg)](https://codecov.io/gh/newspec/DevOps-Core-Course) # devops-info-service (Go) ## Overview From be33caeb656ddd3737bd48fc09f437e3651a6213 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 22:39:41 +0300 Subject: [PATCH 27/40] Only python file changed --- .github/workflows/python-ci.yml | 10 +++++++++- app_python/README.md | 1 + app_python/requirements.txt | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index c7cd4a5081..54eacc9e95 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -31,7 +31,15 @@ jobs: run: flake8 - name: Run tests - run: pytest + run: pytest --cov=. --cov-report=xml:coverage.xml --cov-report=term + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v5 + with: + files: app_python/coverage.xml + fail_ci_if_error: true + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} security: runs-on: ubuntu-latest diff --git a/app_python/README.md b/app_python/README.md index 4eb3540441..76ebbf74c5 100644 --- a/app_python/README.md +++ b/app_python/README.md @@ -1,4 +1,5 @@ [![Python CI](https://github.com/newspec/DevOps-Core-Course/actions/workflows/python-ci.yml/badge.svg?branch=lab03)](https://github.com/newspec/DevOps-Core-Course/actions/workflows/python-ci.yml?query=branch%3Alab03) +[![Coverage](https://codecov.io/gh/newspec/DevOps-Core-Course/branch/lab03/graph/badge.svg)](https://codecov.io/gh/newspec/DevOps-Core-Course) # devops-info-service diff --git a/app_python/requirements.txt b/app_python/requirements.txt index 170f1dfdce..c6245af3cf 100644 --- a/app_python/requirements.txt +++ b/app_python/requirements.txt @@ -3,3 +3,4 @@ uvicorn[standard]==0.38.0 pytest==8.4.2 flake8==7.3.0 httpx==0.28.1 +pytest-cov==7.0.0 From 1f09d67786bca475ae376ef9e8eb89925b048441 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 22:45:16 +0300 Subject: [PATCH 28/40] only python files changes --- .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 54eacc9e95..8c5cec5f4b 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -31,6 +31,7 @@ jobs: run: flake8 - name: Run tests + working-directory: app_python run: pytest --cov=. --cov-report=xml:coverage.xml --cov-report=term - name: Upload coverage to Codecov From ff1f215a3863cb45eebdace34c44cb0b94a4c23a Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 22:49:16 +0300 Subject: [PATCH 29/40] both python and go files changed --- app_go/README.md | 2 +- app_python/README.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app_go/README.md b/app_go/README.md index d2b0230888..6d97b75bc3 100644 --- a/app_go/README.md +++ b/app_go/README.md @@ -42,4 +42,4 @@ The application is configured using environment variables. | Variable | Default | Description | Example | |---------|---------|-------------|---------| | `HOST` | `0.0.0.0` | Host interface to bind the server to | `0.0.0.0` | -| `PORT` | `8080` | Port the server listens on | `8080` | \ No newline at end of file +| `PORT` | `8080` | Port the server listens on | `8080` | diff --git a/app_python/README.md b/app_python/README.md index 76ebbf74c5..4853c7205a 100644 --- a/app_python/README.md +++ b/app_python/README.md @@ -72,3 +72,4 @@ To run test locally use command: ```bash pytest ``` + From 8e5eecec72e628db6a6e4a5e5bbd8977d47a153f Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 23:03:44 +0300 Subject: [PATCH 30/40] fix (codecov): report links and flags --- .github/workflows/go-ci.yml | 1 + .github/workflows/python-ci.yml | 1 + app_go/README.md | 2 +- app_python/README.md | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go-ci.yml b/.github/workflows/go-ci.yml index 8ba9be0578..841fc460ba 100644 --- a/.github/workflows/go-ci.yml +++ b/.github/workflows/go-ci.yml @@ -38,6 +38,7 @@ jobs: with: name: go-coverage path: app_go/coverage.out + flags: go - name: Upload coverage to Codecov uses: codecov/codecov-action@v4 diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 8c5cec5f4b..7847aee837 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -39,6 +39,7 @@ jobs: with: files: app_python/coverage.xml fail_ci_if_error: true + flags: python env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/app_go/README.md b/app_go/README.md index 6d97b75bc3..507bda3303 100644 --- a/app_go/README.md +++ b/app_go/README.md @@ -1,5 +1,5 @@ [![Go CI](https://github.com/newspec/DevOps-Core-Course/actions/workflows/go-ci.yml/badge.svg?branch=lab03)](https://github.com/newspec/DevOps-Core-Course/actions/workflows/go-ci.yml?query=branch%3Alab03) -[![Coverage](https://codecov.io/gh/newspec/DevOps-Core-Course/branch/lab03/graph/badge.svg)](https://codecov.io/gh/newspec/DevOps-Core-Course) +[![Coverage](https://codecov.io/gh/newspec/DevOps-Core-Course/branch/lab03/graph/badge.svg)](https://codecov.io/gh/newspec/DevOps-Core-Course?flag=go) # devops-info-service (Go) ## Overview diff --git a/app_python/README.md b/app_python/README.md index 4853c7205a..98483a5a73 100644 --- a/app_python/README.md +++ b/app_python/README.md @@ -1,5 +1,5 @@ [![Python CI](https://github.com/newspec/DevOps-Core-Course/actions/workflows/python-ci.yml/badge.svg?branch=lab03)](https://github.com/newspec/DevOps-Core-Course/actions/workflows/python-ci.yml?query=branch%3Alab03) -[![Coverage](https://codecov.io/gh/newspec/DevOps-Core-Course/branch/lab03/graph/badge.svg)](https://codecov.io/gh/newspec/DevOps-Core-Course) +[![Coverage](https://codecov.io/gh/newspec/DevOps-Core-Course/branch/lab03/graph/badge.svg)](https://codecov.io/gh/newspec/DevOps-Core-Course?flag=python) # devops-info-service From 88ca03ed63e482cfcc00a62b43bc142ae4bafb2d Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 23:11:58 +0300 Subject: [PATCH 31/40] fix (codecod): paths --- .github/workflows/go-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/go-ci.yml b/.github/workflows/go-ci.yml index 841fc460ba..41295a924c 100644 --- a/.github/workflows/go-ci.yml +++ b/.github/workflows/go-ci.yml @@ -31,6 +31,7 @@ jobs: test -z "$(gofmt -l .)" - name: Run tests with coverage + working-directory: app_go run: go test -coverprofile=coverage.out ./... - name: Upload coverage artifact From 0bdb02420a40ebfa32f17262de9ff930b2a357cb Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 23:25:47 +0300 Subject: [PATCH 32/40] fixes --- .github/workflows/go-ci.yml | 4 +-- .github/workflows/python-ci.yml | 2 +- app_go/main_test.go | 56 +++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 app_go/main_test.go diff --git a/.github/workflows/go-ci.yml b/.github/workflows/go-ci.yml index 41295a924c..3fdc914fb8 100644 --- a/.github/workflows/go-ci.yml +++ b/.github/workflows/go-ci.yml @@ -39,12 +39,12 @@ jobs: with: name: go-coverage path: app_go/coverage.out - flags: go - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@v5 with: files: app_go/coverage.out + flags: go env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 7847aee837..f0ed5ca75c 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -35,7 +35,7 @@ jobs: run: pytest --cov=. --cov-report=xml:coverage.xml --cov-report=term - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5 + uses: codecov/codecov-action@v5 with: files: app_python/coverage.xml fail_ci_if_error: true diff --git a/app_go/main_test.go b/app_go/main_test.go new file mode 100644 index 0000000000..a273d1f240 --- /dev/null +++ b/app_go/main_test.go @@ -0,0 +1,56 @@ +package main + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" +) + +func TestRootOK(t *testing.T) { + req := httptest.NewRequest(http.MethodGet, "/", nil) + rr := httptest.NewRecorder() + + mainHandler(rr, req) + + if rr.Code != http.StatusOK { + t.Fatalf("expected 200, got %d", rr.Code) + } + + var data map[string]any + if err := json.Unmarshal(rr.Body.Bytes(), &data); err != nil { + t.Fatalf("invalid json: %v", err) + } + + // top-level keys + for _, k := range []string{"service", "system", "runtime", "request", "endpoints"} { + if _, ok := data[k]; !ok { + t.Fatalf("missing key: %s", k) + } + } +} + +func TestHealthOK(t *testing.T) { + req := httptest.NewRequest(http.MethodGet, "/health", nil) + rr := httptest.NewRecorder() + + healthHandler(rr, req) + + if rr.Code != http.StatusOK { + t.Fatalf("expected 200, got %d", rr.Code) + } + + var data map[string]any + if err := json.Unmarshal(rr.Body.Bytes(), &data); err != nil { + t.Fatalf("invalid json: %v", err) + } + + for _, k := range []string{"status", "timestamp", "uptime_seconds"} { + if _, ok := data[k]; !ok { + t.Fatalf("missing key: %s", k) + } + } + if data["status"] != "healthy" { + t.Fatalf("expected status healthy, got %v", data["status"]) + } +} From 6ae7df78ba815adea0a866a180e0ae3481ee5a12 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Mon, 9 Feb 2026 23:59:11 +0300 Subject: [PATCH 33/40] feat: lab03 bonus task completed --- app_go/README.md | 4 +- app_go/docs/LAB03.md | 86 ++++++++++++++++++ app_go/docs/screenshots/coverage.png | Bin 0 -> 42943 bytes .../screenshots/proof_of_path_validations.png | Bin 0 -> 45844 bytes app_python/README.md | 3 +- 5 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 app_go/docs/LAB03.md create mode 100644 app_go/docs/screenshots/coverage.png create mode 100644 app_go/docs/screenshots/proof_of_path_validations.png diff --git a/app_go/README.md b/app_go/README.md index 507bda3303..f2870f9688 100644 --- a/app_go/README.md +++ b/app_go/README.md @@ -1,5 +1,7 @@ [![Go CI](https://github.com/newspec/DevOps-Core-Course/actions/workflows/go-ci.yml/badge.svg?branch=lab03)](https://github.com/newspec/DevOps-Core-Course/actions/workflows/go-ci.yml?query=branch%3Alab03) -[![Coverage](https://codecov.io/gh/newspec/DevOps-Core-Course/branch/lab03/graph/badge.svg)](https://codecov.io/gh/newspec/DevOps-Core-Course?flag=go) +[![Coverage](https://codecov.io/gh/newspec/DevOps-Core-Course/branch/lab03/graph/badge.svg?flag=go)](https://codecov.io/gh/newspec/DevOps-Core-Course/branch/lab03?flag=go) + + # devops-info-service (Go) ## Overview diff --git a/app_go/docs/LAB03.md b/app_go/docs/LAB03.md new file mode 100644 index 0000000000..e039089a71 --- /dev/null +++ b/app_go/docs/LAB03.md @@ -0,0 +1,86 @@ +# LAB03 (Go) — Bonus: Multi-App CI + Path Filters + Coverage + +## 1) Second workflow implementation (Go CI) + language-specific best practices + +A separate workflow file is added for the Go application: + +- `.github/workflows/go-ci.yml` + +It implements Go-specific CI best practices: + +- **Setup Go toolchain** via `actions/setup-go` (Go 1.22+) +- **Formatting check**: `gofmt -l .` must return empty output +- **Linting**: `golangci-lint` (industry-standard Go linter aggregator) +- **Unit tests**: `go test ./...` +- **Coverage generation**: `go test -coverprofile=coverage.out ./...` +- **Docker build/push**: multi-stage Docker build using the existing `app_go/Dockerfile` (builder stage + distroless runtime) + +Docker image tagging follows the same CalVer strategy as Python: + +- `YYYY.MM.DD` (CalVer) +- `${GITHUB_SHA}` (commit SHA) +- `latest` + +## 2) Path filter configuration + testing proof + +The Go workflow is triggered only when Go-related files change: + +- `app_go/**` +- `.github/workflows/go-ci.yml` + +This prevents unnecessary CI runs for unrelated parts of the monorepo. + +### Proof (selective triggering) + +Provide evidence with 2 small commits: + +1) **Change only Go files** + - https://github.com/newspec/DevOps-Core-Course/actions/runs/21837847722 + +2) **Change only Python files** + - https://github.com/newspec/DevOps-Core-Course/actions/runs/21838134121 + +## 3) Benefits analysis — why path filters matter in monorepos + +Path filters are important in monorepos because they: + +- **Save CI time and compute**: no need to run Go CI when only Python changes (and vice versa) +- **Reduce noise in PR checks**: fewer irrelevant checks, faster feedback for reviewers +- **Improve developer experience**: faster iteration and fewer “unrelated failures” +- **Scale better** as more apps/labs are added to the same repository + +## 4) Example showing workflows running independently + +Example scenario: + +- Commit A modifies only `app_go/**` → only Go CI runs +- Commit B modifies only `app_python/**` → only Python CI runs +- Commit C modifies both `app_go/**` and `app_python/**` → both workflows run in parallel + +![screenshots/proof_of_path_validations.png](screenshots/proof_of_path_validations.png) + +## 5) Terminal output / Actions evidence (selective triggering) + +See links and screenshot above. + +## 6) Coverage integration (dashboard link / screenshot) +![screenshots/coverage.png](screenshots/coverage.png) + +## 7) Coverage analysis (current percentage, covered/not covered, threshold) + +### Current coverage + +Current Go coverage: 44% +Current Python coverage 99% + +### What is covered (Go) +- `GET /` handler (`mainHandler`) returns status `200` and contains required top-level JSON keys: + `service`, `system`, `runtime`, `request`, `endpoints` +- `GET /health` handler (`healthHandler`) returns status `200` and contains required keys: + `status`, `timestamp`, `uptime_seconds` + +### What is not covered (Go) +- Middleware behavior (`withRecover`, `withLogging`, `withNotFound`) +- Negative/error scenarios (e.g., unknown path via middleware, panic recovery) +- Strict validation of dynamic fields (timestamps formatting beyond basic checks) + diff --git a/app_go/docs/screenshots/coverage.png b/app_go/docs/screenshots/coverage.png new file mode 100644 index 0000000000000000000000000000000000000000..1c9c2434ef5561d8ad71219c0dd60feb65326e66 GIT binary patch literal 42943 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

BBx%uin@b>EWKGniiHK5;jhWWKC?xA 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 a_MW7XxpG;vG%fy2K3y}m1mg@{qy7VkqgyBd literal 0 HcmV?d00001 diff --git a/app_go/docs/screenshots/proof_of_path_validations.png b/app_go/docs/screenshots/proof_of_path_validations.png new file mode 100644 index 0000000000000000000000000000000000000000..00df9e79978dfaf9c6aba5e0b623f4f8dced5fc8 GIT binary patch literal 45844 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 SNCCksz)*XprBtS18T2o!0y0wo literal 0 HcmV?d00001 diff --git a/app_python/README.md b/app_python/README.md index 98483a5a73..170f1cac89 100644 --- a/app_python/README.md +++ b/app_python/README.md @@ -1,5 +1,6 @@ [![Python CI](https://github.com/newspec/DevOps-Core-Course/actions/workflows/python-ci.yml/badge.svg?branch=lab03)](https://github.com/newspec/DevOps-Core-Course/actions/workflows/python-ci.yml?query=branch%3Alab03) -[![Coverage](https://codecov.io/gh/newspec/DevOps-Core-Course/branch/lab03/graph/badge.svg)](https://codecov.io/gh/newspec/DevOps-Core-Course?flag=python) +[![Coverage](https://codecov.io/gh/newspec/DevOps-Core-Course/branch/lab03/graph/badge.svg?flag=python)](https://codecov.io/gh/newspec/DevOps-Core-Course/branch/lab03?flag=python) + # devops-info-service From 0b725d56944f1cb3c322b504e1a128f0b0dfe345 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Tue, 17 Feb 2026 03:43:06 +0300 Subject: [PATCH 34/40] feat: lab04 completed --- .github/workflows/terraform-ci.yml | 94 +++ .gitignore | 70 +- docs/LAB04.md | 1192 ++++++++++++++++++++++++++++ docs/image.png | Bin 0 -> 181869 bytes pulumi/Pulumi.yaml | 3 + pulumi/__main__.py | 146 ++++ pulumi/requirements.txt | 2 + terraform/.terraform.lock.hcl | 18 + terraform/.terraformrc | 9 + terraform/.tflint.hcl | 30 + terraform/github.tf | 52 ++ terraform/main.tf | 118 +++ terraform/outputs.tf | 53 ++ terraform/variables.tf | 61 ++ 14 files changed, 1847 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/terraform-ci.yml create mode 100644 docs/LAB04.md create mode 100644 docs/image.png create mode 100644 pulumi/Pulumi.yaml create mode 100644 pulumi/__main__.py create mode 100644 pulumi/requirements.txt create mode 100644 terraform/.terraform.lock.hcl create mode 100644 terraform/.terraformrc create mode 100644 terraform/.tflint.hcl create mode 100644 terraform/github.tf create mode 100644 terraform/main.tf create mode 100644 terraform/outputs.tf create mode 100644 terraform/variables.tf diff --git a/.github/workflows/terraform-ci.yml b/.github/workflows/terraform-ci.yml new file mode 100644 index 0000000000..6931a90b72 --- /dev/null +++ b/.github/workflows/terraform-ci.yml @@ -0,0 +1,94 @@ +name: Terraform CI + +on: + pull_request: + paths: + - 'terraform/**' + - '.github/workflows/terraform-ci.yml' + push: + branches: + - lab04 + paths: + - 'terraform/**' + - '.github/workflows/terraform-ci.yml' + +jobs: + terraform-validate: + name: Terraform Validation + runs-on: ubuntu-latest + + defaults: + run: + working-directory: terraform + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v3 + with: + terraform_version: 1.9.0 + + - name: Terraform Format Check + id: fmt + run: terraform fmt -check -recursive + continue-on-error: true + + - name: Terraform Init + id: init + run: terraform init -backend=false + + - name: Terraform Validate + id: validate + run: | + terraform validate -no-color | tee validate.txt + + - name: Setup TFLint + uses: terraform-linters/setup-tflint@v4 + with: + tflint_version: latest + + - name: Initialize TFLint + run: tflint --init + + - name: Run TFLint + id: tflint + run: tflint --format compact + continue-on-error: true + + - name: Comment PR with Results + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const validateOut = fs.existsSync('terraform/validate.txt') + ? fs.readFileSync('terraform/validate.txt', 'utf8') + : 'No validation output'; + + const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\` + #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\` + #### Terraform Validation 🤖\`${{ steps.validate.outcome }}\` + #### TFLint 🔍\`${{ steps.tflint.outcome }}\` + +

Show Validation Output + + \`\`\` + ${validateOut} + \`\`\` + +
+ + *Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`, Workflow: \`${{ github.workflow }}\`*`; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: output + }) + + - name: Fail if validation failed + if: steps.fmt.outcome == 'failure' || steps.validate.outcome == 'failure' + run: exit 1 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 30d74d2584..5cba3470d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,69 @@ -test \ No newline at end of file +# General +test +.DS_Store +*.log + +# Terraform +*.tfstate +*.tfstate.* +.terraform/ +terraform.tfvars +*.tfvars +crash.log +crash.*.log +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Pulumi +pulumi/venv/ +pulumi/__pycache__/ +Pulumi.*.yaml +.pulumi/ + +# Cloud credentials +*.pem +*.key +*.json +credentials +.aws/ +.azure/ +.gcp/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +venv/ +ENV/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# Node +node_modules/ +npm-debug.log +yarn-error.log \ No newline at end of file diff --git a/docs/LAB04.md b/docs/LAB04.md new file mode 100644 index 0000000000..b17667b00d --- /dev/null +++ b/docs/LAB04.md @@ -0,0 +1,1192 @@ +# Lab 04 - Infrastructure as Code (Terraform & Pulumi) + +## 1. Cloud Provider & Infrastructure + +### Cloud Provider Choice: Yandex Cloud + +**Rationale:** +- **Accessibility in Russia**: No restrictions or sanctions affecting access +- **Free Tier**: 1 VM with 20% vCPU, 1 GB RAM, 10 GB storage +- **No Credit Card Required**: Can start without payment method +- **Good Documentation**: Available in Russian and English +- **Terraform & Pulumi Support**: Official providers available +- **Local Data Centers**: Lower latency for Russian users + +**Alternative Considered:** +- AWS: More popular globally but requires credit card and may have access issues +- GCP: Good free tier but complex setup +- VK Cloud: Russian alternative but less mature tooling support + +### Instance Configuration + +**VM Specifications:** +- **Platform**: standard-v2 +- **CPU**: 2 cores @ 20% (free tier) +- **Memory**: 1 GB RAM +- **Disk**: 10 GB HDD (network-hdd) +- **OS**: Ubuntu 24.04 LTS +- **Region/Zone**: ru-central1-a + +**Network Configuration:** +- **VPC Network**: Custom network (10.128.0.0/24) +- **Public IP**: Yes (NAT enabled) +- **Security Group Rules**: + - SSH (port 22): Allow from anywhere (0.0.0.0/0) + - HTTP (port 80): Allow from anywhere + - Custom (port 5000): Allow from anywhere (for app deployment) + - Egress: Allow all outbound traffic + +### Cost Analysis + +**Total Cost: $0.00/month** + +Using Yandex Cloud free tier: +- VM: Free (20% vCPU, 1 GB RAM within limits) +- Storage: Free (10 GB HDD within limits) +- Network: Free (within egress limits) +- Public IP: Free (1 static IP included) + +### Resources Created + +**Terraform Resources:** +1. `yandex_vpc_network.lab04_network` - VPC network +2. `yandex_vpc_subnet.lab04_subnet` - Subnet (10.128.0.0/24) +3. `yandex_vpc_security_group.lab04_sg` - Security group with firewall rules +4. `yandex_compute_instance.lab04_vm` - VM instance + +**Pulumi Resources:** +1. `lab04-network` - VPC network +2. `lab04-subnet` - Subnet (10.128.0.0/24) +3. `lab04-sg` - Security group with firewall rules +4. `lab04-vm` - VM instance + +--- + +## 2. Terraform Implementation + +### Terraform Version + +```bash +Terraform v1.9.0 +on darwin_arm64 ++ provider registry.terraform.io/integrations/github v5.45.0 ++ provider registry.terraform.io/yandex-cloud/yandex v0.187.0 +``` + +### Project Structure + +``` +terraform/ +├── .terraform.lock.hcl # Provider version lock file +├── .terraformrc # Terraform CLI configuration (Yandex mirror) +├── .tflint.hcl # TFLint configuration +├── main.tf # Main resources (VM, network, security) +├── variables.tf # Input variable declarations +├── outputs.tf # Output value definitions +├── github.tf # GitHub provider (bonus task) +├── terraform.tfvars # Actual configuration (gitignored) +├── terraform.tfstate # State file (gitignored) +└── terraform.tfstate.backup # State backup (gitignored) +``` + +**Note:** `terraform.tfstate` files are present locally but excluded from Git via `.gitignore`. + +### Key Configuration Decisions + +**1. Provider Configuration** +- Used Yandex Cloud provider version ~> 0.187 +- Authentication via Service Account key (authorized key JSON file) +- Configured default zone (ru-central1-a) and folder_id +- GitHub provider version ~> 5.45 for repository management + +**2. Resource Organization** +- Separated resources logically in main.tf +- Used data source for Ubuntu image (latest 24.04 LTS) +- Created dedicated VPC network instead of using default + +**3. Security Approach** +- Security group with explicit ingress/egress rules +- SSH key injection via metadata +- All sensitive values in gitignored terraform.tfvars +- Used variables for all configurable parameters + +**4. Free Tier Optimization** +- Set `core_fraction = 20` for free tier CPU +- Used `network-hdd` disk type (cheaper than SSD) +- Minimal 10 GB disk size +- Single VM instance + +### Challenges Encountered + +**1. Authentication Setup** +- **Issue**: Initial confusion about OAuth token vs service account +- **Solution**: Created Service Account with appropriate roles, generated authorized key (JSON) +- **Learning**: Service accounts provide better security and are recommended for automation + +**3. Image Selection** +- **Issue**: Needed to find correct Ubuntu 24.04 image family name +- **Solution**: Used data source with `family = "ubuntu-2404-lts"` +- **Learning**: Data sources are powerful for dynamic resource lookup + +**4. Free Tier Configuration** +- **Issue**: Ensuring configuration stays within free tier limits +- **Solution**: Set `core_fraction = 20`, used network-hdd, 10 GB disk +- **Learning**: Important to understand cloud provider pricing models + +### Terraform Commands Output + +#### terraform init + +```bash +$ cd terraform/ +terraform init + +Initializing the backend... + +Initializing provider plugins... +- Finding yandex-cloud/yandex versions matching "~> 0.100"... +- Finding integrations/github versions matching "~> 5.0"... +- Installing yandex-cloud/yandex v0.187.0... +- Installed yandex-cloud/yandex v0.187.0 (unauthenticated) +- Installing integrations/github v5.45.0... +- Installed integrations/github v5.45.0 (unauthenticated) + +Terraform has created a lock file .terraform.lock.hcl to record the provider +selections it made above. Include this file in your version control repository +so that Terraform can guarantee to make the same selections by default when +you run "terraform init" in the future. + +╷ +│ Warning: Incomplete lock file information for providers +│ +│ Due to your customized provider installation methods, Terraform was forced to calculate lock file checksums +│ locally for the following providers: +│ - integrations/github +│ - yandex-cloud/yandex +│ +│ The current .terraform.lock.hcl file only includes checksums for darwin_arm64, so Terraform running on another +│ platform will fail to install these providers. +│ +│ To calculate additional checksums for another platform, run: +│ terraform providers lock -platform=linux_amd64 +│ (where linux_amd64 is the platform to generate) +╵ + +Terraform has been successfully initialized! + +You may now begin working with Terraform. Try running "terraform plan" to see +any changes that are required for your infrastructure. All Terraform commands +should now work. + +If you ever set or change modules or backend configuration for Terraform, +rerun this command to reinitialize your working directory. If you forget, other +commands will detect it and remind you to do so if necessary. +``` + +#### terraform plan + +```bash +terraform plan +var.cloud_id + Yandex Cloud ID + + Enter a value: ******** + +data.yandex_compute_image.ubuntu: Reading... +data.yandex_compute_image.ubuntu: Read complete after 0s [id=********] + +Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # github_branch_protection.master_protection will be created + + resource "github_branch_protection" "master_protection" { + + allows_deletions = false + + allows_force_pushes = false + + blocks_creations = false + + enforce_admins = false + + id = (known after apply) + + lock_branch = false + + pattern = "master" + + repository_id = (known after apply) + + require_conversation_resolution = false + + require_signed_commits = false + + required_linear_history = false + + + required_pull_request_reviews { + + dismiss_stale_reviews = true + + require_code_owner_reviews = false + + require_last_push_approval = false + + required_approving_review_count = 0 + } + } + + # github_repository.devops_course will be created + + resource "github_repository" "devops_course" { + + allow_auto_merge = false + + allow_merge_commit = true + + allow_rebase_merge = true + + allow_squash_merge = true + + archived = false + + default_branch = (known after apply) + + delete_branch_on_merge = true + + description = "DevOps Engineering: Core Practices - Lab assignments and projects" + + etag = (known after apply) + + full_name = (known after apply) + + git_clone_url = (known after apply) + + has_downloads = true + + has_issues = true + + has_projects = false + + has_wiki = false + + html_url = (known after apply) + + http_clone_url = (known after apply) + + id = (known after apply) + + merge_commit_message = "PR_TITLE" + + merge_commit_title = "MERGE_MESSAGE" + + name = "DevOps-Core-Course" + + node_id = (known after apply) + + primary_language = (known after apply) + + private = (known after apply) + + repo_id = (known after apply) + + squash_merge_commit_message = "COMMIT_MESSAGES" + + squash_merge_commit_title = "COMMIT_OR_PR_TITLE" + + ssh_clone_url = (known after apply) + + svn_url = (known after apply) + + topics = [ + + "ansible", + + "ci-cd", + + "devops", + + "docker", + + "infrastructure-as-code", + + "kubernetes", + + "pulumi", + + "terraform", + ] + + visibility = "public" + + web_commit_signoff_required = false + } + + # yandex_compute_instance.lab04_vm will be created + + resource "yandex_compute_instance" "lab04_vm" { + + created_at = (known after apply) + + folder_id = (known after apply) + + fqdn = (known after apply) + + gpu_cluster_id = (known after apply) + + hardware_generation = (known after apply) + + hostname = "lab04-vm" + + id = (known after apply) + + labels = { + + "environment" = "lab04" + + "managed_by" = "terraform" + + "purpose" = "devops-course" + } + + maintenance_grace_period = (known after apply) + + maintenance_policy = (known after apply) + + metadata = { + + "ssh-keys" = <<-EOT + ************************ + EOT + } + + name = "lab04-vm" + + network_acceleration_type = "standard" + + platform_id = "standard-v2" + + status = (known after apply) + + zone = "ru-central1-a" + + + boot_disk { + + auto_delete = true + + device_name = (known after apply) + + disk_id = (known after apply) + + mode = (known after apply) + + + initialize_params { + + block_size = (known after apply) + + description = (known after apply) + + image_id = "fd8lt661chfo5i13a40d" + + name = (known after apply) + + size = 10 + + snapshot_id = (known after apply) + + type = "network-hdd" + } + } + + + network_interface { + + index = (known after apply) + + ip_address = (known after apply) + + ipv4 = true + + ipv6 = (known after apply) + + ipv6_address = (known after apply) + + mac_address = (known after apply) + + nat = true + + nat_ip_address = (known after apply) + + nat_ip_version = (known after apply) + + subnet_id = (known after apply) + } + + + resources { + + core_fraction = 20 + + cores = 2 + + memory = 1 + } + + + scheduling_policy { + + preemptible = false + } + } + + # yandex_vpc_network.lab04_network will be created + + resource "yandex_vpc_network" "lab04_network" { + + created_at = (known after apply) + + default_security_group_id = (known after apply) + + description = "Network for Lab 04 VM" + + folder_id = (known after apply) + + id = (known after apply) + + labels = (known after apply) + + name = "lab04-network" + + subnet_ids = (known after apply) + } + + # yandex_vpc_subnet.lab04_subnet will be created + + resource "yandex_vpc_subnet" "lab04_subnet" { + + created_at = (known after apply) + + description = "Subnet for Lab 04 VM" + + folder_id = (known after apply) + + id = (known after apply) + + labels = (known after apply) + + name = "lab04-subnet" + + network_id = (known after apply) + + v4_cidr_blocks = [ + + "10.128.0.0/24", + ] + + v6_cidr_blocks = (known after apply) + + zone = "ru-central1-a" + } + +Plan: 5 to add, 0 to change, 0 to destroy. + +Changes to Outputs: + + connection_info = { + + private_ip = (known after apply) + + public_ip = (known after apply) + + ssh_command = (known after apply) + + ssh_user = "ubuntu" + } + + network_id = (known after apply) + + ssh_command = (known after apply) + + subnet_id = (known after apply) + + vm_id = (known after apply) + + vm_name = "lab04-vm" + + vm_private_ip = (known after apply) + + vm_public_ip = (known after apply) + +────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + +Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now. +``` + +#### terraform apply + +```bash +terraform apply +var.cloud_id + Yandex Cloud ID + + Enter a value: ****** + +github_repository.devops_course: Refreshing state... [id=DevOps-Core-Course] +data.yandex_compute_image.ubuntu: Reading... +yandex_vpc_network.lab04_network: Refreshing state... [id=******] +data.yandex_compute_image.ubuntu: Read complete after 0s [id=******] +yandex_vpc_subnet.lab04_subnet: Refreshing state... [id=******] +yandex_compute_instance.lab04_vm: Refreshing state... [id=******] +github_branch_protection.master_protection: Refreshing state... [id=B******] + +Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with +the following symbols: +-/+ destroy and then create replacement + +Terraform will perform the following actions: + + # github_branch_protection.master_protection is tainted, so must be replaced +-/+ resource "github_branch_protection" "master_protection" { + - force_push_bypassers = [] -> null + ~ id = "******" -> (known after apply) + - push_restrictions = [] -> null + # (10 unchanged attributes hidden) + + ~ required_pull_request_reviews { + - dismissal_restrictions = [] -> null + - pull_request_bypassers = [] -> null + - restrict_dismissals = false -> null + # (4 unchanged attributes hidden) + } + } + +Plan: 1 to add, 0 to change, 1 to destroy. + +Do you want to perform these actions? + Terraform will perform the actions described above. + Only 'yes' will be accepted to approve. + + Enter a value: yes + +github_branch_protection.master_protection: Destroying... [id=******] +github_branch_protection.master_protection: Destruction complete after 0s +github_branch_protection.master_protection: Creating... +github_branch_protection.master_protection: Creation complete after 4s [id=******] + +Apply complete! Resources: 1 added, 0 changed, 1 destroyed. + +Outputs: + +connection_info = { + "private_ip" = "10.128.0.11" + "public_ip" = "84.201.128.171" + "ssh_command" = "ssh ubuntu@84.201.128.171" + "ssh_user" = "ubuntu" +} +network_id = "enp5kqg9rma6c31bjsen" +ssh_command = "ssh ubuntu@84.201.128.171" +subnet_id = "e9bl6fnifjfbe7ufp7tl" +vm_id = "fhmbajpub1spksjhkvct" +vm_name = "lab04-vm" +vm_private_ip = "10.128.0.11" +vm_public_ip = "84.201.128.171" +``` + +### SSH Connection Verification + +```bash +ssh -i ~/.ssh/yandex_cloud_key ubuntu@84.201.128.171 +Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.8.0-100-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/pro + + System information as of Mon Feb 16 23:12:16 UTC 2026 + + System load: 0.0 Processes: 96 + Usage of /: 23.1% of 9.04GB Users logged in: 0 + Memory usage: 17% IPv4 address for eth0: 10.128.0.11 + Swap usage: 0% + + +Expanded Security Maintenance for Applications is not enabled. + +0 updates can be applied immediately. + +Enable ESM Apps to receive additional future security updates. +See https://ubuntu.com/esm or run: sudo pro status + + + +The programs included with the Ubuntu system are free software; +the exact distribution terms for each program are described in the +individual files in /usr/share/doc/*/copyright. + +Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by +applicable law. + +To run a command as administrator (user "root"), use "sudo ". +See "man sudo_root" for details. + +ubuntu@lab04-vm:~$ +``` + +--- + +## 3. Pulumi Implementation + +### Pulumi Version and Language + +```bash +Pulumi v3.220.0 +Python 3.9.6 +pulumi-yandex v0.13.0 +``` + +**Language Choice: Python** + +### Code Differences from Terraform + +**1. Language Paradigm** + +**Terraform (Declarative HCL):** +```hcl +resource "yandex_vpc_network" "lab04_network" { + name = "lab04-network" + description = "Network for Lab 04 VM" +} +``` + +**Pulumi (Imperative Python):** +```python +network = yandex.VpcNetwork( + "lab04-network", + name="lab04-pulumi-network", + description="Network for Lab 04 Pulumi VM", + folder_id=folder_id +) +``` + +**Key Differences:** +- Terraform: Resource blocks with attributes +- Pulumi: Object instantiation with constructor arguments +- Terraform: Static configuration +- Pulumi: Can use variables, loops, functions naturally + +**2. Configuration Management** + +**Terraform:** +```hcl +# variables.tf +variable "folder_id" { + description = "Yandex Cloud folder ID" + type = string +} + +# terraform.tfvars +folder_id = "b1g..." +``` + +**Pulumi:** +```python +# __main__.py +config = pulumi.Config() +folder_id = config.require("folder_id") + +# Command line +pulumi config set lab04-pulumi:folder_id b1g... +``` + +**Key Differences:** +- Terraform: Separate variable files +- Pulumi: Config object in code +- Terraform: tfvars files +- Pulumi: Stack-specific YAML files or CLI commands + +**3. Outputs** + +**Terraform:** +```hcl +output "vm_public_ip" { + description = "Public IP address of the VM" + value = yandex_compute_instance.lab04_vm.network_interface[0].nat_ip_address +} +``` + +**Pulumi:** +```python +pulumi.export("vm_public_ip", vm.network_interfaces[0].nat_ip_address) + +# For computed values +pulumi.export("ssh_command", vm.network_interfaces[0].nat_ip_address.apply( + lambda ip: f"ssh {ssh_user}@{ip}" +)) +``` + +**Key Differences:** +- Terraform: Output blocks +- Pulumi: Export function calls +- Pulumi: `.apply()` for working with computed values (Promises) + +**4. Resource Dependencies** + +**Terraform:** +```hcl +# Implicit dependencies through references +resource "yandex_vpc_subnet" "lab04_subnet" { + network_id = yandex_vpc_network.lab04_network.id # Implicit dependency +} +``` + +**Pulumi:** +```python +# Same implicit dependencies through references +subnet = yandex.VpcSubnet( + "lab04-subnet", + network_id=network.id # Implicit dependency +) +``` + +**Key Differences:** +- Both handle dependencies automatically +- Pulumi can use explicit `depends_on` if needed +- Pulumi's type system helps catch errors earlier + +### Advantages Discovered + +**1. Programming Language Features** + + **Loops and Conditionals:** +```python +# Easy to create multiple similar resources +for i in range(3): + subnet = yandex.VpcSubnet(f"subnet-{i}", ...) + +# Conditional resource creation +if config.get_bool("enable_monitoring"): + monitoring = yandex.MonitoringDashboard(...) +``` + + **Functions and Reusability:** +```python +def create_security_rule(port, description): + return yandex.VpcSecurityGroupIngressArgs( + protocol="TCP", + description=description, + v4_cidr_blocks=["0.0.0.0/0"], + port=port + ) + +# Use function to create rules +ingress=[ + create_security_rule(22, "Allow SSH"), + create_security_rule(80, "Allow HTTP"), + create_security_rule(5000, "Allow app port 5000"), +] +``` + + **Error Handling:** +```python +try: + with open(ssh_public_key_path, "r") as f: + ssh_public_key = f.read().strip() +except FileNotFoundError: + raise Exception(f"SSH public key not found at {ssh_public_key_path}") +``` + +**2. IDE Support** + + **Autocomplete:** +- IDE suggests available properties +- Type hints show expected types +- Inline documentation + + **Type Checking:** +- Catch errors before deployment +- Better refactoring support +- Clear error messages + +**3. Testing Capabilities** + + **Unit Tests:** +```python +# Can write unit tests for infrastructure +import unittest +from pulumi import runtime + +class TestInfrastructure(unittest.TestCase): + @pulumi.runtime.test + def test_vm_has_correct_size(self): + # Test infrastructure code + pass +``` + +**4. Secrets Management** + + **Encrypted by Default:** +```bash +pulumi config set --secret github_token ghp_... +# Automatically encrypted in Pulumi.*.yaml +``` + + **No Plain Text in State:** +- Secrets encrypted in state file +- Safer than Terraform's plain text state + +### Challenges Encountered + +**1. Learning Curve** +- **Issue**: Understanding Pulumi's async/promise model (`.apply()`) +- **Solution**: Read documentation on Output types and computed values +- **Learning**: Pulumi's Output type handles async resource creation + +**2. Provider Documentation** +- **Issue**: Yandex Cloud Pulumi provider has less documentation than Terraform +- **Solution**: Referred to Terraform docs and translated to Pulumi syntax +- **Learning**: Terraform has larger community and more examples + +**4. Python Path Issues** +- **Issue**: SSH key path with `~` not expanding correctly +- **Solution**: Added manual path expansion in code +- **Learning**: Need to handle OS-specific path issues in code + +### Pulumi Commands Output + +#### pulumi preview + +```bash +pulumi preview +Enter your passphrase to unlock config/secrets + (set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember): +Enter your passphrase to unlock config/secrets +Previewing update (dev): + Type Name Plan + + pulumi:pulumi:Stack lab04-pulumi-dev create + + ├─ yandex:index:VpcNetwork lab04-network create + + ├─ yandex:index:VpcSubnet lab04-subnet create + + ├─ yandex:index:VpcSecurityGroup lab04-sg create + + └─ yandex:index:ComputeInstance lab04-vm create + +Outputs: + connection_info: { + private_ip : [unknown] + public_ip : [unknown] + ssh_command: [unknown] + ssh_user : "ubuntu" + } + network_id : [unknown] + ssh_command : [unknown] + subnet_id : [unknown] + vm_id : [unknown] + vm_name : "lab04-pulumi-vm" + vm_private_ip : [unknown] + vm_public_ip : [unknown] + +Resources: + + 5 to create + +(venv) newspec@10 pulumi % +``` + +#### pulumi up + +```bash +pulumi up +Enter your passphrase to unlock config/secrets + (set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember): +Enter your passphrase to unlock config/secrets +Previewing update (dev): + Type Name Plan + + pulumi:pulumi:Stack lab04-pulumi-dev create + + ├─ yandex:index:VpcNetwork lab04-network create + + ├─ yandex:index:VpcSubnet lab04-subnet create + + ├─ yandex:index:VpcSecurityGroup lab04-sg create + + └─ yandex:index:ComputeInstance lab04-vm create + +Outputs: + connection_info: { + private_ip : [unknown] + public_ip : [unknown] + ssh_command: [unknown] + ssh_user : "ubuntu" + } + network_id : [unknown] + ssh_command : [unknown] + subnet_id : [unknown] + vm_id : [unknown] + vm_name : "lab04-pulumi-vm" + vm_private_ip : [unknown] + vm_public_ip : [unknown] + +Resources: + + 5 to create + +Do you want to perform this update? yes +Updating (dev): + Type Name Status + + pulumi:pulumi:Stack lab04-pulumi-dev created (41s) + + ├─ yandex:index:VpcNetwork lab04-network created (1s) + + ├─ yandex:index:VpcSecurityGroup lab04-sg created (1s) + + ├─ yandex:index:VpcSubnet lab04-subnet created (0.43s) + + └─ yandex:index:ComputeInstance lab04-vm created (38s) + +Outputs: + connection_info: { + private_ip : "10.128.0.13" + public_ip : "84.201.128.246" + ssh_command: "ssh ubuntu@84.201.128.246" + ssh_user : "ubuntu" + } + network_id : "enpej60jp6arufbqcu7g" + ssh_command : "ssh ubuntu@84.201.128.246" + subnet_id : "e9bdpptsdf2nafbj1s10" + vm_id : "fhmvjrq2012fqg0mloc8" + vm_name : "lab04-pulumi-vm" + vm_private_ip : "10.128.0.13" + vm_public_ip : "84.201.128.246" + +Resources: + + 5 created + +Duration: 42s +``` + +### SSH Connection Verification + +```bash +ssh -i ~/.ssh/yandex_cloud_key ubuntu@84.201.128.246 +Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.8.0-100-generic x86_64) + + * Documentation: https://help.ubuntu.com + * Management: https://landscape.canonical.com + * Support: https://ubuntu.com/pro + + System information as of Mon Feb 16 23:50:44 UTC 2026 + + System load: 0.01 Processes: 99 + Usage of /: 23.1% of 9.04GB Users logged in: 0 + Memory usage: 17% IPv4 address for eth0: 10.128.0.13 + Swap usage: 0% + + +Expanded Security Maintenance for Applications is not enabled. + +0 updates can be applied immediately. + +Enable ESM Apps to receive additional future security updates. +See https://ubuntu.com/esm or run: sudo pro status + + + +The programs included with the Ubuntu system are free software; +the exact distribution terms for each program are described in the +individual files in /usr/share/doc/*/copyright. + +Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by +applicable law. + + +To run a command as administrator (user "root"), use "sudo ". +See "man sudo_root" for details. + +ubuntu@lab04-pulumi-vm:~$ +``` +--- + +## 4. Terraform vs Pulumi Comparison + +### Ease of Learning + +**Terraform: (4/5)** + +**Pros:** +- Simple, declarative syntax +- Easy to understand resource blocks +- Extensive documentation and examples +- Large community with many tutorials +- Consistent patterns across providers + +**Cons:** +- Need to learn HCL syntax +- Limited logic capabilities +- Some concepts (count, for_each) can be confusing + +**Pulumi: (3/5)** + +**Pros:** +- Use familiar programming language +- No new syntax to learn (if you know Python) +- Natural use of variables and functions + +**Cons:** +- Need to understand Output/Promise model +- Async concepts can be confusing +- Less community content and examples +- Requires programming knowledge + +**Winner: Terraform** - Lower barrier to entry, especially for those without programming background. + +### Code Readability + +**Terraform: (5/5)** + +**Pros:** +- Very clear and declarative +- Easy to see what infrastructure will be created +- Consistent structure across all resources +- Self-documenting with descriptions + +**Pulumi: (4/5)** + +**Pros:** +- Familiar Python syntax +- Can add comments and documentation strings +- Type hints improve clarity +- IDE shows inline documentation + +**Cons:** +- More verbose than HCL +- Mixing infrastructure and logic can reduce clarity +- Need to understand Python conventions + +**Winner: Terraform** - More concise and purpose-built for infrastructure. + +### Debugging + +**Terraform: (3/5)** + +**Pros:** +- Clear error messages +- `terraform plan` shows what will change +- Can use `terraform console` for testing expressions +- State file helps understand current state + +**Cons:** +- Limited debugging tools +- Hard to debug complex expressions +- No step-through debugging +- Error messages can be cryptic for complex scenarios + +**Pulumi: (4/5)** + +**Pros:** +- Can use Python debugger (pdb) +- IDE debugging support +- Better error messages with stack traces +- Can add print statements for debugging +- Unit testing capabilities + +**Cons:** +- Async nature can complicate debugging +- Output types require `.apply()` understanding + +**Winner: Pulumi** - Full programming language debugging capabilities. + +### Documentation + +**Terraform: (5/5)** + +**Pros:** +- Extensive official documentation +- Large community with many examples +- Provider documentation in Terraform Registry +- Many tutorials and courses +- Stack Overflow has many answers + +**Cons:** +- Documentation can be overwhelming +- Some providers have better docs than others + +**Pulumi: (3/5)** + +**Pros:** +- Good official documentation +- API reference auto-generated +- Examples in multiple languages +- Good getting started guides + +**Cons:** +- Smaller community +- Fewer third-party tutorials +- Less Stack Overflow content +- Provider docs sometimes less detailed + +**Winner: Terraform** - Much larger ecosystem and community. + +### Use Cases + +**When to Use Terraform:** + + **Simple to Medium Infrastructure** +- Straightforward resource provisioning +- Standard cloud patterns +- Team prefers declarative approach + + **Multi-Cloud Deployments** +- Largest provider ecosystem +- Consistent syntax across clouds +- Mature and stable + + **Compliance and Governance** +- Clear audit trail +- Policy as code (Sentinel) +- Established best practices + + **Team Without Programming Background** +- DevOps/Ops teams +- Infrastructure-focused roles +- Lower learning curve + +**When to Use Pulumi:** + + **Complex Infrastructure Logic** +- Dynamic resource creation +- Complex conditionals +- Advanced transformations + + **Developer-Centric Teams** +- Software engineers managing infrastructure +- Want to use familiar languages +- Need testing capabilities + + **Reusable Components** +- Building infrastructure libraries +- Sharing code via packages +- Higher-level abstractions + + **Better Secrets Management** +- Need encrypted secrets +- Compliance requirements +- Sensitive data handling + +## 5. Lab 5 Preparation & Cleanup + +### VM for Lab 5 + +**Are you keeping your VM for Lab 5?** No + +**What will you use for Lab 5?** Will recreate cloud VM + +**Terrafrom destroy**: +```bash +terraform destroy +var.cloud_id + Yandex Cloud ID + + Enter a value: ******** + +github_repository.devops_course: Refreshing state... [id=DevOps-Core-Course] +data.yandex_compute_image.ubuntu: Reading... +data.yandex_compute_image.ubuntu: Read complete after 0s [id=*******] + +Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + - destroy + +Terraform will perform the following actions: + + # github_repository.devops_course will be destroyed + - resource "github_repository" "devops_course" { + - allow_auto_merge = false -> null + - allow_merge_commit = true -> null + - allow_rebase_merge = true -> null + - allow_squash_merge = true -> null + - allow_update_branch = false -> null + - archived = false -> null + - auto_init = false -> null + - default_branch = "master" -> null + - delete_branch_on_merge = true -> null + - description = "DevOps Engineering: Core Practices - Lab assignments and projects" -> null + - etag = "W/\"8f88878a50eedec268e373e039998430cbf194a2a9e0c3ff93a27116412b1b69\"" -> null + - full_name = "newspec/DevOps-Core-Course" -> null + - git_clone_url = "git://github.com/newspec/DevOps-Core-Course.git" -> null + - has_discussions = false -> null + - has_downloads = true -> null + - has_issues = true -> null + - has_projects = false -> null + - has_wiki = false -> null + - html_url = "https://github.com/newspec/DevOps-Core-Course" -> null + - http_clone_url = "https://github.com/newspec/DevOps-Core-Course.git" -> null + - id = "DevOps-Core-Course" -> null + - is_template = false -> null + - merge_commit_message = "PR_TITLE" -> null + - merge_commit_title = "MERGE_MESSAGE" -> null + - name = "DevOps-Core-Course" -> null + - node_id = "R_kgDORA7Qvw" -> null + - private = false -> null + - repo_id = 1141821631 -> null + - squash_merge_commit_message = "COMMIT_MESSAGES" -> null + - squash_merge_commit_title = "COMMIT_OR_PR_TITLE" -> null + - ssh_clone_url = "git@github.com:newspec/DevOps-Core-Course.git" -> null + - svn_url = "https://github.com/newspec/DevOps-Core-Course" -> null + - topics = [ + - "ansible", + - "ci-cd", + - "devops", + - "docker", + - "infrastructure-as-code", + - "kubernetes", + - "pulumi", + - "terraform", + ] -> null + - visibility = "public" -> null + - vulnerability_alerts = false -> null + - web_commit_signoff_required = false -> null + + - security_and_analysis { + - secret_scanning { + - status = "enabled" -> null + } + - secret_scanning_push_protection { + - status = "enabled" -> null + } + } + } + +Plan: 0 to add, 0 to change, 1 to destroy. + +Changes to Outputs: + - vm_name = "lab04-vm" -> null + +Do you really want to destroy all resources? + Terraform will destroy all your managed infrastructure, as shown above. + There is no undo. Only 'yes' will be accepted to confirm. + + Enter a value: yes + +github_repository.devops_course: Destroying... [id=DevOps-Core-Course] +╷ +│ Error: DELETE https://api.github.com/repos/newspec/DevOps-Core-Course: 403 Must have admin rights to Repository. [] +│ +│ +╵ +``` +**pulumi destroy**: +```bash +pulumi destroy +Enter your passphrase to unlock config/secrets + (set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember): +Enter your passphrase to unlock config/secrets +Previewing destroy (dev): + Type Name Plan + - pulumi:pulumi:Stack lab04-pulumi-dev delete + - ├─ yandex:index:VpcNetwork lab04-network delete + - ├─ yandex:index:ComputeInstance lab04-vm delete + - ├─ yandex:index:VpcSubnet lab04-subnet delete + - └─ yandex:index:VpcSecurityGroup lab04-sg delete + +Outputs: + - connection_info: { + - private_ip : "10.128.0.13" + - public_ip : "84.201.128.246" + - ssh_command: "ssh ubuntu@84.201.128.246" + - ssh_user : "ubuntu" + } + - network_id : "enpej60jp6arufbqcu7g" + - ssh_command : "ssh ubuntu@84.201.128.246" + - subnet_id : "e9bdpptsdf2nafbj1s10" + - vm_id : "fhmvjrq2012fqg0mloc8" + - vm_name : "lab04-pulumi-vm" + - vm_private_ip : "10.128.0.13" + - vm_public_ip : "84.201.128.246" + +Resources: + - 5 to delete + +Do you want to perform this destroy? yes +Destroying (dev): + Type Name Status + - pulumi:pulumi:Stack lab04-pulumi-dev deleted (0.01s) + - ├─ yandex:index:ComputeInstance lab04-vm deleted (33s) + - ├─ yandex:index:VpcSubnet lab04-subnet deleted (4s) + - ├─ yandex:index:VpcSecurityGroup lab04-sg deleted (0.43s) + - └─ yandex:index:VpcNetwork lab04-network deleted (1s) + +Outputs: + - connection_info: { + - private_ip : "10.128.0.13" + - public_ip : "84.201.128.246" + - ssh_command: "ssh ubuntu@84.201.128.246" + - ssh_user : "ubuntu" + } + - network_id : "enpej60jp6arufbqcu7g" + - ssh_command : "ssh ubuntu@84.201.128.246" + - subnet_id : "e9bdpptsdf2nafbj1s10" + - vm_id : "fhmvjrq2012fqg0mloc8" + - vm_name : "lab04-pulumi-vm" + - vm_private_ip : "10.128.0.13" + - vm_public_ip : "84.201.128.246" + +Resources: + - 5 deleted + +Duration: 40s + +The resources in the stack have been deleted, but the history and configuration associated with the stack are still maintained. +If you want to remove the stack completely, run `pulumi stack rm dev`. +``` + +**screenshot showing resource status:** ![alt text](image.png) diff --git a/docs/image.png b/docs/image.png new file mode 100644 index 0000000000000000000000000000000000000000..83ce4aa12fa0e67b6863632b1a035c698bf45400 GIT binary patch literal 181869 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 M8C)v7c7cK`qY literal 0 HcmV?d00001 diff --git a/pulumi/Pulumi.yaml b/pulumi/Pulumi.yaml new file mode 100644 index 0000000000..0e9b5069df --- /dev/null +++ b/pulumi/Pulumi.yaml @@ -0,0 +1,3 @@ +name: lab04-pulumi +runtime: python +description: Lab 04 - Infrastructure as Code with Pulumi (Yandex Cloud) \ No newline at end of file diff --git a/pulumi/__main__.py b/pulumi/__main__.py new file mode 100644 index 0000000000..00429f2be9 --- /dev/null +++ b/pulumi/__main__.py @@ -0,0 +1,146 @@ +""" +Lab 04 - Pulumi Infrastructure as Code +Provisions a VM on Yandex Cloud with network and security configuration +""" + +import pulumi +import pulumi_yandex as yandex + +# Get configuration +config = pulumi.Config() +folder_id = config.require("folder_id") +zone = config.get("zone") or "ru-central1-a" +vm_name = config.get("vm_name") or "lab04-pulumi-vm" +ssh_user = config.get("ssh_user") or "ubuntu" +ssh_public_key_path = config.get("ssh_public_key_path") or "~/.ssh/id_rsa.pub" +ssh_allowed_cidr = config.require("ssh_allowed_cidr") # CIDR allowed to SSH, e.g. 203.0.113.10/32 + +# Read SSH public key +with open(ssh_public_key_path.replace("~", pulumi.runtime.get_config("HOME") or "~"), "r") as f: + ssh_public_key = f.read().strip() + +# Get latest Ubuntu 24.04 image +ubuntu_image = yandex.get_compute_image( + family="ubuntu-2404-lts", + folder_id="standard-images" +) + +# Create VPC network +network = yandex.VpcNetwork( + "lab04-network", + name="lab04-pulumi-network", + description="Network for Lab 04 Pulumi VM", + folder_id=folder_id +) + +# Create subnet +subnet = yandex.VpcSubnet( + "lab04-subnet", + name="lab04-pulumi-subnet", + description="Subnet for Lab 04 Pulumi VM", + v4_cidr_blocks=["10.128.0.0/24"], + zone=zone, + network_id=network.id, + folder_id=folder_id +) + +# Create security group +security_group = yandex.VpcSecurityGroup( + "lab04-sg", + name="lab04-pulumi-security-group", + description="Security group for Lab 04 Pulumi VM", + network_id=network.id, + folder_id=folder_id, + ingresses=[ + # Allow SSH from specific IP + yandex.VpcSecurityGroupIngressArgs( + protocol="TCP", + description="Allow SSH from my IP", + v4_cidr_blocks=[ssh_allowed_cidr], + port=22 + ), + # Allow HTTP + yandex.VpcSecurityGroupIngressArgs( + protocol="TCP", + description="Allow HTTP", + v4_cidr_blocks=["0.0.0.0/0"], + port=80 + ), + # Allow custom port 5000 + yandex.VpcSecurityGroupIngressArgs( + protocol="TCP", + description="Allow app port 5000", + v4_cidr_blocks=["0.0.0.0/0"], + port=5000 + ), + ], + egresses=[ + # Allow all outbound traffic + yandex.VpcSecurityGroupEgressArgs( + protocol="ANY", + description="Allow all outbound traffic", + v4_cidr_blocks=["0.0.0.0/0"], + from_port=0, + to_port=65535 + ), + ] +) + +# Create VM instance +vm = yandex.ComputeInstance( + "lab04-vm", + name=vm_name, + hostname=vm_name, + platform_id="standard-v2", + zone=zone, + folder_id=folder_id, + resources=yandex.ComputeInstanceResourcesArgs( + cores=2, + memory=1, + core_fraction=20 # Free tier: 20% CPU + ), + boot_disk=yandex.ComputeInstanceBootDiskArgs( + initialize_params=yandex.ComputeInstanceBootDiskInitializeParamsArgs( + image_id=ubuntu_image.id, + size=10, # 10 GB + type="network-hdd" + ) + ), + network_interfaces=[ + yandex.ComputeInstanceNetworkInterfaceArgs( + subnet_id=subnet.id, + nat=True, # Assign public IP + security_group_ids=[security_group.id] + ) + ], + metadata={ + "ssh-keys": f"{ssh_user}:{ssh_public_key}" + }, + labels={ + "environment": "lab04", + "managed_by": "pulumi", + "purpose": "devops-course" + }, + scheduling_policy=yandex.ComputeInstanceSchedulingPolicyArgs( + preemptible=False + ) +) + +# Export outputs +pulumi.export("vm_id", vm.id) +pulumi.export("vm_name", vm.name) +pulumi.export("vm_public_ip", vm.network_interfaces[0].nat_ip_address) +pulumi.export("vm_private_ip", vm.network_interfaces[0].ip_address) +pulumi.export("network_id", network.id) +pulumi.export("subnet_id", subnet.id) +pulumi.export("ssh_command", vm.network_interfaces[0].nat_ip_address.apply( + lambda ip: f"ssh {ssh_user}@{ip}" +)) +pulumi.export("connection_info", { + "public_ip": vm.network_interfaces[0].nat_ip_address, + "private_ip": vm.network_interfaces[0].ip_address, + "ssh_user": ssh_user, + "ssh_command": vm.network_interfaces[0].nat_ip_address.apply( + lambda ip: f"ssh {ssh_user}@{ip}" + ) +}) \ No newline at end of file diff --git a/pulumi/requirements.txt b/pulumi/requirements.txt new file mode 100644 index 0000000000..2356228903 --- /dev/null +++ b/pulumi/requirements.txt @@ -0,0 +1,2 @@ +pulumi>=3.0.0,<4.0.0 +pulumi-yandex>=0.13.0 \ No newline at end of file diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl new file mode 100644 index 0000000000..90ce0f0af0 --- /dev/null +++ b/terraform/.terraform.lock.hcl @@ -0,0 +1,18 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/integrations/github" { + version = "5.45.0" + constraints = "~> 5.0" + hashes = [ + "h1:sP/Er9osOsz4vhKZAul+GeV0c5XdvMblJBMiP+T5tWc=", + ] +} + +provider "registry.terraform.io/yandex-cloud/yandex" { + version = "0.187.0" + constraints = "~> 0.100" + hashes = [ + "h1:+uf4EBRLDwNYIvZsGK/ZUzN3sGzJaXcUngyYSIJoyyQ=", + ] +} diff --git a/terraform/.terraformrc b/terraform/.terraformrc new file mode 100644 index 0000000000..9bc7728211 --- /dev/null +++ b/terraform/.terraformrc @@ -0,0 +1,9 @@ +provider_installation { + network_mirror { + url = "https://terraform-mirror.yandexcloud.net/" + include = ["registry.terraform.io/*/*"] + } + direct { + exclude = ["registry.terraform.io/*/*"] + } +} \ No newline at end of file diff --git a/terraform/.tflint.hcl b/terraform/.tflint.hcl new file mode 100644 index 0000000000..6711210ee7 --- /dev/null +++ b/terraform/.tflint.hcl @@ -0,0 +1,30 @@ +plugin "terraform" { + enabled = true + preset = "recommended" +} + +plugin "yandex" { + enabled = true + version = "0.1.0" + source = "github.com/yandex-cloud/tflint-ruleset-yandex-cloud" +} + +rule "terraform_naming_convention" { + enabled = true +} + +rule "terraform_documented_variables" { + enabled = true +} + +rule "terraform_documented_outputs" { + enabled = true +} + +rule "terraform_unused_declarations" { + enabled = true +} + +rule "terraform_deprecated_index" { + enabled = true +} \ No newline at end of file diff --git a/terraform/github.tf b/terraform/github.tf new file mode 100644 index 0000000000..39b5a40c02 --- /dev/null +++ b/terraform/github.tf @@ -0,0 +1,52 @@ +# GitHub Provider Configuration for Repository Management +# This file demonstrates importing existing infrastructure into Terraform +# Note: required_providers for github is defined in main.tf + +provider "github" { + token = var.github_token + owner = var.github_owner +} + +# Import existing DevOps-Core-Course repository +resource "github_repository" "devops_course" { + name = "DevOps-Core-Course" + description = "DevOps Engineering: Core Practices - Lab assignments and projects" + visibility = "public" + + has_issues = true + has_wiki = false + has_projects = false + has_downloads = true + + allow_merge_commit = true + allow_squash_merge = true + allow_rebase_merge = true + allow_auto_merge = false + + delete_branch_on_merge = true + + topics = [ + "devops", + "terraform", + "pulumi", + "docker", + "kubernetes", + "ansible", + "ci-cd", + "infrastructure-as-code" + ] +} + +# Branch protection for master branch (optional) +resource "github_branch_protection" "master_protection" { + repository_id = github_repository.devops_course.node_id + pattern = "master" + + required_pull_request_reviews { + dismiss_stale_reviews = true + require_code_owner_reviews = false + required_approving_review_count = 0 + } + + enforce_admins = false +} \ No newline at end of file diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 0000000000..1b24dfba9f --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,118 @@ +terraform { + required_providers { + yandex = { + source = "yandex-cloud/yandex" + version = "~> 0.187" + } + github = { + source = "integrations/github" + version = "~> 5.0" + } + } + required_version = ">= 1.9.0" +} + +provider "yandex" { + service_account_key_file = pathexpand(var.service_account_key_file) + cloud_id = var.cloud_id + folder_id = var.folder_id + zone = var.zone +} + +# Get latest Ubuntu 24.04 image +data "yandex_compute_image" "ubuntu" { + family = "ubuntu-2404-lts" +} + +# Create VPC network +resource "yandex_vpc_network" "lab04_network" { + name = "lab04-network" + description = "Network for Lab 04 VM" +} + +# Create subnet +resource "yandex_vpc_subnet" "lab04_subnet" { + name = "lab04-subnet" + description = "Subnet for Lab 04 VM" + v4_cidr_blocks = ["10.128.0.0/24"] + zone = var.zone + network_id = yandex_vpc_network.lab04_network.id +} + +# Create security group with required rules +resource "yandex_vpc_security_group" "lab04_sg" { + name = "lab04-sg" + description = "Lab04 security group" + network_id = yandex_vpc_network.lab04_network.id + + ingress { + protocol = "TCP" + description = "SSH from my IP" + v4_cidr_blocks = [var.ssh_allowed_cidr] + port = 22 + } + + ingress { + protocol = "TCP" + description = "HTTP" + v4_cidr_blocks = ["0.0.0.0/0"] + port = 80 + } + + ingress { + protocol = "TCP" + description = "App 5000" + v4_cidr_blocks = ["0.0.0.0/0"] + port = 5000 + } + + egress { + protocol = "ANY" + description = "Allow all egress" + v4_cidr_blocks = ["0.0.0.0/0"] + from_port = 0 + to_port = 65535 + } +} + +# Create VM instance +resource "yandex_compute_instance" "lab04_vm" { + name = var.vm_name + hostname = var.vm_name + platform_id = "standard-v2" + zone = var.zone + + resources { + cores = 2 + memory = 1 + core_fraction = 20 # Free tier: 20% CPU + } + + boot_disk { + initialize_params { + image_id = data.yandex_compute_image.ubuntu.id + size = 10 # 10 GB HDD + type = "network-hdd" + } + } + + network_interface { + subnet_id = yandex_vpc_subnet.lab04_subnet.id + nat = true # Assign public IP + security_group_ids = [yandex_vpc_security_group.lab04_sg.id] + } + + metadata = { + ssh-keys = "${var.ssh_user}:${file(var.ssh_public_key_path)}" + } + + labels = { + environment = "lab04" + managed_by = "terraform" + purpose = "devops-course" + } + + scheduling_policy { + preemptible = false + } +} \ No newline at end of file diff --git a/terraform/outputs.tf b/terraform/outputs.tf new file mode 100644 index 0000000000..0699bacaae --- /dev/null +++ b/terraform/outputs.tf @@ -0,0 +1,53 @@ +# VM outputs +output "vm_id" { + description = "ID of the created VM" + value = yandex_compute_instance.lab04_vm.id +} + +output "vm_name" { + description = "Name of the created VM" + value = yandex_compute_instance.lab04_vm.name +} + +output "vm_public_ip" { + description = "Public IP address of the VM" + value = yandex_compute_instance.lab04_vm.network_interface[0].nat_ip_address +} + +output "vm_private_ip" { + description = "Private IP address of the VM" + value = yandex_compute_instance.lab04_vm.network_interface[0].ip_address +} + +# Network outputs +output "network_id" { + description = "ID of the VPC network" + value = yandex_vpc_network.lab04_network.id +} + +output "subnet_id" { + description = "ID of the subnet" + value = yandex_vpc_subnet.lab04_subnet.id +} + +output "security_group_id" { + description = "ID of the security group" + value = yandex_vpc_security_group.lab04_sg.id +} + +# SSH connection command +output "ssh_command" { + description = "SSH command to connect to the VM" + value = "ssh ${var.ssh_user}@${yandex_compute_instance.lab04_vm.network_interface[0].nat_ip_address}" +} + +# Connection info +output "connection_info" { + description = "Complete connection information" + value = { + public_ip = yandex_compute_instance.lab04_vm.network_interface[0].nat_ip_address + private_ip = yandex_compute_instance.lab04_vm.network_interface[0].ip_address + ssh_user = var.ssh_user + ssh_command = "ssh ${var.ssh_user}@${yandex_compute_instance.lab04_vm.network_interface[0].nat_ip_address}" + } +} \ No newline at end of file diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000000..5efc57b2e9 --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,61 @@ +# Yandex Cloud configuration +variable "cloud_id" { + description = "Yandex Cloud ID" + type = string +} + +variable "folder_id" { + description = "Yandex Cloud folder ID" + type = string +} + +variable "service_account_key_file" { + description = "Path to service account key file (JSON)" + type = string + default = "~/.config/yandex-cloud/key.json" +} + +variable "zone" { + description = "Yandex Cloud availability zone" + type = string + default = "ru-central1-a" +} + +# VM configuration +variable "vm_name" { + description = "Name of the virtual machine" + type = string + default = "lab04-vm" +} + +# SSH configuration +variable "ssh_user" { + description = "SSH username for VM access" + type = string + default = "ubuntu" +} + +variable "ssh_public_key_path" { + description = "Path to SSH public key file" + type = string + default = "~/.ssh/id_rsa.pub" +} + +variable "ssh_allowed_cidr" { + description = "CIDR allowed to SSH, e.g. 203.0.113.10/32" + type = string +} + +# GitHub configuration (for bonus task) +variable "github_token" { + description = "GitHub personal access token" + type = string + sensitive = true + default = "" +} + +variable "github_owner" { + description = "GitHub repository owner (username or organization)" + type = string + default = "" +} \ No newline at end of file From 383ef5e4ea2e8e032155788143140dce53232833 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Tue, 17 Feb 2026 03:45:17 +0300 Subject: [PATCH 35/40] feat: lab04 completed --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5cba3470d7..784616ee32 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ test *.log # Terraform +.terraform.lock.hcl *.tfstate *.tfstate.* .terraform/ From d48256884cb677e52444c41b769e263f0772fcee Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Tue, 17 Feb 2026 03:46:16 +0300 Subject: [PATCH 36/40] feat: lab04 completed --- terraform/.terraform.lock.hcl | 1 + terraform/.terraformrc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl index 90ce0f0af0..bd6ac44051 100644 --- a/terraform/.terraform.lock.hcl +++ b/terraform/.terraform.lock.hcl @@ -16,3 +16,4 @@ provider "registry.terraform.io/yandex-cloud/yandex" { "h1:+uf4EBRLDwNYIvZsGK/ZUzN3sGzJaXcUngyYSIJoyyQ=", ] } + diff --git a/terraform/.terraformrc b/terraform/.terraformrc index 9bc7728211..17415e3e00 100644 --- a/terraform/.terraformrc +++ b/terraform/.terraformrc @@ -6,4 +6,4 @@ provider_installation { direct { exclude = ["registry.terraform.io/*/*"] } -} \ No newline at end of file +} From c248abbd46b24cafcfc1d7eca81e904fba03540b Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Tue, 17 Feb 2026 03:47:15 +0300 Subject: [PATCH 37/40] feat: lab04 completed --- .gitignore | 2 +- terraform/.terraformrc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 784616ee32..cd53c583d7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ test *.log # Terraform -.terraform.lock.hcl +*.terraform.lock.hcl *.tfstate *.tfstate.* .terraform/ diff --git a/terraform/.terraformrc b/terraform/.terraformrc index 17415e3e00..9bc7728211 100644 --- a/terraform/.terraformrc +++ b/terraform/.terraformrc @@ -6,4 +6,4 @@ provider_installation { direct { exclude = ["registry.terraform.io/*/*"] } -} +} \ No newline at end of file From ba3ad72095efbca99f6843ec48fe996cbddfbf8a Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Tue, 17 Feb 2026 03:48:13 +0300 Subject: [PATCH 38/40] feat: lab04 completed --- terraform/.terraform.lock.hcl | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 terraform/.terraform.lock.hcl diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl deleted file mode 100644 index bd6ac44051..0000000000 --- a/terraform/.terraform.lock.hcl +++ /dev/null @@ -1,19 +0,0 @@ -# This file is maintained automatically by "terraform init". -# Manual edits may be lost in future updates. - -provider "registry.terraform.io/integrations/github" { - version = "5.45.0" - constraints = "~> 5.0" - hashes = [ - "h1:sP/Er9osOsz4vhKZAul+GeV0c5XdvMblJBMiP+T5tWc=", - ] -} - -provider "registry.terraform.io/yandex-cloud/yandex" { - version = "0.187.0" - constraints = "~> 0.100" - hashes = [ - "h1:+uf4EBRLDwNYIvZsGK/ZUzN3sGzJaXcUngyYSIJoyyQ=", - ] -} - From 477ec3e3f94588dd9f4d3b3674d3f14c339b98c9 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Tue, 17 Feb 2026 03:51:29 +0300 Subject: [PATCH 39/40] feat: lab04 completed --- terraform/.tflint.hcl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/terraform/.tflint.hcl b/terraform/.tflint.hcl index 6711210ee7..96e00d361b 100644 --- a/terraform/.tflint.hcl +++ b/terraform/.tflint.hcl @@ -3,12 +3,6 @@ plugin "terraform" { preset = "recommended" } -plugin "yandex" { - enabled = true - version = "0.1.0" - source = "github.com/yandex-cloud/tflint-ruleset-yandex-cloud" -} - rule "terraform_naming_convention" { enabled = true } From 301e324dc582d68230b3df86c7478d01f5f45680 Mon Sep 17 00:00:00 2001 From: Maksim Malov Date: Tue, 17 Feb 2026 04:04:11 +0300 Subject: [PATCH 40/40] feat lab04: completed --- pulumi/__main__.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pulumi/__main__.py b/pulumi/__main__.py index 00429f2be9..e719228a87 100644 --- a/pulumi/__main__.py +++ b/pulumi/__main__.py @@ -13,10 +13,14 @@ vm_name = config.get("vm_name") or "lab04-pulumi-vm" ssh_user = config.get("ssh_user") or "ubuntu" ssh_public_key_path = config.get("ssh_public_key_path") or "~/.ssh/id_rsa.pub" -ssh_allowed_cidr = config.require("ssh_allowed_cidr") # CIDR allowed to SSH, e.g. 203.0.113.10/32 +# CIDR allowed to SSH, e.g. 203.0.113.10/32 +ssh_allowed_cidr = config.require("ssh_allowed_cidr") # Read SSH public key -with open(ssh_public_key_path.replace("~", pulumi.runtime.get_config("HOME") or "~"), "r") as f: +ssh_key_expanded = ssh_public_key_path.replace( + "~", pulumi.runtime.get_config("HOME") or "~" +) +with open(ssh_key_expanded, "r") as f: ssh_public_key = f.read().strip() # Get latest Ubuntu 24.04 image @@ -143,4 +147,4 @@ "ssh_command": vm.network_interfaces[0].nat_ip_address.apply( lambda ip: f"ssh {ssh_user}@{ip}" ) -}) \ No newline at end of file +})