├── .gitignore ├── README.md ├── cs-app ├── Controllers │ └── DeviceController.cs ├── Dockerfile ├── Program.cs ├── Properties │ └── launchSettings.json ├── appsettings.Development.json ├── appsettings.json ├── cs-app.csproj └── deploy │ ├── deployment.yaml │ ├── ingress.yaml │ ├── namespace.yaml │ └── service.yaml ├── dashboards ├── latency.json └── saturation.json ├── docker-compose.yaml ├── go-app ├── Dockerfile ├── deploy │ ├── deployment.yaml │ ├── ingress.yaml │ ├── namespace.yaml │ └── service.yaml ├── go.mod ├── go.sum └── main.go ├── monitoring ├── cadvisor │ ├── 0-namespace.yaml │ ├── 1-service-account.yaml │ ├── 2-daemonset.yaml │ ├── 3-service.yaml │ └── 4-service-monitor.yaml ├── grafana │ ├── 0-namespace.yaml │ ├── 1-secret.yaml │ ├── 2-config.yaml │ ├── 3-datasources.yaml │ ├── 4-dashboards.yaml │ ├── 5-pvc.yaml │ ├── 6-deployment.yaml │ ├── 7-service.yaml │ └── 8-ingress.yaml ├── ingress-nginx │ └── service-monitor.yaml ├── kube-state-metrics │ ├── 0-service-account.yaml │ ├── 1-cluster-role.yaml │ ├── 2-cluster-role-binding.yaml │ ├── 3-deployment.yaml │ ├── 4-service.yaml │ └── 5-service-monitor.yaml ├── namespace.yaml ├── prometheus-crds-rbac.yaml ├── prometheus-operator │ ├── 0-service-account.yaml │ ├── 1-cluster-role.yaml │ ├── 2-cluster-role-binding.yaml │ ├── 3-deployment.yaml │ └── 4-service.yaml └── prometheus │ ├── 0-service-account.yaml │ ├── 1-cluster-role.yaml │ ├── 2-cluster-role-binding.yaml │ └── 3-prometheus.yaml ├── prometheus-operator-crd ├── alertmanagerconfigs.yaml ├── alertmanagers.yaml ├── podmonitors.yaml ├── probes.yaml ├── prometheuses.yaml ├── prometheusrules.yaml ├── servicemonitors.yaml └── thanosrulers.yaml ├── rust-app ├── .cargo │ └── config.toml ├── .dockerignore ├── Cargo.lock ├── Cargo.toml ├── Dockerfile ├── deploy │ ├── deployment.yaml │ ├── ingress.yaml │ ├── namespace.yaml │ └── service.yaml └── src │ └── main.rs └── terraform ├── .terraform.lock.hcl ├── 00-provider.tf ├── 01-vpc.tf ├── 02-igw.tf ├── 03-subnets.tf ├── 04-nat.tf ├── 05-routes.tf ├── 06-eks.tf ├── 07-nodes.tf ├── 08-iam-oidc.tf ├── 09-csi-driver-iam.tf ├── 10-csi-driver-addon.tf ├── 11-helm-provider.tf └── 12-helm-nginx-ingress.tf /.gitignore: -------------------------------------------------------------------------------- 1 | */target/* 2 | */bin/* 3 | */obj/* 4 | **/.tfstate.* 5 | terraform/terraform.tfstate 6 | terraform/terraform.tfstate.backup 7 | terraform/.terraform.tfstate.lock.info 8 | terraform.tfstate 9 | terraform/.terraform/* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go (Golang) vs. Rust: (HTTP/REST API in Kubernetes) Performance Benchmark 2 | 3 | Blog post for this can be found [here](https://medium.com/@shyamsundarb/c-vs-rust-vs-go-a-performance-benchmarking-in-kubernetes-c303b67b84b5). 4 | -------------------------------------------------------------------------------- /cs-app/Controllers/DeviceController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace cs_app.Controllers 8 | { 9 | [Route("api/[controller]")] 10 | [ApiController] 11 | public class DeviceController : ControllerBase 12 | { 13 | [HttpGet] 14 | public ActionResult> GetDevices() 15 | { 16 | var devices = new List 17 | { 18 | new Device { Id = 1, Mac = "5F-33-CC-1F-43-82", Firmware = "2.1.6" }, 19 | new Device { Id = 2, Mac = "EF-2B-C4-F5-D6-34", Firmware = "2.1.6" }, 20 | }; 21 | 22 | return devices; 23 | } 24 | 25 | [HttpPost] 26 | public ActionResult CreateDevice() 27 | { 28 | int number = 40; 29 | int fib = Fibonacci(number); 30 | string location = $"/api/devices/{fib}"; 31 | return Created(location, location); 32 | } 33 | 34 | private int Fibonacci(int n) 35 | { 36 | if (n == 1 || n == 2) 37 | return 1; 38 | if (n == 3) 39 | return 2; 40 | return Fibonacci(n - 1) + Fibonacci(n - 2); 41 | } 42 | } 43 | 44 | public class Device 45 | { 46 | public int Id { get; set; } 47 | public string Mac { get; set; } 48 | public string Firmware { get; set; } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /cs-app/Dockerfile: -------------------------------------------------------------------------------- 1 | # Use the latest LTS version of the .NET Core SDK image 2 | FROM mcr.microsoft.com/dotnet/sdk:7.0-alpine AS build 3 | 4 | # Set the working directory to /src 5 | WORKDIR /src 6 | 7 | # Copy all the source code files to the image 8 | COPY . . 9 | 10 | # Build the API using the dotnet CLI 11 | RUN dotnet build cs-app.csproj -c Release 12 | 13 | # Publish the API using the dotnet CLI 14 | RUN dotnet publish cs-app.csproj -c Release -o /app 15 | 16 | # Use the latest LTS version of the .NET Core runtime image 17 | FROM mcr.microsoft.com/dotnet/aspnet:7.0-alpine 18 | 19 | # Copy the published files of the API to the image 20 | COPY --from=build /app/ /app 21 | 22 | # Set the working directory to /app 23 | WORKDIR /app 24 | 25 | ENV ASPNETCORE_URLS="http://0.0.0.0:8002" 26 | # Expose port 80 for incoming traffic to the API 27 | EXPOSE 8002 28 | 29 | # Set the startup command to run the API 30 | CMD ["dotnet", "cs-app.dll"] 31 | 32 | 33 | -------------------------------------------------------------------------------- /cs-app/Program.cs: -------------------------------------------------------------------------------- 1 | var builder = WebApplication.CreateBuilder(args); 2 | 3 | // Add services to the container. 4 | 5 | builder.Services.AddControllers(); 6 | // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle 7 | builder.Services.AddEndpointsApiExplorer(); 8 | 9 | var app = builder.Build(); 10 | 11 | app.UseHttpsRedirection(); 12 | 13 | app.UseAuthorization(); 14 | 15 | app.MapControllers(); 16 | 17 | app.Run(); 18 | -------------------------------------------------------------------------------- /cs-app/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:50459", 8 | "sslPort": 44305 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "launchUrl": "swagger", 17 | "applicationUrl": "http://localhost:5111", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "launchUrl": "swagger", 27 | "applicationUrl": "https://localhost:7213;http://localhost:5111", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "launchUrl": "swagger", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /cs-app/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /cs-app/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /cs-app/cs-app.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net7.0 5 | enable 6 | enable 7 | cs_app 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /cs-app/deploy/deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: cs-app 6 | namespace: staging 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: cs-app 12 | template: 13 | metadata: 14 | labels: 15 | app: cs-app 16 | spec: 17 | containers: 18 | - name: cs-app 19 | image: youraccount.dkr.ecr.us-east-1.amazonaws.com/cs-app:0.3 20 | ports: 21 | - name: http 22 | containerPort: 8002 23 | resources: 24 | requests: 25 | memory: 512Mi 26 | cpu: 500m 27 | limits: 28 | memory: 1024Mi 29 | cpu: 1000m 30 | env: 31 | - name: ASPNETCORE_ENVIRONMENT 32 | value: PRODUCTION 33 | affinity: 34 | podAntiAffinity: 35 | preferredDuringSchedulingIgnoredDuringExecution: 36 | - weight: 100 37 | podAffinityTerm: 38 | labelSelector: 39 | matchExpressions: 40 | - key: app 41 | operator: In 42 | values: 43 | - go-app 44 | - rust-app 45 | - cs-app 46 | topologyKey: topology.kubernetes.io/zone 47 | -------------------------------------------------------------------------------- /cs-app/deploy/ingress.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: networking.k8s.io/v1 3 | kind: Ingress 4 | metadata: 5 | name: cs-app 6 | namespace: staging 7 | spec: 8 | ingressClassName: external-ingress-nginx 9 | rules: 10 | - host: cs-app.thedeltafarmers.com 11 | http: 12 | paths: 13 | - path: / 14 | pathType: Prefix 15 | backend: 16 | service: 17 | name: cs-app 18 | port: 19 | number: 8002 -------------------------------------------------------------------------------- /cs-app/deploy/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: staging 6 | labels: 7 | monitoring: prometheus 8 | -------------------------------------------------------------------------------- /cs-app/deploy/service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | namespace: staging 7 | name: cs-app 8 | labels: 9 | app: cs-app 10 | spec: 11 | type: ClusterIP 12 | ports: 13 | - name: http 14 | port: 8002 15 | protocol: TCP 16 | selector: 17 | app: cs-app 18 | -------------------------------------------------------------------------------- /dashboards/latency.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "target": { 15 | "limit": 100, 16 | "matchAny": false, 17 | "tags": [], 18 | "type": "dashboard" 19 | }, 20 | "type": "dashboard" 21 | } 22 | ] 23 | }, 24 | "editable": true, 25 | "fiscalYearStartMonth": 0, 26 | "graphTooltip": 0, 27 | "id": 2, 28 | "links": [], 29 | "liveNow": false, 30 | "panels": [ 31 | { 32 | "datasource": { 33 | "type": "prometheus", 34 | "uid": "PEB814BE3CA3B78C0" 35 | }, 36 | "fieldConfig": { 37 | "defaults": { 38 | "color": { 39 | "mode": "palette-classic" 40 | }, 41 | "custom": { 42 | "axisCenteredZero": false, 43 | "axisColorMode": "text", 44 | "axisLabel": "", 45 | "axisPlacement": "auto", 46 | "barAlignment": 0, 47 | "drawStyle": "line", 48 | "fillOpacity": 50, 49 | "gradientMode": "opacity", 50 | "hideFrom": { 51 | "legend": false, 52 | "tooltip": false, 53 | "viz": false 54 | }, 55 | "lineInterpolation": "smooth", 56 | "lineWidth": 2, 57 | "pointSize": 5, 58 | "scaleDistribution": { 59 | "type": "linear" 60 | }, 61 | "showPoints": "auto", 62 | "spanNulls": true, 63 | "stacking": { 64 | "group": "A", 65 | "mode": "none" 66 | }, 67 | "thresholdsStyle": { 68 | "mode": "off" 69 | } 70 | }, 71 | "decimals": 2, 72 | "mappings": [], 73 | "thresholds": { 74 | "mode": "absolute", 75 | "steps": [ 76 | { 77 | "color": "green", 78 | "value": null 79 | }, 80 | { 81 | "color": "red", 82 | "value": 80 83 | } 84 | ] 85 | }, 86 | "unit": "s" 87 | }, 88 | "overrides": [ 89 | { 90 | "matcher": { 91 | "id": "byRegexp", 92 | "options": "/.*rust.*/" 93 | }, 94 | "properties": [ 95 | { 96 | "id": "color", 97 | "value": { 98 | "fixedColor": "red", 99 | "mode": "fixed" 100 | } 101 | } 102 | ] 103 | }, 104 | { 105 | "matcher": { 106 | "id": "byRegexp", 107 | "options": "/.*go.*/" 108 | }, 109 | "properties": [ 110 | { 111 | "id": "color", 112 | "value": { 113 | "fixedColor": "blue", 114 | "mode": "fixed" 115 | } 116 | } 117 | ] 118 | }, 119 | { 120 | "matcher": { 121 | "id": "byRegexp", 122 | "options": "/.*cs.*/" 123 | }, 124 | "properties": [ 125 | { 126 | "id": "color", 127 | "value": { 128 | "fixedColor": "green", 129 | "mode": "fixed" 130 | } 131 | } 132 | ] 133 | } 134 | ] 135 | }, 136 | "gridPos": { 137 | "h": 12, 138 | "w": 24, 139 | "x": 0, 140 | "y": 0 141 | }, 142 | "id": 2, 143 | "options": { 144 | "legend": { 145 | "calcs": [ 146 | "lastNotNull" 147 | ], 148 | "displayMode": "table", 149 | "placement": "right", 150 | "showLegend": true 151 | }, 152 | "tooltip": { 153 | "mode": "single", 154 | "sort": "none" 155 | } 156 | }, 157 | "targets": [ 158 | { 159 | "datasource": { 160 | "type": "prometheus", 161 | "uid": "PEB814BE3CA3B78C0" 162 | }, 163 | "editorMode": "code", 164 | "expr": "histogram_quantile(\n 0.99, sum(\n rate(\n nginx_ingress_controller_request_duration_seconds_bucket\n {\n ingress=~\"$ingress\"\n }[1m])) by (le, ingress)\n )", 165 | "legendFormat": "{{ ingress }}", 166 | "range": true, 167 | "refId": "A" 168 | } 169 | ], 170 | "title": "p99 (Latency)", 171 | "type": "timeseries" 172 | }, 173 | { 174 | "datasource": { 175 | "type": "prometheus", 176 | "uid": "PEB814BE3CA3B78C0" 177 | }, 178 | "fieldConfig": { 179 | "defaults": { 180 | "color": { 181 | "mode": "palette-classic" 182 | }, 183 | "custom": { 184 | "axisCenteredZero": false, 185 | "axisColorMode": "text", 186 | "axisLabel": "", 187 | "axisPlacement": "auto", 188 | "barAlignment": 0, 189 | "drawStyle": "line", 190 | "fillOpacity": 50, 191 | "gradientMode": "opacity", 192 | "hideFrom": { 193 | "legend": false, 194 | "tooltip": false, 195 | "viz": false 196 | }, 197 | "lineInterpolation": "smooth", 198 | "lineWidth": 2, 199 | "pointSize": 5, 200 | "scaleDistribution": { 201 | "type": "linear" 202 | }, 203 | "showPoints": "auto", 204 | "spanNulls": true, 205 | "stacking": { 206 | "group": "A", 207 | "mode": "none" 208 | }, 209 | "thresholdsStyle": { 210 | "mode": "off" 211 | } 212 | }, 213 | "decimals": 2, 214 | "mappings": [], 215 | "thresholds": { 216 | "mode": "absolute", 217 | "steps": [ 218 | { 219 | "color": "green", 220 | "value": null 221 | }, 222 | { 223 | "color": "red", 224 | "value": 80 225 | } 226 | ] 227 | }, 228 | "unit": "s" 229 | }, 230 | "overrides": [ 231 | { 232 | "matcher": { 233 | "id": "byRegexp", 234 | "options": "/.*rust.*/" 235 | }, 236 | "properties": [ 237 | { 238 | "id": "color", 239 | "value": { 240 | "fixedColor": "red", 241 | "mode": "fixed" 242 | } 243 | } 244 | ] 245 | }, 246 | { 247 | "matcher": { 248 | "id": "byRegexp", 249 | "options": "/.*go.*/" 250 | }, 251 | "properties": [ 252 | { 253 | "id": "color", 254 | "value": { 255 | "fixedColor": "blue", 256 | "mode": "fixed" 257 | } 258 | } 259 | ] 260 | }, 261 | { 262 | "matcher": { 263 | "id": "byRegexp", 264 | "options": "/.*cs.*/" 265 | }, 266 | "properties": [ 267 | { 268 | "id": "color", 269 | "value": { 270 | "fixedColor": "green", 271 | "mode": "fixed" 272 | } 273 | } 274 | ] 275 | } 276 | ] 277 | }, 278 | "gridPos": { 279 | "h": 12, 280 | "w": 24, 281 | "x": 0, 282 | "y": 12 283 | }, 284 | "id": 3, 285 | "options": { 286 | "legend": { 287 | "calcs": [ 288 | "lastNotNull" 289 | ], 290 | "displayMode": "table", 291 | "placement": "right", 292 | "showLegend": true 293 | }, 294 | "tooltip": { 295 | "mode": "single", 296 | "sort": "none" 297 | } 298 | }, 299 | "targets": [ 300 | { 301 | "datasource": { 302 | "type": "prometheus", 303 | "uid": "PEB814BE3CA3B78C0" 304 | }, 305 | "editorMode": "code", 306 | "expr": "histogram_quantile(\n 0.90, sum(\n rate(\n nginx_ingress_controller_request_duration_seconds_bucket\n {\n ingress=~\"$ingress\"\n }[1m])) by (le, ingress)\n )", 307 | "legendFormat": "{{ ingress }}", 308 | "range": true, 309 | "refId": "A" 310 | } 311 | ], 312 | "title": "p90 (Latency)", 313 | "type": "timeseries" 314 | } 315 | ], 316 | "refresh": "5s", 317 | "schemaVersion": 37, 318 | "style": "dark", 319 | "tags": [], 320 | "templating": { 321 | "list": [ 322 | { 323 | "current": { 324 | "selected": true, 325 | "text": [ 326 | "go-app", 327 | "rust-app" 328 | ], 329 | "value": [ 330 | "go-app", 331 | "rust-app" 332 | ] 333 | }, 334 | "datasource": { 335 | "type": "prometheus", 336 | "uid": "PEB814BE3CA3B78C0" 337 | }, 338 | "definition": "label_values(nginx_ingress_controller_request_duration_seconds_bucket, ingress)", 339 | "hide": 0, 340 | "includeAll": false, 341 | "multi": true, 342 | "name": "ingress", 343 | "options": [], 344 | "query": { 345 | "query": "label_values(nginx_ingress_controller_request_duration_seconds_bucket, ingress)", 346 | "refId": "StandardVariableQuery" 347 | }, 348 | "refresh": 1, 349 | "regex": "", 350 | "skipUrlSync": false, 351 | "sort": 0, 352 | "type": "query" 353 | } 354 | ] 355 | }, 356 | "time": { 357 | "from": "now-15m", 358 | "to": "now" 359 | }, 360 | "timepicker": {}, 361 | "timezone": "", 362 | "title": "Latency", 363 | "uid": "0fk-M6O4k", 364 | "version": 8, 365 | "weekStart": "" 366 | } 367 | -------------------------------------------------------------------------------- /dashboards/saturation.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": { 7 | "type": "grafana", 8 | "uid": "-- Grafana --" 9 | }, 10 | "enable": true, 11 | "hide": true, 12 | "iconColor": "rgba(0, 211, 255, 1)", 13 | "name": "Annotations & Alerts", 14 | "target": { 15 | "limit": 100, 16 | "matchAny": false, 17 | "tags": [], 18 | "type": "dashboard" 19 | }, 20 | "type": "dashboard" 21 | } 22 | ] 23 | }, 24 | "editable": true, 25 | "fiscalYearStartMonth": 0, 26 | "graphTooltip": 0, 27 | "id": 1, 28 | "links": [], 29 | "liveNow": false, 30 | "panels": [ 31 | { 32 | "datasource": { 33 | "type": "prometheus", 34 | "uid": "PEB814BE3CA3B78C0" 35 | }, 36 | "fieldConfig": { 37 | "defaults": { 38 | "color": { 39 | "mode": "palette-classic" 40 | }, 41 | "custom": { 42 | "axisCenteredZero": false, 43 | "axisColorMode": "text", 44 | "axisLabel": "", 45 | "axisPlacement": "auto", 46 | "barAlignment": 0, 47 | "drawStyle": "line", 48 | "fillOpacity": 50, 49 | "gradientMode": "opacity", 50 | "hideFrom": { 51 | "legend": false, 52 | "tooltip": false, 53 | "viz": false 54 | }, 55 | "lineInterpolation": "smooth", 56 | "lineWidth": 2, 57 | "pointSize": 5, 58 | "scaleDistribution": { 59 | "type": "linear" 60 | }, 61 | "showPoints": "auto", 62 | "spanNulls": true, 63 | "stacking": { 64 | "group": "A", 65 | "mode": "none" 66 | }, 67 | "thresholdsStyle": { 68 | "mode": "off" 69 | } 70 | }, 71 | "decimals": 2, 72 | "mappings": [], 73 | "thresholds": { 74 | "mode": "absolute", 75 | "steps": [ 76 | { 77 | "color": "green", 78 | "value": null 79 | }, 80 | { 81 | "color": "red", 82 | "value": 80 83 | } 84 | ] 85 | }, 86 | "unit": "percentunit" 87 | }, 88 | "overrides": [ 89 | { 90 | "matcher": { 91 | "id": "byRegexp", 92 | "options": "/.*go.*/" 93 | }, 94 | "properties": [ 95 | { 96 | "id": "color", 97 | "value": { 98 | "fixedColor": "blue", 99 | "mode": "fixed" 100 | } 101 | } 102 | ] 103 | }, 104 | { 105 | "matcher": { 106 | "id": "byRegexp", 107 | "options": "/.*rust.*/" 108 | }, 109 | "properties": [ 110 | { 111 | "id": "color", 112 | "value": { 113 | "fixedColor": "red", 114 | "mode": "fixed" 115 | } 116 | } 117 | ] 118 | }, 119 | { 120 | "matcher": { 121 | "id": "byRegexp", 122 | "options": "/.*cs.*/" 123 | }, 124 | "properties": [ 125 | { 126 | "id": "color", 127 | "value": { 128 | "fixedColor": "green", 129 | "mode": "fixed" 130 | } 131 | } 132 | ] 133 | } 134 | ] 135 | }, 136 | "gridPos": { 137 | "h": 11, 138 | "w": 24, 139 | "x": 0, 140 | "y": 0 141 | }, 142 | "id": 2, 143 | "options": { 144 | "legend": { 145 | "calcs": [ 146 | "lastNotNull" 147 | ], 148 | "displayMode": "table", 149 | "placement": "right", 150 | "showLegend": true 151 | }, 152 | "tooltip": { 153 | "mode": "single", 154 | "sort": "none" 155 | } 156 | }, 157 | "targets": [ 158 | { 159 | "datasource": { 160 | "type": "prometheus", 161 | "uid": "PEB814BE3CA3B78C0" 162 | }, 163 | "editorMode": "code", 164 | "expr": "sum(\n rate(\n container_cpu_usage_seconds_total\n {\n container_label_io_kubernetes_pod_namespace=~\"$namespace\",\n container_label_io_kubernetes_pod_name=~\"$pod\",\n image!=\"\",\n container_label_io_cri_containerd_kind=\"container\"\n }[1m]\n )\n )\nby (\n container_label_io_kubernetes_pod_name,\n container_label_io_kubernetes_container_name\n ) /\nsum(\n container_spec_cpu_quota\n {\n container_label_io_kubernetes_pod_namespace=~\"$namespace\",\n container_label_io_kubernetes_pod_name=~\"$pod\",\n image!=\"\",\n container_label_io_cri_containerd_kind=\"container\"\n } /\n container_spec_cpu_period\n {\n container_label_io_kubernetes_pod_namespace=~\"$namespace\",\n container_label_io_kubernetes_pod_name=~\"$pod\",\n image!=\"\",\n container_label_io_cri_containerd_kind=\"container\"\n }\n )\nby (\n container_label_io_kubernetes_pod_name,\n container_label_io_kubernetes_container_name\n )", 165 | "legendFormat": "{{ container_label_io_kubernetes_container_name }} in {{ container_label_io_kubernetes_pod_name }}", 166 | "range": true, 167 | "refId": "A" 168 | } 169 | ], 170 | "title": "CPU Usage % of the Limit", 171 | "type": "timeseries" 172 | }, 173 | { 174 | "datasource": { 175 | "type": "prometheus", 176 | "uid": "PEB814BE3CA3B78C0" 177 | }, 178 | "fieldConfig": { 179 | "defaults": { 180 | "color": { 181 | "mode": "palette-classic" 182 | }, 183 | "custom": { 184 | "axisCenteredZero": false, 185 | "axisColorMode": "text", 186 | "axisLabel": "", 187 | "axisPlacement": "auto", 188 | "barAlignment": 0, 189 | "drawStyle": "line", 190 | "fillOpacity": 50, 191 | "gradientMode": "opacity", 192 | "hideFrom": { 193 | "legend": false, 194 | "tooltip": false, 195 | "viz": false 196 | }, 197 | "lineInterpolation": "smooth", 198 | "lineWidth": 2, 199 | "pointSize": 5, 200 | "scaleDistribution": { 201 | "type": "linear" 202 | }, 203 | "showPoints": "auto", 204 | "spanNulls": true, 205 | "stacking": { 206 | "group": "A", 207 | "mode": "none" 208 | }, 209 | "thresholdsStyle": { 210 | "mode": "off" 211 | } 212 | }, 213 | "decimals": 1, 214 | "mappings": [], 215 | "thresholds": { 216 | "mode": "absolute", 217 | "steps": [ 218 | { 219 | "color": "green", 220 | "value": null 221 | }, 222 | { 223 | "color": "red", 224 | "value": 80 225 | } 226 | ] 227 | }, 228 | "unit": "percentunit" 229 | }, 230 | "overrides": [ 231 | { 232 | "matcher": { 233 | "id": "byRegexp", 234 | "options": "/.*go.*/" 235 | }, 236 | "properties": [ 237 | { 238 | "id": "color", 239 | "value": { 240 | "fixedColor": "blue", 241 | "mode": "fixed" 242 | } 243 | } 244 | ] 245 | }, 246 | { 247 | "matcher": { 248 | "id": "byRegexp", 249 | "options": "/.*rust.*/" 250 | }, 251 | "properties": [ 252 | { 253 | "id": "color", 254 | "value": { 255 | "fixedColor": "red", 256 | "mode": "fixed" 257 | } 258 | } 259 | ] 260 | }, 261 | { 262 | "matcher": { 263 | "id": "byRegexp", 264 | "options": "/.*cs.*/" 265 | }, 266 | "properties": [ 267 | { 268 | "id": "color", 269 | "value": { 270 | "fixedColor": "green", 271 | "mode": "fixed" 272 | } 273 | } 274 | ] 275 | } 276 | ] 277 | }, 278 | "gridPos": { 279 | "h": 12, 280 | "w": 24, 281 | "x": 0, 282 | "y": 11 283 | }, 284 | "id": 4, 285 | "options": { 286 | "legend": { 287 | "calcs": [ 288 | "lastNotNull" 289 | ], 290 | "displayMode": "table", 291 | "placement": "right", 292 | "showLegend": true 293 | }, 294 | "tooltip": { 295 | "mode": "single", 296 | "sort": "none" 297 | } 298 | }, 299 | "targets": [ 300 | { 301 | "datasource": { 302 | "type": "prometheus", 303 | "uid": "PEB814BE3CA3B78C0" 304 | }, 305 | "editorMode": "code", 306 | "expr": "container_memory_working_set_bytes\n{\n container_label_io_kubernetes_pod_namespace=~\"$namespace\",\n container_label_io_kubernetes_pod_name=~\"$pod\",\n container_label_io_cri_containerd_kind=\"container\"\n} /\ncontainer_spec_memory_limit_bytes\n{\n container_label_io_kubernetes_pod_namespace=~\"$namespace\",\n container_label_io_kubernetes_pod_name=~\"$pod\",\n container_label_io_cri_containerd_kind=\"container\"\n}", 307 | "legendFormat": "{{ container_label_io_kubernetes_container_name }} in {{ container_label_io_kubernetes_pod_name }}", 308 | "range": true, 309 | "refId": "A" 310 | } 311 | ], 312 | "title": "Memory Usage % of the Limit", 313 | "type": "timeseries" 314 | } 315 | ], 316 | "refresh": "5s", 317 | "schemaVersion": 37, 318 | "style": "dark", 319 | "tags": [], 320 | "templating": { 321 | "list": [ 322 | { 323 | "current": { 324 | "selected": false, 325 | "text": "staging", 326 | "value": "staging" 327 | }, 328 | "datasource": { 329 | "type": "prometheus", 330 | "uid": "PEB814BE3CA3B78C0" 331 | }, 332 | "definition": "label_values(container_cpu_usage_seconds_total, container_label_io_kubernetes_pod_namespace)", 333 | "hide": 2, 334 | "includeAll": true, 335 | "multi": false, 336 | "name": "namespace", 337 | "options": [], 338 | "query": { 339 | "query": "label_values(container_cpu_usage_seconds_total, container_label_io_kubernetes_pod_namespace)", 340 | "refId": "StandardVariableQuery" 341 | }, 342 | "refresh": 1, 343 | "regex": "", 344 | "skipUrlSync": false, 345 | "sort": 0, 346 | "type": "query" 347 | }, 348 | { 349 | "current": { 350 | "selected": false, 351 | "text": "All", 352 | "value": "$__all" 353 | }, 354 | "datasource": { 355 | "type": "prometheus", 356 | "uid": "PEB814BE3CA3B78C0" 357 | }, 358 | "definition": "label_values(container_cpu_usage_seconds_total{container_label_io_kubernetes_pod_namespace=~\"$namespace\"}, container_label_io_kubernetes_pod_name)", 359 | "hide": 2, 360 | "includeAll": true, 361 | "multi": false, 362 | "name": "pod", 363 | "options": [], 364 | "query": { 365 | "query": "label_values(container_cpu_usage_seconds_total{container_label_io_kubernetes_pod_namespace=~\"$namespace\"}, container_label_io_kubernetes_pod_name)", 366 | "refId": "StandardVariableQuery" 367 | }, 368 | "refresh": 1, 369 | "regex": "", 370 | "skipUrlSync": false, 371 | "sort": 0, 372 | "type": "query" 373 | } 374 | ] 375 | }, 376 | "time": { 377 | "from": "now-30m", 378 | "to": "now" 379 | }, 380 | "timepicker": {}, 381 | "timezone": "", 382 | "title": "Saturation", 383 | "uid": "JjkD76OVk", 384 | "version": 5, 385 | "weekStart": "" 386 | } 387 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | version: "3" 3 | 4 | services: 5 | 6 | rust-app: 7 | build: rust-app 8 | ports: 9 | - 8000:8080 10 | environment: 11 | - ROCKET_ADDRESS="0.0.0.0" 12 | 13 | go-app: 14 | build: go-app 15 | ports: 16 | - 8001:8001 17 | environment: 18 | - GIN_MODE=release 19 | 20 | cs-app: 21 | build: cs-app 22 | ports: 23 | - 8002:80 24 | environment: 25 | - ASPNETCORE_ENVIRONMENT=PRODUCTION 26 | -------------------------------------------------------------------------------- /go-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.19.3-buster AS build 2 | 3 | WORKDIR /app 4 | 5 | COPY go.mod ./ 6 | COPY go.sum ./ 7 | 8 | RUN go mod download && go mod verify 9 | 10 | COPY main.go ./ 11 | 12 | RUN go build -o /my-app 13 | 14 | FROM gcr.io/distroless/base-debian11 15 | 16 | COPY --from=build /my-app /my-app 17 | 18 | ENTRYPOINT ["/my-app"] 19 | -------------------------------------------------------------------------------- /go-app/deploy/deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: go-app 6 | namespace: staging 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: go-app 12 | template: 13 | metadata: 14 | labels: 15 | app: go-app 16 | spec: 17 | containers: 18 | - name: go-app 19 | image: youraccount.dkr.ecr.us-east-1.amazonaws.com/go-app:latest 20 | ports: 21 | - name: http 22 | containerPort: 8001 23 | resources: 24 | requests: 25 | memory: 512Mi 26 | cpu: 500m 27 | limits: 28 | memory: 1024Mi 29 | cpu: 1000m 30 | env: 31 | - name: GIN_MODE 32 | value: release 33 | affinity: 34 | podAntiAffinity: 35 | preferredDuringSchedulingIgnoredDuringExecution: 36 | - weight: 100 37 | podAffinityTerm: 38 | labelSelector: 39 | matchExpressions: 40 | - key: app 41 | operator: In 42 | values: 43 | - go-app 44 | - rust-app 45 | - cs-app 46 | topologyKey: topology.kubernetes.io/zone 47 | -------------------------------------------------------------------------------- /go-app/deploy/ingress.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: networking.k8s.io/v1 3 | kind: Ingress 4 | metadata: 5 | name: go-app 6 | namespace: staging 7 | spec: 8 | ingressClassName: external-ingress-nginx 9 | rules: 10 | - host: go-app.thedeltafarmers.com 11 | http: 12 | paths: 13 | - path: / 14 | pathType: Prefix 15 | backend: 16 | service: 17 | name: go-app 18 | port: 19 | number: 8001 20 | -------------------------------------------------------------------------------- /go-app/deploy/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: staging 6 | labels: 7 | monitoring: prometheus 8 | -------------------------------------------------------------------------------- /go-app/deploy/service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | namespace: staging 7 | name: go-app 8 | labels: 9 | app: go-app 10 | spec: 11 | type: ClusterIP 12 | ports: 13 | - name: http 14 | port: 8001 15 | protocol: TCP 16 | selector: 17 | app: go-app 18 | -------------------------------------------------------------------------------- /go-app/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/antonputra/tutorials/lessons/137/my-app 2 | 3 | go 1.19 4 | 5 | require github.com/gin-gonic/gin v1.8.1 6 | 7 | require ( 8 | github.com/gin-contrib/sse v0.1.0 // indirect 9 | github.com/go-playground/locales v0.14.0 // indirect 10 | github.com/go-playground/universal-translator v0.18.0 // indirect 11 | github.com/go-playground/validator/v10 v10.10.0 // indirect 12 | github.com/goccy/go-json v0.9.7 // indirect 13 | github.com/google/go-cmp v0.5.8 // indirect 14 | github.com/json-iterator/go v1.1.12 // indirect 15 | github.com/leodido/go-urn v1.2.1 // indirect 16 | github.com/mattn/go-isatty v0.0.14 // indirect 17 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 18 | github.com/modern-go/reflect2 v1.0.2 // indirect 19 | github.com/pelletier/go-toml/v2 v2.0.1 // indirect 20 | github.com/ugorji/go/codec v1.2.7 // indirect 21 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect 22 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect 23 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect 24 | golang.org/x/text v0.3.7 // indirect 25 | google.golang.org/protobuf v1.28.1 // indirect 26 | gopkg.in/yaml.v2 v2.4.0 // indirect 27 | ) 28 | -------------------------------------------------------------------------------- /go-app/go.sum: -------------------------------------------------------------------------------- 1 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 4 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 5 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 6 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 7 | github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= 8 | github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= 9 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= 10 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 11 | github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= 12 | github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= 13 | github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= 14 | github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= 15 | github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= 16 | github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= 17 | github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= 18 | github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 19 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 20 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 21 | github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= 22 | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 23 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 24 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 25 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 26 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 27 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 28 | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= 29 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= 30 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 31 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 32 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 33 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 34 | github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= 35 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= 36 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 37 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 38 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 39 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 40 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 41 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 42 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 43 | github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= 44 | github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= 45 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 46 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 47 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 48 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= 49 | github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= 50 | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= 51 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 52 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 53 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 54 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 55 | github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= 56 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 57 | github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= 58 | github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= 59 | github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= 60 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= 61 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 62 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 63 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= 64 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 65 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 66 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 67 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 68 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 69 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= 70 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 71 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 72 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 73 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 74 | golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= 75 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 76 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 77 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 78 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 79 | google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= 80 | google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 81 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 82 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 83 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 84 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 85 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 86 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 87 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 88 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 89 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 90 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 91 | -------------------------------------------------------------------------------- /go-app/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gin-gonic/gin" 7 | ) 8 | 9 | type Device struct { 10 | ID int `json:"id"` 11 | Mac string `json:"mac"` 12 | Firmware string `json:"firmware"` 13 | } 14 | 15 | func main() { 16 | r := gin.Default() 17 | r.GET("/api/devices", getDevices) 18 | r.POST("/api/devices", createDevice) 19 | r.Run(":8001") 20 | } 21 | 22 | func getDevices(c *gin.Context) { 23 | dvs := []Device{ 24 | {1, "5F-33-CC-1F-43-82", "2.1.6"}, 25 | {2, "EF-2B-C4-F5-D6-34", "2.1.6"}, 26 | } 27 | 28 | c.JSON(http.StatusOK, dvs) 29 | } 30 | 31 | func createDevice(c *gin.Context) { 32 | number := 40 33 | 34 | fib := fibonacci(number) 35 | 36 | c.JSON(http.StatusCreated, gin.H{"fib": fib}) 37 | } 38 | 39 | func fibonacci(n int) int { 40 | if n <= 1 { 41 | return n 42 | } 43 | return fibonacci(n-1) + fibonacci(n-2) 44 | } 45 | -------------------------------------------------------------------------------- /monitoring/cadvisor/0-namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: cadvisor 6 | labels: 7 | monitoring: prometheus 8 | -------------------------------------------------------------------------------- /monitoring/cadvisor/1-service-account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: cadvisor 5 | namespace: cadvisor 6 | -------------------------------------------------------------------------------- /monitoring/cadvisor/2-daemonset.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: DaemonSet 4 | metadata: 5 | name: cadvisor 6 | namespace: cadvisor 7 | spec: 8 | selector: 9 | matchLabels: 10 | name: cadvisor 11 | template: 12 | metadata: 13 | labels: 14 | name: cadvisor 15 | spec: 16 | serviceAccountName: cadvisor 17 | containers: 18 | - name: cadvisor 19 | image: gcr.io/cadvisor/cadvisor:v0.46.0 20 | resources: 21 | requests: 22 | memory: 400Mi 23 | cpu: 400m 24 | limits: 25 | memory: 2000Mi 26 | cpu: 800m 27 | volumeMounts: 28 | - name: rootfs 29 | mountPath: /rootfs 30 | readOnly: true 31 | - name: var-run 32 | mountPath: /var/run 33 | readOnly: true 34 | - name: sys 35 | mountPath: /sys 36 | readOnly: true 37 | - name: docker 38 | mountPath: /var/lib/docker 39 | readOnly: true 40 | - name: disk 41 | mountPath: /dev/disk 42 | readOnly: true 43 | ports: 44 | - name: http 45 | containerPort: 8080 46 | protocol: TCP 47 | automountServiceAccountToken: false 48 | terminationGracePeriodSeconds: 30 49 | volumes: 50 | - name: rootfs 51 | hostPath: 52 | path: / 53 | - name: var-run 54 | hostPath: 55 | path: /var/run 56 | - name: sys 57 | hostPath: 58 | path: /sys 59 | - name: docker 60 | hostPath: 61 | path: /var/lib/docker 62 | - name: disk 63 | hostPath: 64 | path: /dev/disk 65 | -------------------------------------------------------------------------------- /monitoring/cadvisor/3-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: cadvisor 6 | namespace: cadvisor 7 | labels: 8 | name: cadvisor 9 | spec: 10 | clusterIP: None 11 | ports: 12 | - name: http 13 | port: 8080 14 | targetPort: http 15 | selector: 16 | name: cadvisor 17 | -------------------------------------------------------------------------------- /monitoring/cadvisor/4-service-monitor.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: ServiceMonitor 4 | metadata: 5 | name: cadvisor 6 | namespace: cadvisor 7 | labels: 8 | component: main 9 | spec: 10 | selector: 11 | matchLabels: 12 | name: cadvisor 13 | endpoints: 14 | - port: http 15 | -------------------------------------------------------------------------------- /monitoring/grafana/0-namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: grafana 6 | labels: 7 | monitoring: prometheus 8 | -------------------------------------------------------------------------------- /monitoring/grafana/1-secret.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | namespace: grafana 6 | name: grafana 7 | type: Opaque 8 | data: 9 | admin-user: "YWRtaW4=" 10 | admin-password: "ZGV2b3BzMTIz" 11 | -------------------------------------------------------------------------------- /monitoring/grafana/2-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | namespace: grafana 6 | name: grafana 7 | data: 8 | grafana.ini: | 9 | [analytics] 10 | reporting_enabled = false 11 | check_for_updates = true 12 | 13 | [grafana_net] 14 | url = https://grafana.net 15 | 16 | [log] 17 | mode = console 18 | 19 | [paths] 20 | data = /var/lib/grafana/data 21 | logs = /var/log/grafana 22 | plugins = /var/lib/grafana/plugins 23 | provisioning = /etc/grafana/provisioning 24 | 25 | [server] 26 | root_url = "https://my-grafana.example.pvt" 27 | 28 | [auth.anonymous] 29 | enabled = false 30 | 31 | [metrics] 32 | enabled = true 33 | disable_total_stats = false 34 | -------------------------------------------------------------------------------- /monitoring/grafana/3-datasources.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: datasources 6 | namespace: grafana 7 | data: 8 | datasources.yaml: | 9 | apiVersion: 1 10 | datasources: 11 | - name: Main 12 | type: prometheus 13 | url: http://prometheus-operated.monitoring:9090 14 | isDefault: false 15 | jsonData: 16 | manageAlerts: false 17 | -------------------------------------------------------------------------------- /monitoring/grafana/4-dashboards.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | namespace: grafana 6 | name: dashboards 7 | data: 8 | dashboardproviders.yaml: |- 9 | apiVersion: 1 10 | providers: 11 | - disableDeletion: false 12 | editable: false 13 | folder: Kubernetes 14 | name: kubernetes 15 | options: 16 | path: /var/lib/grafana/dashboards/kubernetes 17 | orgId: 1 18 | type: file 19 | -------------------------------------------------------------------------------- /monitoring/grafana/5-pvc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolumeClaim 4 | metadata: 5 | namespace: grafana 6 | name: grafana 7 | spec: 8 | accessModes: 9 | - ReadWriteOnce 10 | resources: 11 | requests: 12 | storage: 8Gi 13 | -------------------------------------------------------------------------------- /monitoring/grafana/6-deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | namespace: grafana 6 | name: grafana 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: grafana 12 | strategy: 13 | type: Recreate 14 | template: 15 | metadata: 16 | labels: 17 | app: grafana 18 | spec: 19 | securityContext: 20 | fsGroup: 472 21 | runAsUser: 472 22 | containers: 23 | - name: grafana 24 | image: grafana/grafana:9.3.1 25 | imagePullPolicy: IfNotPresent 26 | volumeMounts: 27 | - name: storage 28 | mountPath: "/var/lib/grafana" 29 | - name: config 30 | mountPath: "/etc/grafana/grafana.ini" 31 | subPath: grafana.ini 32 | - name: datasources 33 | mountPath: "/etc/grafana/provisioning/datasources/datasources.yaml" 34 | subPath: datasources.yaml 35 | - name: dashboards 36 | mountPath: "/etc/grafana/provisioning/dashboards/dashboardproviders.yaml" 37 | subPath: dashboardproviders.yaml 38 | ports: 39 | - name: grafana 40 | containerPort: 3000 41 | protocol: TCP 42 | env: 43 | - name: GF_SECURITY_ADMIN_USER 44 | valueFrom: 45 | secretKeyRef: 46 | name: grafana 47 | key: admin-user 48 | - name: GF_SECURITY_ADMIN_PASSWORD 49 | valueFrom: 50 | secretKeyRef: 51 | name: grafana 52 | key: admin-password 53 | livenessProbe: 54 | failureThreshold: 10 55 | httpGet: 56 | path: /api/health 57 | port: 3000 58 | initialDelaySeconds: 60 59 | timeoutSeconds: 30 60 | readinessProbe: 61 | httpGet: 62 | path: /api/health 63 | port: 3000 64 | resources: 65 | requests: 66 | cpu: 500m 67 | memory: 1Gi 68 | limits: 69 | cpu: 2000m 70 | memory: 4Gi 71 | volumes: 72 | - name: storage 73 | persistentVolumeClaim: 74 | claimName: grafana 75 | - name: config 76 | configMap: 77 | name: grafana 78 | - name: datasources 79 | configMap: 80 | name: datasources 81 | - name: dashboards 82 | configMap: 83 | name: dashboards 84 | -------------------------------------------------------------------------------- /monitoring/grafana/7-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | namespace: grafana 6 | name: grafana 7 | labels: 8 | app: grafana 9 | spec: 10 | type: ClusterIP 11 | ports: 12 | - name: service 13 | port: 3000 14 | protocol: TCP 15 | selector: 16 | app: grafana 17 | -------------------------------------------------------------------------------- /monitoring/grafana/8-ingress.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: networking.k8s.io/v1 3 | kind: Ingress 4 | metadata: 5 | name: grafana 6 | namespace: grafana 7 | spec: 8 | ingressClassName: external-ingress-nginx 9 | rules: 10 | - host: grafana.thedeltafarmers.com 11 | http: 12 | paths: 13 | - path: / 14 | pathType: Prefix 15 | backend: 16 | service: 17 | name: grafana 18 | port: 19 | number: 3000 20 | -------------------------------------------------------------------------------- /monitoring/ingress-nginx/service-monitor.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: ServiceMonitor 4 | metadata: 5 | name: ingress-nginx 6 | namespace: monitoring 7 | labels: 8 | component: main 9 | spec: 10 | selector: 11 | matchLabels: 12 | app.kubernetes.io/name: ingress-nginx 13 | namespaceSelector: 14 | matchNames: 15 | - ingress-nginx 16 | endpoints: 17 | - port: metrics 18 | -------------------------------------------------------------------------------- /monitoring/kube-state-metrics/0-service-account.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: kube-state-metrics 6 | namespace: monitoring 7 | -------------------------------------------------------------------------------- /monitoring/kube-state-metrics/1-cluster-role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: kube-state-metrics 5 | rules: 6 | - apiGroups: 7 | - "" 8 | resources: 9 | - configmaps 10 | - secrets 11 | - nodes 12 | - pods 13 | - services 14 | - serviceaccounts 15 | - resourcequotas 16 | - replicationcontrollers 17 | - limitranges 18 | - persistentvolumeclaims 19 | - persistentvolumes 20 | - namespaces 21 | - endpoints 22 | verbs: 23 | - list 24 | - watch 25 | - apiGroups: 26 | - apps 27 | resources: 28 | - statefulsets 29 | - daemonsets 30 | - deployments 31 | - replicasets 32 | verbs: 33 | - list 34 | - watch 35 | - apiGroups: 36 | - batch 37 | resources: 38 | - cronjobs 39 | - jobs 40 | verbs: 41 | - list 42 | - watch 43 | - apiGroups: 44 | - autoscaling 45 | resources: 46 | - horizontalpodautoscalers 47 | verbs: 48 | - list 49 | - watch 50 | - apiGroups: 51 | - authentication.k8s.io 52 | resources: 53 | - tokenreviews 54 | verbs: 55 | - create 56 | - apiGroups: 57 | - authorization.k8s.io 58 | resources: 59 | - subjectaccessreviews 60 | verbs: 61 | - create 62 | - apiGroups: 63 | - policy 64 | resources: 65 | - poddisruptionbudgets 66 | verbs: 67 | - list 68 | - watch 69 | - apiGroups: 70 | - certificates.k8s.io 71 | resources: 72 | - certificatesigningrequests 73 | verbs: 74 | - list 75 | - watch 76 | - apiGroups: 77 | - storage.k8s.io 78 | resources: 79 | - storageclasses 80 | - volumeattachments 81 | verbs: 82 | - list 83 | - watch 84 | - apiGroups: 85 | - admissionregistration.k8s.io 86 | resources: 87 | - mutatingwebhookconfigurations 88 | - validatingwebhookconfigurations 89 | verbs: 90 | - list 91 | - watch 92 | - apiGroups: 93 | - networking.k8s.io 94 | resources: 95 | - networkpolicies 96 | - ingresses 97 | verbs: 98 | - list 99 | - watch 100 | - apiGroups: 101 | - coordination.k8s.io 102 | resources: 103 | - leases 104 | verbs: 105 | - list 106 | - watch 107 | - apiGroups: 108 | - rbac.authorization.k8s.io 109 | resources: 110 | - clusterrolebindings 111 | - clusterroles 112 | - rolebindings 113 | - roles 114 | verbs: 115 | - list 116 | - watch 117 | -------------------------------------------------------------------------------- /monitoring/kube-state-metrics/2-cluster-role-binding.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | name: kube-state-metrics 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: kube-state-metrics 10 | subjects: 11 | - kind: ServiceAccount 12 | name: kube-state-metrics 13 | namespace: monitoring 14 | -------------------------------------------------------------------------------- /monitoring/kube-state-metrics/3-deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: kube-state-metrics 6 | namespace: monitoring 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app.kubernetes.io/name: kube-state-metrics 12 | template: 13 | metadata: 14 | labels: 15 | app.kubernetes.io/name: kube-state-metrics 16 | spec: 17 | automountServiceAccountToken: true 18 | containers: 19 | - image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.7.0 20 | livenessProbe: 21 | httpGet: 22 | path: /healthz 23 | port: 8080 24 | initialDelaySeconds: 5 25 | timeoutSeconds: 5 26 | name: kube-state-metrics 27 | resources: 28 | requests: 29 | cpu: 50m 30 | memory: 128Mi 31 | limits: 32 | cpu: 200m 33 | memory: 256Mi 34 | ports: 35 | - containerPort: 8080 36 | name: http-metrics 37 | - containerPort: 8081 38 | name: telemetry 39 | readinessProbe: 40 | httpGet: 41 | path: / 42 | port: 8081 43 | initialDelaySeconds: 5 44 | timeoutSeconds: 5 45 | securityContext: 46 | allowPrivilegeEscalation: false 47 | capabilities: 48 | drop: 49 | - ALL 50 | readOnlyRootFilesystem: true 51 | runAsUser: 65534 52 | nodeSelector: 53 | kubernetes.io/os: linux 54 | serviceAccountName: kube-state-metrics 55 | -------------------------------------------------------------------------------- /monitoring/kube-state-metrics/4-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | labels: 6 | app.kubernetes.io/name: kube-state-metrics 7 | name: kube-state-metrics 8 | namespace: monitoring 9 | spec: 10 | clusterIP: None 11 | ports: 12 | - name: http-metrics 13 | port: 8080 14 | targetPort: http-metrics 15 | - name: telemetry 16 | port: 8081 17 | targetPort: telemetry 18 | selector: 19 | app.kubernetes.io/name: kube-state-metrics 20 | -------------------------------------------------------------------------------- /monitoring/kube-state-metrics/5-service-monitor.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: ServiceMonitor 4 | metadata: 5 | name: kube-state-metrics 6 | namespace: monitoring 7 | labels: 8 | component: main 9 | spec: 10 | selector: 11 | matchLabels: 12 | app.kubernetes.io/name: kube-state-metrics 13 | endpoints: 14 | - port: http-metrics 15 | -------------------------------------------------------------------------------- /monitoring/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: monitoring 6 | labels: 7 | monitoring: prometheus 8 | -------------------------------------------------------------------------------- /monitoring/prometheus-crds-rbac.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | kind: ClusterRole 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | metadata: 5 | name: prometheus-crd-view 6 | labels: 7 | rbac.authorization.k8s.io/aggregate-to-admin: "true" 8 | rbac.authorization.k8s.io/aggregate-to-edit: "true" 9 | rbac.authorization.k8s.io/aggregate-to-view: "true" 10 | rules: 11 | - apiGroups: ["monitoring.coreos.com"] 12 | resources: ["alertmanagers", "alertmanagerconfigs", "prometheuses", "prometheusrules", "servicemonitors", "podmonitors", "probes"] 13 | verbs: ["get", "list", "watch"] 14 | --- 15 | kind: ClusterRole 16 | apiVersion: rbac.authorization.k8s.io/v1 17 | metadata: 18 | name: prometheus-crd-edit 19 | labels: 20 | rbac.authorization.k8s.io/aggregate-to-edit: "true" 21 | rbac.authorization.k8s.io/aggregate-to-admin: "true" 22 | rules: 23 | - apiGroups: ["monitoring.coreos.com"] 24 | resources: ["alertmanagers", "alertmanagerconfigs", "prometheuses", "prometheusrules", "servicemonitors", "podmonitors", "probes"] 25 | verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] 26 | -------------------------------------------------------------------------------- /monitoring/prometheus-operator/0-service-account.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | automountServiceAccountToken: false 4 | kind: ServiceAccount 5 | metadata: 6 | labels: 7 | app.kubernetes.io/component: controller 8 | app.kubernetes.io/name: prometheus-operator 9 | app.kubernetes.io/version: 0.61.1 10 | name: prometheus-operator 11 | namespace: monitoring 12 | -------------------------------------------------------------------------------- /monitoring/prometheus-operator/1-cluster-role.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | labels: 6 | app.kubernetes.io/component: controller 7 | app.kubernetes.io/name: prometheus-operator 8 | app.kubernetes.io/version: 0.61.1 9 | name: prometheus-operator 10 | rules: 11 | - apiGroups: 12 | - monitoring.coreos.com 13 | resources: 14 | - alertmanagers 15 | - alertmanagers/finalizers 16 | - alertmanagerconfigs 17 | - prometheuses 18 | - prometheuses/finalizers 19 | - prometheuses/status 20 | - thanosrulers 21 | - thanosrulers/finalizers 22 | - servicemonitors 23 | - podmonitors 24 | - probes 25 | - prometheusrules 26 | verbs: 27 | - '*' 28 | - apiGroups: 29 | - apps 30 | resources: 31 | - statefulsets 32 | verbs: 33 | - '*' 34 | - apiGroups: 35 | - "" 36 | resources: 37 | - configmaps 38 | - secrets 39 | verbs: 40 | - '*' 41 | - apiGroups: 42 | - "" 43 | resources: 44 | - pods 45 | verbs: 46 | - list 47 | - delete 48 | - apiGroups: 49 | - "" 50 | resources: 51 | - services 52 | - services/finalizers 53 | - endpoints 54 | verbs: 55 | - get 56 | - create 57 | - update 58 | - delete 59 | - apiGroups: 60 | - "" 61 | resources: 62 | - nodes 63 | verbs: 64 | - list 65 | - watch 66 | - apiGroups: 67 | - "" 68 | resources: 69 | - namespaces 70 | verbs: 71 | - get 72 | - list 73 | - watch 74 | - apiGroups: 75 | - networking.k8s.io 76 | resources: 77 | - ingresses 78 | verbs: 79 | - get 80 | - list 81 | - watch 82 | -------------------------------------------------------------------------------- /monitoring/prometheus-operator/2-cluster-role-binding.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | labels: 6 | app.kubernetes.io/component: controller 7 | app.kubernetes.io/name: prometheus-operator 8 | app.kubernetes.io/version: 0.61.1 9 | name: prometheus-operator 10 | roleRef: 11 | apiGroup: rbac.authorization.k8s.io 12 | kind: ClusterRole 13 | name: prometheus-operator 14 | subjects: 15 | - kind: ServiceAccount 16 | name: prometheus-operator 17 | namespace: monitoring 18 | -------------------------------------------------------------------------------- /monitoring/prometheus-operator/3-deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | labels: 6 | app.kubernetes.io/component: controller 7 | app.kubernetes.io/name: prometheus-operator 8 | app.kubernetes.io/version: 0.61.1 9 | name: prometheus-operator 10 | namespace: monitoring 11 | spec: 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | app.kubernetes.io/component: controller 16 | app.kubernetes.io/name: prometheus-operator 17 | template: 18 | metadata: 19 | annotations: 20 | kubectl.kubernetes.io/default-container: prometheus-operator 21 | labels: 22 | app.kubernetes.io/component: controller 23 | app.kubernetes.io/name: prometheus-operator 24 | app.kubernetes.io/version: 0.61.1 25 | spec: 26 | automountServiceAccountToken: true 27 | containers: 28 | - args: 29 | - --kubelet-service=kube-system/kubelet 30 | - --prometheus-config-reloader=quay.io/prometheus-operator/prometheus-config-reloader:v0.61.1 31 | image: quay.io/prometheus-operator/prometheus-operator:v0.61.1 32 | name: prometheus-operator 33 | ports: 34 | - containerPort: 8080 35 | name: http 36 | resources: 37 | limits: 38 | cpu: 200m 39 | memory: 200Mi 40 | requests: 41 | cpu: 100m 42 | memory: 100Mi 43 | securityContext: 44 | allowPrivilegeEscalation: false 45 | capabilities: 46 | drop: 47 | - ALL 48 | readOnlyRootFilesystem: true 49 | nodeSelector: 50 | kubernetes.io/os: linux 51 | securityContext: 52 | runAsNonRoot: true 53 | runAsUser: 65534 54 | serviceAccountName: prometheus-operator 55 | -------------------------------------------------------------------------------- /monitoring/prometheus-operator/4-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | labels: 6 | app.kubernetes.io/component: controller 7 | app.kubernetes.io/name: prometheus-operator 8 | app.kubernetes.io/version: 0.61.1 9 | name: prometheus-operator 10 | namespace: monitoring 11 | spec: 12 | clusterIP: None 13 | ports: 14 | - name: http 15 | port: 8080 16 | targetPort: http 17 | selector: 18 | app.kubernetes.io/component: controller 19 | app.kubernetes.io/name: prometheus-operator 20 | -------------------------------------------------------------------------------- /monitoring/prometheus/0-service-account.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: prometheus 6 | namespace: monitoring 7 | -------------------------------------------------------------------------------- /monitoring/prometheus/1-cluster-role.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: prometheus 6 | rules: 7 | - apiGroups: [""] 8 | resources: 9 | - nodes 10 | - nodes/metrics 11 | - services 12 | - endpoints 13 | - pods 14 | verbs: ["get", "list", "watch"] 15 | - apiGroups: [""] 16 | resources: 17 | - configmaps 18 | verbs: ["get"] 19 | - apiGroups: 20 | - networking.k8s.io 21 | resources: 22 | - ingresses 23 | verbs: ["get", "list", "watch"] 24 | - nonResourceURLs: ["/metrics"] 25 | verbs: ["get"] 26 | -------------------------------------------------------------------------------- /monitoring/prometheus/2-cluster-role-binding.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | name: prometheus 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: prometheus 10 | subjects: 11 | - kind: ServiceAccount 12 | name: prometheus 13 | namespace: monitoring 14 | -------------------------------------------------------------------------------- /monitoring/prometheus/3-prometheus.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: Prometheus 4 | metadata: 5 | name: main 6 | namespace: monitoring 7 | spec: 8 | version: v2.40.6 9 | serviceAccountName: prometheus 10 | serviceMonitorSelector: 11 | matchLabels: 12 | component: main 13 | serviceMonitorNamespaceSelector: 14 | matchLabels: 15 | monitoring: prometheus 16 | resources: 17 | requests: 18 | cpu: 250m 19 | memory: 1Gi 20 | limits: 21 | cpu: 2000m 22 | memory: 4Gi 23 | replicas: 1 24 | logLevel: info 25 | logFormat: logfmt 26 | scrapeInterval: 5s 27 | securityContext: 28 | fsGroup: 0 29 | runAsNonRoot: false 30 | runAsUser: 0 31 | storage: 32 | volumeClaimTemplate: 33 | spec: 34 | resources: 35 | requests: 36 | storage: 20Gi 37 | -------------------------------------------------------------------------------- /prometheus-operator-crd/podmonitors.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.9.2 7 | creationTimestamp: null 8 | name: podmonitors.monitoring.coreos.com 9 | spec: 10 | group: monitoring.coreos.com 11 | names: 12 | categories: 13 | - prometheus-operator 14 | kind: PodMonitor 15 | listKind: PodMonitorList 16 | plural: podmonitors 17 | shortNames: 18 | - pmon 19 | singular: podmonitor 20 | scope: Namespaced 21 | versions: 22 | - name: v1 23 | schema: 24 | openAPIV3Schema: 25 | description: PodMonitor defines monitoring for a set of pods. 26 | properties: 27 | apiVersion: 28 | description: 'APIVersion defines the versioned schema of this representation 29 | of an object. Servers should convert recognized schemas to the latest 30 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 31 | type: string 32 | kind: 33 | description: 'Kind is a string value representing the REST resource this 34 | object represents. Servers may infer this from the endpoint the client 35 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 36 | type: string 37 | metadata: 38 | type: object 39 | spec: 40 | description: Specification of desired Pod selection for target discovery 41 | by Prometheus. 42 | properties: 43 | attachMetadata: 44 | description: Attaches node metadata to discovered targets. Requires 45 | Prometheus v2.35.0 and above. 46 | properties: 47 | node: 48 | description: When set to true, Prometheus must have permissions 49 | to get Nodes. 50 | type: boolean 51 | type: object 52 | jobLabel: 53 | description: The label to use to retrieve the job name from. 54 | type: string 55 | labelLimit: 56 | description: Per-scrape limit on number of labels that will be accepted 57 | for a sample. Only valid in Prometheus versions 2.27.0 and newer. 58 | format: int64 59 | type: integer 60 | labelNameLengthLimit: 61 | description: Per-scrape limit on length of labels name that will be 62 | accepted for a sample. Only valid in Prometheus versions 2.27.0 63 | and newer. 64 | format: int64 65 | type: integer 66 | labelValueLengthLimit: 67 | description: Per-scrape limit on length of labels value that will 68 | be accepted for a sample. Only valid in Prometheus versions 2.27.0 69 | and newer. 70 | format: int64 71 | type: integer 72 | namespaceSelector: 73 | description: Selector to select which namespaces the Endpoints objects 74 | are discovered from. 75 | properties: 76 | any: 77 | description: Boolean describing whether all namespaces are selected 78 | in contrast to a list restricting them. 79 | type: boolean 80 | matchNames: 81 | description: List of namespace names to select from. 82 | items: 83 | type: string 84 | type: array 85 | type: object 86 | podMetricsEndpoints: 87 | description: A list of endpoints allowed as part of this PodMonitor. 88 | items: 89 | description: PodMetricsEndpoint defines a scrapeable endpoint of 90 | a Kubernetes Pod serving Prometheus metrics. 91 | properties: 92 | authorization: 93 | description: Authorization section for this endpoint 94 | properties: 95 | credentials: 96 | description: The secret's key that contains the credentials 97 | of the request 98 | properties: 99 | key: 100 | description: The key of the secret to select from. Must 101 | be a valid secret key. 102 | type: string 103 | name: 104 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 105 | TODO: Add other useful fields. apiVersion, kind, uid?' 106 | type: string 107 | optional: 108 | description: Specify whether the Secret or its key must 109 | be defined 110 | type: boolean 111 | required: 112 | - key 113 | type: object 114 | x-kubernetes-map-type: atomic 115 | type: 116 | description: Set the authentication type. Defaults to Bearer, 117 | Basic will cause an error 118 | type: string 119 | type: object 120 | basicAuth: 121 | description: 'BasicAuth allow an endpoint to authenticate over 122 | basic authentication. More info: https://prometheus.io/docs/operating/configuration/#endpoint' 123 | properties: 124 | password: 125 | description: The secret in the service monitor namespace 126 | that contains the password for authentication. 127 | properties: 128 | key: 129 | description: The key of the secret to select from. Must 130 | be a valid secret key. 131 | type: string 132 | name: 133 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 134 | TODO: Add other useful fields. apiVersion, kind, uid?' 135 | type: string 136 | optional: 137 | description: Specify whether the Secret or its key must 138 | be defined 139 | type: boolean 140 | required: 141 | - key 142 | type: object 143 | x-kubernetes-map-type: atomic 144 | username: 145 | description: The secret in the service monitor namespace 146 | that contains the username for authentication. 147 | properties: 148 | key: 149 | description: The key of the secret to select from. Must 150 | be a valid secret key. 151 | type: string 152 | name: 153 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 154 | TODO: Add other useful fields. apiVersion, kind, uid?' 155 | type: string 156 | optional: 157 | description: Specify whether the Secret or its key must 158 | be defined 159 | type: boolean 160 | required: 161 | - key 162 | type: object 163 | x-kubernetes-map-type: atomic 164 | type: object 165 | bearerTokenSecret: 166 | description: Secret to mount to read bearer token for scraping 167 | targets. The secret needs to be in the same namespace as the 168 | pod monitor and accessible by the Prometheus Operator. 169 | properties: 170 | key: 171 | description: The key of the secret to select from. Must 172 | be a valid secret key. 173 | type: string 174 | name: 175 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 176 | TODO: Add other useful fields. apiVersion, kind, uid?' 177 | type: string 178 | optional: 179 | description: Specify whether the Secret or its key must 180 | be defined 181 | type: boolean 182 | required: 183 | - key 184 | type: object 185 | x-kubernetes-map-type: atomic 186 | enableHttp2: 187 | description: Whether to enable HTTP2. 188 | type: boolean 189 | filterRunning: 190 | description: 'Drop pods that are not running. (Failed, Succeeded). 191 | Enabled by default. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase' 192 | type: boolean 193 | followRedirects: 194 | description: FollowRedirects configures whether scrape requests 195 | follow HTTP 3xx redirects. 196 | type: boolean 197 | honorLabels: 198 | description: HonorLabels chooses the metric's labels on collisions 199 | with target labels. 200 | type: boolean 201 | honorTimestamps: 202 | description: HonorTimestamps controls whether Prometheus respects 203 | the timestamps present in scraped data. 204 | type: boolean 205 | interval: 206 | description: Interval at which metrics should be scraped If 207 | not specified Prometheus' global scrape interval is used. 208 | pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ 209 | type: string 210 | metricRelabelings: 211 | description: MetricRelabelConfigs to apply to samples before 212 | ingestion. 213 | items: 214 | description: 'RelabelConfig allows dynamic rewriting of the 215 | label set, being applied to samples before ingestion. It 216 | defines ``-section of Prometheus 217 | configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' 218 | properties: 219 | action: 220 | default: replace 221 | description: Action to perform based on regex matching. 222 | Default is 'replace'. uppercase and lowercase actions 223 | require Prometheus >= 2.36. 224 | enum: 225 | - replace 226 | - Replace 227 | - keep 228 | - Keep 229 | - drop 230 | - Drop 231 | - hashmod 232 | - HashMod 233 | - labelmap 234 | - LabelMap 235 | - labeldrop 236 | - LabelDrop 237 | - labelkeep 238 | - LabelKeep 239 | - lowercase 240 | - Lowercase 241 | - uppercase 242 | - Uppercase 243 | type: string 244 | modulus: 245 | description: Modulus to take of the hash of the source 246 | label values. 247 | format: int64 248 | type: integer 249 | regex: 250 | description: Regular expression against which the extracted 251 | value is matched. Default is '(.*)' 252 | type: string 253 | replacement: 254 | description: Replacement value against which a regex replace 255 | is performed if the regular expression matches. Regex 256 | capture groups are available. Default is '$1' 257 | type: string 258 | separator: 259 | description: Separator placed between concatenated source 260 | label values. default is ';'. 261 | type: string 262 | sourceLabels: 263 | description: The source labels select values from existing 264 | labels. Their content is concatenated using the configured 265 | separator and matched against the configured regular 266 | expression for the replace, keep, and drop actions. 267 | items: 268 | description: LabelName is a valid Prometheus label name 269 | which may only contain ASCII letters, numbers, as 270 | well as underscores. 271 | pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ 272 | type: string 273 | type: array 274 | targetLabel: 275 | description: Label to which the resulting value is written 276 | in a replace action. It is mandatory for replace actions. 277 | Regex capture groups are available. 278 | type: string 279 | type: object 280 | type: array 281 | oauth2: 282 | description: OAuth2 for the URL. Only valid in Prometheus versions 283 | 2.27.0 and newer. 284 | properties: 285 | clientId: 286 | description: The secret or configmap containing the OAuth2 287 | client id 288 | properties: 289 | configMap: 290 | description: ConfigMap containing data to use for the 291 | targets. 292 | properties: 293 | key: 294 | description: The key to select. 295 | type: string 296 | name: 297 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 298 | TODO: Add other useful fields. apiVersion, kind, 299 | uid?' 300 | type: string 301 | optional: 302 | description: Specify whether the ConfigMap or its 303 | key must be defined 304 | type: boolean 305 | required: 306 | - key 307 | type: object 308 | x-kubernetes-map-type: atomic 309 | secret: 310 | description: Secret containing data to use for the targets. 311 | properties: 312 | key: 313 | description: The key of the secret to select from. Must 314 | be a valid secret key. 315 | type: string 316 | name: 317 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 318 | TODO: Add other useful fields. apiVersion, kind, 319 | uid?' 320 | type: string 321 | optional: 322 | description: Specify whether the Secret or its key 323 | must be defined 324 | type: boolean 325 | required: 326 | - key 327 | type: object 328 | x-kubernetes-map-type: atomic 329 | type: object 330 | clientSecret: 331 | description: The secret containing the OAuth2 client secret 332 | properties: 333 | key: 334 | description: The key of the secret to select from. Must 335 | be a valid secret key. 336 | type: string 337 | name: 338 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 339 | TODO: Add other useful fields. apiVersion, kind, uid?' 340 | type: string 341 | optional: 342 | description: Specify whether the Secret or its key must 343 | be defined 344 | type: boolean 345 | required: 346 | - key 347 | type: object 348 | x-kubernetes-map-type: atomic 349 | endpointParams: 350 | additionalProperties: 351 | type: string 352 | description: Parameters to append to the token URL 353 | type: object 354 | scopes: 355 | description: OAuth2 scopes used for the token request 356 | items: 357 | type: string 358 | type: array 359 | tokenUrl: 360 | description: The URL to fetch the token from 361 | minLength: 1 362 | type: string 363 | required: 364 | - clientId 365 | - clientSecret 366 | - tokenUrl 367 | type: object 368 | params: 369 | additionalProperties: 370 | items: 371 | type: string 372 | type: array 373 | description: Optional HTTP URL parameters 374 | type: object 375 | path: 376 | description: HTTP path to scrape for metrics. If empty, Prometheus 377 | uses the default value (e.g. `/metrics`). 378 | type: string 379 | port: 380 | description: Name of the pod port this endpoint refers to. Mutually 381 | exclusive with targetPort. 382 | type: string 383 | proxyUrl: 384 | description: ProxyURL eg http://proxyserver:2195 Directs scrapes 385 | to proxy through this endpoint. 386 | type: string 387 | relabelings: 388 | description: 'RelabelConfigs to apply to samples before scraping. 389 | Prometheus Operator automatically adds relabelings for a few 390 | standard Kubernetes fields. The original scrape job''s name 391 | is available via the `__tmp_prometheus_job_name` label. More 392 | info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' 393 | items: 394 | description: 'RelabelConfig allows dynamic rewriting of the 395 | label set, being applied to samples before ingestion. It 396 | defines ``-section of Prometheus 397 | configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' 398 | properties: 399 | action: 400 | default: replace 401 | description: Action to perform based on regex matching. 402 | Default is 'replace'. uppercase and lowercase actions 403 | require Prometheus >= 2.36. 404 | enum: 405 | - replace 406 | - Replace 407 | - keep 408 | - Keep 409 | - drop 410 | - Drop 411 | - hashmod 412 | - HashMod 413 | - labelmap 414 | - LabelMap 415 | - labeldrop 416 | - LabelDrop 417 | - labelkeep 418 | - LabelKeep 419 | - lowercase 420 | - Lowercase 421 | - uppercase 422 | - Uppercase 423 | type: string 424 | modulus: 425 | description: Modulus to take of the hash of the source 426 | label values. 427 | format: int64 428 | type: integer 429 | regex: 430 | description: Regular expression against which the extracted 431 | value is matched. Default is '(.*)' 432 | type: string 433 | replacement: 434 | description: Replacement value against which a regex replace 435 | is performed if the regular expression matches. Regex 436 | capture groups are available. Default is '$1' 437 | type: string 438 | separator: 439 | description: Separator placed between concatenated source 440 | label values. default is ';'. 441 | type: string 442 | sourceLabels: 443 | description: The source labels select values from existing 444 | labels. Their content is concatenated using the configured 445 | separator and matched against the configured regular 446 | expression for the replace, keep, and drop actions. 447 | items: 448 | description: LabelName is a valid Prometheus label name 449 | which may only contain ASCII letters, numbers, as 450 | well as underscores. 451 | pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ 452 | type: string 453 | type: array 454 | targetLabel: 455 | description: Label to which the resulting value is written 456 | in a replace action. It is mandatory for replace actions. 457 | Regex capture groups are available. 458 | type: string 459 | type: object 460 | type: array 461 | scheme: 462 | description: HTTP scheme to use for scraping. 463 | type: string 464 | scrapeTimeout: 465 | description: Timeout after which the scrape is ended If not 466 | specified, the Prometheus global scrape interval is used. 467 | pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ 468 | type: string 469 | targetPort: 470 | anyOf: 471 | - type: integer 472 | - type: string 473 | description: 'Deprecated: Use ''port'' instead.' 474 | x-kubernetes-int-or-string: true 475 | tlsConfig: 476 | description: TLS configuration to use when scraping the endpoint. 477 | properties: 478 | ca: 479 | description: Certificate authority used when verifying server 480 | certificates. 481 | properties: 482 | configMap: 483 | description: ConfigMap containing data to use for the 484 | targets. 485 | properties: 486 | key: 487 | description: The key to select. 488 | type: string 489 | name: 490 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 491 | TODO: Add other useful fields. apiVersion, kind, 492 | uid?' 493 | type: string 494 | optional: 495 | description: Specify whether the ConfigMap or its 496 | key must be defined 497 | type: boolean 498 | required: 499 | - key 500 | type: object 501 | x-kubernetes-map-type: atomic 502 | secret: 503 | description: Secret containing data to use for the targets. 504 | properties: 505 | key: 506 | description: The key of the secret to select from. Must 507 | be a valid secret key. 508 | type: string 509 | name: 510 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 511 | TODO: Add other useful fields. apiVersion, kind, 512 | uid?' 513 | type: string 514 | optional: 515 | description: Specify whether the Secret or its key 516 | must be defined 517 | type: boolean 518 | required: 519 | - key 520 | type: object 521 | x-kubernetes-map-type: atomic 522 | type: object 523 | cert: 524 | description: Client certificate to present when doing client-authentication. 525 | properties: 526 | configMap: 527 | description: ConfigMap containing data to use for the 528 | targets. 529 | properties: 530 | key: 531 | description: The key to select. 532 | type: string 533 | name: 534 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 535 | TODO: Add other useful fields. apiVersion, kind, 536 | uid?' 537 | type: string 538 | optional: 539 | description: Specify whether the ConfigMap or its 540 | key must be defined 541 | type: boolean 542 | required: 543 | - key 544 | type: object 545 | x-kubernetes-map-type: atomic 546 | secret: 547 | description: Secret containing data to use for the targets. 548 | properties: 549 | key: 550 | description: The key of the secret to select from. Must 551 | be a valid secret key. 552 | type: string 553 | name: 554 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 555 | TODO: Add other useful fields. apiVersion, kind, 556 | uid?' 557 | type: string 558 | optional: 559 | description: Specify whether the Secret or its key 560 | must be defined 561 | type: boolean 562 | required: 563 | - key 564 | type: object 565 | x-kubernetes-map-type: atomic 566 | type: object 567 | insecureSkipVerify: 568 | description: Disable target certificate validation. 569 | type: boolean 570 | keySecret: 571 | description: Secret containing the client key file for the 572 | targets. 573 | properties: 574 | key: 575 | description: The key of the secret to select from. Must 576 | be a valid secret key. 577 | type: string 578 | name: 579 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 580 | TODO: Add other useful fields. apiVersion, kind, uid?' 581 | type: string 582 | optional: 583 | description: Specify whether the Secret or its key must 584 | be defined 585 | type: boolean 586 | required: 587 | - key 588 | type: object 589 | x-kubernetes-map-type: atomic 590 | serverName: 591 | description: Used to verify the hostname for the targets. 592 | type: string 593 | type: object 594 | type: object 595 | type: array 596 | podTargetLabels: 597 | description: PodTargetLabels transfers labels on the Kubernetes Pod 598 | onto the target. 599 | items: 600 | type: string 601 | type: array 602 | sampleLimit: 603 | description: SampleLimit defines per-scrape limit on number of scraped 604 | samples that will be accepted. 605 | format: int64 606 | type: integer 607 | selector: 608 | description: Selector to select Pod objects. 609 | properties: 610 | matchExpressions: 611 | description: matchExpressions is a list of label selector requirements. 612 | The requirements are ANDed. 613 | items: 614 | description: A label selector requirement is a selector that 615 | contains values, a key, and an operator that relates the key 616 | and values. 617 | properties: 618 | key: 619 | description: key is the label key that the selector applies 620 | to. 621 | type: string 622 | operator: 623 | description: operator represents a key's relationship to 624 | a set of values. Valid operators are In, NotIn, Exists 625 | and DoesNotExist. 626 | type: string 627 | values: 628 | description: values is an array of string values. If the 629 | operator is In or NotIn, the values array must be non-empty. 630 | If the operator is Exists or DoesNotExist, the values 631 | array must be empty. This array is replaced during a strategic 632 | merge patch. 633 | items: 634 | type: string 635 | type: array 636 | required: 637 | - key 638 | - operator 639 | type: object 640 | type: array 641 | matchLabels: 642 | additionalProperties: 643 | type: string 644 | description: matchLabels is a map of {key,value} pairs. A single 645 | {key,value} in the matchLabels map is equivalent to an element 646 | of matchExpressions, whose key field is "key", the operator 647 | is "In", and the values array contains only "value". The requirements 648 | are ANDed. 649 | type: object 650 | type: object 651 | x-kubernetes-map-type: atomic 652 | targetLimit: 653 | description: TargetLimit defines a limit on the number of scraped 654 | targets that will be accepted. 655 | format: int64 656 | type: integer 657 | required: 658 | - podMetricsEndpoints 659 | - selector 660 | type: object 661 | required: 662 | - spec 663 | type: object 664 | served: true 665 | storage: true 666 | -------------------------------------------------------------------------------- /prometheus-operator-crd/probes.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.9.2 7 | creationTimestamp: null 8 | name: probes.monitoring.coreos.com 9 | spec: 10 | group: monitoring.coreos.com 11 | names: 12 | categories: 13 | - prometheus-operator 14 | kind: Probe 15 | listKind: ProbeList 16 | plural: probes 17 | shortNames: 18 | - prb 19 | singular: probe 20 | scope: Namespaced 21 | versions: 22 | - name: v1 23 | schema: 24 | openAPIV3Schema: 25 | description: Probe defines monitoring for a set of static targets or ingresses. 26 | properties: 27 | apiVersion: 28 | description: 'APIVersion defines the versioned schema of this representation 29 | of an object. Servers should convert recognized schemas to the latest 30 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 31 | type: string 32 | kind: 33 | description: 'Kind is a string value representing the REST resource this 34 | object represents. Servers may infer this from the endpoint the client 35 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 36 | type: string 37 | metadata: 38 | type: object 39 | spec: 40 | description: Specification of desired Ingress selection for target discovery 41 | by Prometheus. 42 | properties: 43 | authorization: 44 | description: Authorization section for this endpoint 45 | properties: 46 | credentials: 47 | description: The secret's key that contains the credentials of 48 | the request 49 | properties: 50 | key: 51 | description: The key of the secret to select from. Must be 52 | a valid secret key. 53 | type: string 54 | name: 55 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 56 | TODO: Add other useful fields. apiVersion, kind, uid?' 57 | type: string 58 | optional: 59 | description: Specify whether the Secret or its key must be 60 | defined 61 | type: boolean 62 | required: 63 | - key 64 | type: object 65 | x-kubernetes-map-type: atomic 66 | type: 67 | description: Set the authentication type. Defaults to Bearer, 68 | Basic will cause an error 69 | type: string 70 | type: object 71 | basicAuth: 72 | description: 'BasicAuth allow an endpoint to authenticate over basic 73 | authentication. More info: https://prometheus.io/docs/operating/configuration/#endpoint' 74 | properties: 75 | password: 76 | description: The secret in the service monitor namespace that 77 | contains the password for authentication. 78 | properties: 79 | key: 80 | description: The key of the secret to select from. Must be 81 | a valid secret key. 82 | type: string 83 | name: 84 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 85 | TODO: Add other useful fields. apiVersion, kind, uid?' 86 | type: string 87 | optional: 88 | description: Specify whether the Secret or its key must be 89 | defined 90 | type: boolean 91 | required: 92 | - key 93 | type: object 94 | x-kubernetes-map-type: atomic 95 | username: 96 | description: The secret in the service monitor namespace that 97 | contains the username for authentication. 98 | properties: 99 | key: 100 | description: The key of the secret to select from. Must be 101 | a valid secret key. 102 | type: string 103 | name: 104 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 105 | TODO: Add other useful fields. apiVersion, kind, uid?' 106 | type: string 107 | optional: 108 | description: Specify whether the Secret or its key must be 109 | defined 110 | type: boolean 111 | required: 112 | - key 113 | type: object 114 | x-kubernetes-map-type: atomic 115 | type: object 116 | bearerTokenSecret: 117 | description: Secret to mount to read bearer token for scraping targets. 118 | The secret needs to be in the same namespace as the probe and accessible 119 | by the Prometheus Operator. 120 | properties: 121 | key: 122 | description: The key of the secret to select from. Must be a 123 | valid secret key. 124 | type: string 125 | name: 126 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 127 | TODO: Add other useful fields. apiVersion, kind, uid?' 128 | type: string 129 | optional: 130 | description: Specify whether the Secret or its key must be defined 131 | type: boolean 132 | required: 133 | - key 134 | type: object 135 | x-kubernetes-map-type: atomic 136 | interval: 137 | description: Interval at which targets are probed using the configured 138 | prober. If not specified Prometheus' global scrape interval is used. 139 | pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ 140 | type: string 141 | jobName: 142 | description: The job name assigned to scraped metrics by default. 143 | type: string 144 | labelLimit: 145 | description: Per-scrape limit on number of labels that will be accepted 146 | for a sample. Only valid in Prometheus versions 2.27.0 and newer. 147 | format: int64 148 | type: integer 149 | labelNameLengthLimit: 150 | description: Per-scrape limit on length of labels name that will be 151 | accepted for a sample. Only valid in Prometheus versions 2.27.0 152 | and newer. 153 | format: int64 154 | type: integer 155 | labelValueLengthLimit: 156 | description: Per-scrape limit on length of labels value that will 157 | be accepted for a sample. Only valid in Prometheus versions 2.27.0 158 | and newer. 159 | format: int64 160 | type: integer 161 | metricRelabelings: 162 | description: MetricRelabelConfigs to apply to samples before ingestion. 163 | items: 164 | description: 'RelabelConfig allows dynamic rewriting of the label 165 | set, being applied to samples before ingestion. It defines ``-section 166 | of Prometheus configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' 167 | properties: 168 | action: 169 | default: replace 170 | description: Action to perform based on regex matching. Default 171 | is 'replace'. uppercase and lowercase actions require Prometheus 172 | >= 2.36. 173 | enum: 174 | - replace 175 | - Replace 176 | - keep 177 | - Keep 178 | - drop 179 | - Drop 180 | - hashmod 181 | - HashMod 182 | - labelmap 183 | - LabelMap 184 | - labeldrop 185 | - LabelDrop 186 | - labelkeep 187 | - LabelKeep 188 | - lowercase 189 | - Lowercase 190 | - uppercase 191 | - Uppercase 192 | type: string 193 | modulus: 194 | description: Modulus to take of the hash of the source label 195 | values. 196 | format: int64 197 | type: integer 198 | regex: 199 | description: Regular expression against which the extracted 200 | value is matched. Default is '(.*)' 201 | type: string 202 | replacement: 203 | description: Replacement value against which a regex replace 204 | is performed if the regular expression matches. Regex capture 205 | groups are available. Default is '$1' 206 | type: string 207 | separator: 208 | description: Separator placed between concatenated source label 209 | values. default is ';'. 210 | type: string 211 | sourceLabels: 212 | description: The source labels select values from existing labels. 213 | Their content is concatenated using the configured separator 214 | and matched against the configured regular expression for 215 | the replace, keep, and drop actions. 216 | items: 217 | description: LabelName is a valid Prometheus label name which 218 | may only contain ASCII letters, numbers, as well as underscores. 219 | pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ 220 | type: string 221 | type: array 222 | targetLabel: 223 | description: Label to which the resulting value is written in 224 | a replace action. It is mandatory for replace actions. Regex 225 | capture groups are available. 226 | type: string 227 | type: object 228 | type: array 229 | module: 230 | description: 'The module to use for probing specifying how to probe 231 | the target. Example module configuring in the blackbox exporter: 232 | https://github.com/prometheus/blackbox_exporter/blob/master/example.yml' 233 | type: string 234 | oauth2: 235 | description: OAuth2 for the URL. Only valid in Prometheus versions 236 | 2.27.0 and newer. 237 | properties: 238 | clientId: 239 | description: The secret or configmap containing the OAuth2 client 240 | id 241 | properties: 242 | configMap: 243 | description: ConfigMap containing data to use for the targets. 244 | properties: 245 | key: 246 | description: The key to select. 247 | type: string 248 | name: 249 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 250 | TODO: Add other useful fields. apiVersion, kind, uid?' 251 | type: string 252 | optional: 253 | description: Specify whether the ConfigMap or its key 254 | must be defined 255 | type: boolean 256 | required: 257 | - key 258 | type: object 259 | x-kubernetes-map-type: atomic 260 | secret: 261 | description: Secret containing data to use for the targets. 262 | properties: 263 | key: 264 | description: The key of the secret to select from. Must 265 | be a valid secret key. 266 | type: string 267 | name: 268 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 269 | TODO: Add other useful fields. apiVersion, kind, uid?' 270 | type: string 271 | optional: 272 | description: Specify whether the Secret or its key must 273 | be defined 274 | type: boolean 275 | required: 276 | - key 277 | type: object 278 | x-kubernetes-map-type: atomic 279 | type: object 280 | clientSecret: 281 | description: The secret containing the OAuth2 client secret 282 | properties: 283 | key: 284 | description: The key of the secret to select from. Must be 285 | a valid secret key. 286 | type: string 287 | name: 288 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 289 | TODO: Add other useful fields. apiVersion, kind, uid?' 290 | type: string 291 | optional: 292 | description: Specify whether the Secret or its key must be 293 | defined 294 | type: boolean 295 | required: 296 | - key 297 | type: object 298 | x-kubernetes-map-type: atomic 299 | endpointParams: 300 | additionalProperties: 301 | type: string 302 | description: Parameters to append to the token URL 303 | type: object 304 | scopes: 305 | description: OAuth2 scopes used for the token request 306 | items: 307 | type: string 308 | type: array 309 | tokenUrl: 310 | description: The URL to fetch the token from 311 | minLength: 1 312 | type: string 313 | required: 314 | - clientId 315 | - clientSecret 316 | - tokenUrl 317 | type: object 318 | prober: 319 | description: Specification for the prober to use for probing targets. 320 | The prober.URL parameter is required. Targets cannot be probed if 321 | left empty. 322 | properties: 323 | path: 324 | default: /probe 325 | description: Path to collect metrics from. Defaults to `/probe`. 326 | type: string 327 | proxyUrl: 328 | description: Optional ProxyURL. 329 | type: string 330 | scheme: 331 | description: HTTP scheme to use for scraping. Defaults to `http`. 332 | type: string 333 | url: 334 | description: Mandatory URL of the prober. 335 | type: string 336 | required: 337 | - url 338 | type: object 339 | sampleLimit: 340 | description: SampleLimit defines per-scrape limit on number of scraped 341 | samples that will be accepted. 342 | format: int64 343 | type: integer 344 | scrapeTimeout: 345 | description: Timeout for scraping metrics from the Prometheus exporter. 346 | If not specified, the Prometheus global scrape interval is used. 347 | pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ 348 | type: string 349 | targetLimit: 350 | description: TargetLimit defines a limit on the number of scraped 351 | targets that will be accepted. 352 | format: int64 353 | type: integer 354 | targets: 355 | description: Targets defines a set of static or dynamically discovered 356 | targets to probe. 357 | properties: 358 | ingress: 359 | description: ingress defines the Ingress objects to probe and 360 | the relabeling configuration. If `staticConfig` is also defined, 361 | `staticConfig` takes precedence. 362 | properties: 363 | namespaceSelector: 364 | description: From which namespaces to select Ingress objects. 365 | properties: 366 | any: 367 | description: Boolean describing whether all namespaces 368 | are selected in contrast to a list restricting them. 369 | type: boolean 370 | matchNames: 371 | description: List of namespace names to select from. 372 | items: 373 | type: string 374 | type: array 375 | type: object 376 | relabelingConfigs: 377 | description: 'RelabelConfigs to apply to the label set of 378 | the target before it gets scraped. The original ingress 379 | address is available via the `__tmp_prometheus_ingress_address` 380 | label. It can be used to customize the probed URL. The original 381 | scrape job''s name is available via the `__tmp_prometheus_job_name` 382 | label. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' 383 | items: 384 | description: 'RelabelConfig allows dynamic rewriting of 385 | the label set, being applied to samples before ingestion. 386 | It defines ``-section of Prometheus 387 | configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' 388 | properties: 389 | action: 390 | default: replace 391 | description: Action to perform based on regex matching. 392 | Default is 'replace'. uppercase and lowercase actions 393 | require Prometheus >= 2.36. 394 | enum: 395 | - replace 396 | - Replace 397 | - keep 398 | - Keep 399 | - drop 400 | - Drop 401 | - hashmod 402 | - HashMod 403 | - labelmap 404 | - LabelMap 405 | - labeldrop 406 | - LabelDrop 407 | - labelkeep 408 | - LabelKeep 409 | - lowercase 410 | - Lowercase 411 | - uppercase 412 | - Uppercase 413 | type: string 414 | modulus: 415 | description: Modulus to take of the hash of the source 416 | label values. 417 | format: int64 418 | type: integer 419 | regex: 420 | description: Regular expression against which the extracted 421 | value is matched. Default is '(.*)' 422 | type: string 423 | replacement: 424 | description: Replacement value against which a regex 425 | replace is performed if the regular expression matches. 426 | Regex capture groups are available. Default is '$1' 427 | type: string 428 | separator: 429 | description: Separator placed between concatenated source 430 | label values. default is ';'. 431 | type: string 432 | sourceLabels: 433 | description: The source labels select values from existing 434 | labels. Their content is concatenated using the configured 435 | separator and matched against the configured regular 436 | expression for the replace, keep, and drop actions. 437 | items: 438 | description: LabelName is a valid Prometheus label 439 | name which may only contain ASCII letters, numbers, 440 | as well as underscores. 441 | pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ 442 | type: string 443 | type: array 444 | targetLabel: 445 | description: Label to which the resulting value is written 446 | in a replace action. It is mandatory for replace actions. 447 | Regex capture groups are available. 448 | type: string 449 | type: object 450 | type: array 451 | selector: 452 | description: Selector to select the Ingress objects. 453 | properties: 454 | matchExpressions: 455 | description: matchExpressions is a list of label selector 456 | requirements. The requirements are ANDed. 457 | items: 458 | description: A label selector requirement is a selector 459 | that contains values, a key, and an operator that 460 | relates the key and values. 461 | properties: 462 | key: 463 | description: key is the label key that the selector 464 | applies to. 465 | type: string 466 | operator: 467 | description: operator represents a key's relationship 468 | to a set of values. Valid operators are In, NotIn, 469 | Exists and DoesNotExist. 470 | type: string 471 | values: 472 | description: values is an array of string values. 473 | If the operator is In or NotIn, the values array 474 | must be non-empty. If the operator is Exists or 475 | DoesNotExist, the values array must be empty. 476 | This array is replaced during a strategic merge 477 | patch. 478 | items: 479 | type: string 480 | type: array 481 | required: 482 | - key 483 | - operator 484 | type: object 485 | type: array 486 | matchLabels: 487 | additionalProperties: 488 | type: string 489 | description: matchLabels is a map of {key,value} pairs. 490 | A single {key,value} in the matchLabels map is equivalent 491 | to an element of matchExpressions, whose key field is 492 | "key", the operator is "In", and the values array contains 493 | only "value". The requirements are ANDed. 494 | type: object 495 | type: object 496 | x-kubernetes-map-type: atomic 497 | type: object 498 | staticConfig: 499 | description: 'staticConfig defines the static list of targets 500 | to probe and the relabeling configuration. If `ingress` is also 501 | defined, `staticConfig` takes precedence. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#static_config.' 502 | properties: 503 | labels: 504 | additionalProperties: 505 | type: string 506 | description: Labels assigned to all metrics scraped from the 507 | targets. 508 | type: object 509 | relabelingConfigs: 510 | description: 'RelabelConfigs to apply to the label set of 511 | the targets before it gets scraped. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' 512 | items: 513 | description: 'RelabelConfig allows dynamic rewriting of 514 | the label set, being applied to samples before ingestion. 515 | It defines ``-section of Prometheus 516 | configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' 517 | properties: 518 | action: 519 | default: replace 520 | description: Action to perform based on regex matching. 521 | Default is 'replace'. uppercase and lowercase actions 522 | require Prometheus >= 2.36. 523 | enum: 524 | - replace 525 | - Replace 526 | - keep 527 | - Keep 528 | - drop 529 | - Drop 530 | - hashmod 531 | - HashMod 532 | - labelmap 533 | - LabelMap 534 | - labeldrop 535 | - LabelDrop 536 | - labelkeep 537 | - LabelKeep 538 | - lowercase 539 | - Lowercase 540 | - uppercase 541 | - Uppercase 542 | type: string 543 | modulus: 544 | description: Modulus to take of the hash of the source 545 | label values. 546 | format: int64 547 | type: integer 548 | regex: 549 | description: Regular expression against which the extracted 550 | value is matched. Default is '(.*)' 551 | type: string 552 | replacement: 553 | description: Replacement value against which a regex 554 | replace is performed if the regular expression matches. 555 | Regex capture groups are available. Default is '$1' 556 | type: string 557 | separator: 558 | description: Separator placed between concatenated source 559 | label values. default is ';'. 560 | type: string 561 | sourceLabels: 562 | description: The source labels select values from existing 563 | labels. Their content is concatenated using the configured 564 | separator and matched against the configured regular 565 | expression for the replace, keep, and drop actions. 566 | items: 567 | description: LabelName is a valid Prometheus label 568 | name which may only contain ASCII letters, numbers, 569 | as well as underscores. 570 | pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ 571 | type: string 572 | type: array 573 | targetLabel: 574 | description: Label to which the resulting value is written 575 | in a replace action. It is mandatory for replace actions. 576 | Regex capture groups are available. 577 | type: string 578 | type: object 579 | type: array 580 | static: 581 | description: The list of hosts to probe. 582 | items: 583 | type: string 584 | type: array 585 | type: object 586 | type: object 587 | tlsConfig: 588 | description: TLS configuration to use when scraping the endpoint. 589 | properties: 590 | ca: 591 | description: Certificate authority used when verifying server 592 | certificates. 593 | properties: 594 | configMap: 595 | description: ConfigMap containing data to use for the targets. 596 | properties: 597 | key: 598 | description: The key to select. 599 | type: string 600 | name: 601 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 602 | TODO: Add other useful fields. apiVersion, kind, uid?' 603 | type: string 604 | optional: 605 | description: Specify whether the ConfigMap or its key 606 | must be defined 607 | type: boolean 608 | required: 609 | - key 610 | type: object 611 | x-kubernetes-map-type: atomic 612 | secret: 613 | description: Secret containing data to use for the targets. 614 | properties: 615 | key: 616 | description: The key of the secret to select from. Must 617 | be a valid secret key. 618 | type: string 619 | name: 620 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 621 | TODO: Add other useful fields. apiVersion, kind, uid?' 622 | type: string 623 | optional: 624 | description: Specify whether the Secret or its key must 625 | be defined 626 | type: boolean 627 | required: 628 | - key 629 | type: object 630 | x-kubernetes-map-type: atomic 631 | type: object 632 | cert: 633 | description: Client certificate to present when doing client-authentication. 634 | properties: 635 | configMap: 636 | description: ConfigMap containing data to use for the targets. 637 | properties: 638 | key: 639 | description: The key to select. 640 | type: string 641 | name: 642 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 643 | TODO: Add other useful fields. apiVersion, kind, uid?' 644 | type: string 645 | optional: 646 | description: Specify whether the ConfigMap or its key 647 | must be defined 648 | type: boolean 649 | required: 650 | - key 651 | type: object 652 | x-kubernetes-map-type: atomic 653 | secret: 654 | description: Secret containing data to use for the targets. 655 | properties: 656 | key: 657 | description: The key of the secret to select from. Must 658 | be a valid secret key. 659 | type: string 660 | name: 661 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 662 | TODO: Add other useful fields. apiVersion, kind, uid?' 663 | type: string 664 | optional: 665 | description: Specify whether the Secret or its key must 666 | be defined 667 | type: boolean 668 | required: 669 | - key 670 | type: object 671 | x-kubernetes-map-type: atomic 672 | type: object 673 | insecureSkipVerify: 674 | description: Disable target certificate validation. 675 | type: boolean 676 | keySecret: 677 | description: Secret containing the client key file for the targets. 678 | properties: 679 | key: 680 | description: The key of the secret to select from. Must be 681 | a valid secret key. 682 | type: string 683 | name: 684 | description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names 685 | TODO: Add other useful fields. apiVersion, kind, uid?' 686 | type: string 687 | optional: 688 | description: Specify whether the Secret or its key must be 689 | defined 690 | type: boolean 691 | required: 692 | - key 693 | type: object 694 | x-kubernetes-map-type: atomic 695 | serverName: 696 | description: Used to verify the hostname for the targets. 697 | type: string 698 | type: object 699 | type: object 700 | required: 701 | - spec 702 | type: object 703 | served: true 704 | storage: true 705 | -------------------------------------------------------------------------------- /prometheus-operator-crd/prometheusrules.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | controller-gen.kubebuilder.io/version: v0.9.2 7 | creationTimestamp: null 8 | name: prometheusrules.monitoring.coreos.com 9 | spec: 10 | group: monitoring.coreos.com 11 | names: 12 | categories: 13 | - prometheus-operator 14 | kind: PrometheusRule 15 | listKind: PrometheusRuleList 16 | plural: prometheusrules 17 | shortNames: 18 | - promrule 19 | singular: prometheusrule 20 | scope: Namespaced 21 | versions: 22 | - name: v1 23 | schema: 24 | openAPIV3Schema: 25 | description: PrometheusRule defines recording and alerting rules for a Prometheus 26 | instance 27 | properties: 28 | apiVersion: 29 | description: 'APIVersion defines the versioned schema of this representation 30 | of an object. Servers should convert recognized schemas to the latest 31 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 32 | type: string 33 | kind: 34 | description: 'Kind is a string value representing the REST resource this 35 | object represents. Servers may infer this from the endpoint the client 36 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 37 | type: string 38 | metadata: 39 | type: object 40 | spec: 41 | description: Specification of desired alerting rule definitions for Prometheus. 42 | properties: 43 | groups: 44 | description: Content of Prometheus rule file 45 | items: 46 | description: RuleGroup is a list of sequentially evaluated recording 47 | and alerting rules. 48 | properties: 49 | interval: 50 | description: Interval determines how often rules in the group 51 | are evaluated. 52 | pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ 53 | type: string 54 | name: 55 | description: Name of the rule group. 56 | minLength: 1 57 | type: string 58 | partial_response_strategy: 59 | default: "" 60 | description: 'PartialResponseStrategy is only used by ThanosRuler 61 | and will be ignored by Prometheus instances. More info: https://github.com/thanos-io/thanos/blob/main/docs/components/rule.md#partial-response' 62 | pattern: ^(?i)(abort|warn)?$ 63 | type: string 64 | rules: 65 | description: List of alerting and recording rules. 66 | items: 67 | description: 'Rule describes an alerting or recording rule 68 | See Prometheus documentation: [alerting](https://www.prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) 69 | or [recording](https://www.prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules) 70 | rule' 71 | properties: 72 | alert: 73 | description: Name of the alert. Must be a valid label 74 | value. Only one of `record` and `alert` must be set. 75 | type: string 76 | annotations: 77 | additionalProperties: 78 | type: string 79 | description: Annotations to add to each alert. Only valid 80 | for alerting rules. 81 | type: object 82 | expr: 83 | anyOf: 84 | - type: integer 85 | - type: string 86 | description: PromQL expression to evaluate. 87 | x-kubernetes-int-or-string: true 88 | for: 89 | description: Alerts are considered firing once they have 90 | been returned for this long. 91 | pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ 92 | type: string 93 | labels: 94 | additionalProperties: 95 | type: string 96 | description: Labels to add or overwrite. 97 | type: object 98 | record: 99 | description: Name of the time series to output to. Must 100 | be a valid metric name. Only one of `record` and `alert` 101 | must be set. 102 | type: string 103 | required: 104 | - expr 105 | type: object 106 | type: array 107 | required: 108 | - name 109 | - rules 110 | type: object 111 | type: array 112 | x-kubernetes-list-map-keys: 113 | - name 114 | x-kubernetes-list-type: map 115 | type: object 116 | required: 117 | - spec 118 | type: object 119 | served: true 120 | storage: true 121 | -------------------------------------------------------------------------------- /rust-app/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [net] 2 | git-fetch-with-cli = true 3 | -------------------------------------------------------------------------------- /rust-app/.dockerignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /rust-app/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "actix-codec" 7 | version = "0.5.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe" 10 | dependencies = [ 11 | "bitflags", 12 | "bytes", 13 | "futures-core", 14 | "futures-sink", 15 | "log", 16 | "memchr", 17 | "pin-project-lite", 18 | "tokio", 19 | "tokio-util", 20 | ] 21 | 22 | [[package]] 23 | name = "actix-http" 24 | version = "3.3.0" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | checksum = "0070905b2c4a98d184c4e81025253cb192aa8a73827553f38e9410801ceb35bb" 27 | dependencies = [ 28 | "actix-codec", 29 | "actix-rt", 30 | "actix-service", 31 | "actix-utils", 32 | "ahash", 33 | "base64", 34 | "bitflags", 35 | "brotli", 36 | "bytes", 37 | "bytestring", 38 | "derive_more", 39 | "encoding_rs", 40 | "flate2", 41 | "futures-core", 42 | "h2", 43 | "http", 44 | "httparse", 45 | "httpdate", 46 | "itoa", 47 | "language-tags", 48 | "local-channel", 49 | "mime", 50 | "percent-encoding", 51 | "pin-project-lite", 52 | "rand", 53 | "sha1", 54 | "smallvec", 55 | "tokio", 56 | "tokio-util", 57 | "tracing", 58 | "zstd", 59 | ] 60 | 61 | [[package]] 62 | name = "actix-macros" 63 | version = "0.2.3" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" 66 | dependencies = [ 67 | "quote", 68 | "syn", 69 | ] 70 | 71 | [[package]] 72 | name = "actix-router" 73 | version = "0.5.1" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" 76 | dependencies = [ 77 | "bytestring", 78 | "http", 79 | "regex", 80 | "serde", 81 | "tracing", 82 | ] 83 | 84 | [[package]] 85 | name = "actix-rt" 86 | version = "2.8.0" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "15265b6b8e2347670eb363c47fc8c75208b4a4994b27192f345fcbe707804f3e" 89 | dependencies = [ 90 | "futures-core", 91 | "tokio", 92 | ] 93 | 94 | [[package]] 95 | name = "actix-server" 96 | version = "2.2.0" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "3e8613a75dd50cc45f473cee3c34d59ed677c0f7b44480ce3b8247d7dc519327" 99 | dependencies = [ 100 | "actix-rt", 101 | "actix-service", 102 | "actix-utils", 103 | "futures-core", 104 | "futures-util", 105 | "mio", 106 | "num_cpus", 107 | "socket2", 108 | "tokio", 109 | "tracing", 110 | ] 111 | 112 | [[package]] 113 | name = "actix-service" 114 | version = "2.0.2" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" 117 | dependencies = [ 118 | "futures-core", 119 | "paste", 120 | "pin-project-lite", 121 | ] 122 | 123 | [[package]] 124 | name = "actix-utils" 125 | version = "3.0.1" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" 128 | dependencies = [ 129 | "local-waker", 130 | "pin-project-lite", 131 | ] 132 | 133 | [[package]] 134 | name = "actix-web" 135 | version = "4.3.0" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "464e0fddc668ede5f26ec1f9557a8d44eda948732f40c6b0ad79126930eb775f" 138 | dependencies = [ 139 | "actix-codec", 140 | "actix-http", 141 | "actix-macros", 142 | "actix-router", 143 | "actix-rt", 144 | "actix-server", 145 | "actix-service", 146 | "actix-utils", 147 | "actix-web-codegen", 148 | "ahash", 149 | "bytes", 150 | "bytestring", 151 | "cfg-if", 152 | "cookie", 153 | "derive_more", 154 | "encoding_rs", 155 | "futures-core", 156 | "futures-util", 157 | "http", 158 | "itoa", 159 | "language-tags", 160 | "log", 161 | "mime", 162 | "once_cell", 163 | "pin-project-lite", 164 | "regex", 165 | "serde", 166 | "serde_json", 167 | "serde_urlencoded", 168 | "smallvec", 169 | "socket2", 170 | "time", 171 | "url", 172 | ] 173 | 174 | [[package]] 175 | name = "actix-web-codegen" 176 | version = "4.1.0" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "1fa9362663c8643d67b2d5eafba49e4cb2c8a053a29ed00a0bea121f17c76b13" 179 | dependencies = [ 180 | "actix-router", 181 | "proc-macro2", 182 | "quote", 183 | "syn", 184 | ] 185 | 186 | [[package]] 187 | name = "adler" 188 | version = "1.0.2" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 191 | 192 | [[package]] 193 | name = "ahash" 194 | version = "0.7.6" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 197 | dependencies = [ 198 | "getrandom", 199 | "once_cell", 200 | "version_check", 201 | ] 202 | 203 | [[package]] 204 | name = "aho-corasick" 205 | version = "0.7.20" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" 208 | dependencies = [ 209 | "memchr", 210 | ] 211 | 212 | [[package]] 213 | name = "alloc-no-stdlib" 214 | version = "2.0.4" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" 217 | 218 | [[package]] 219 | name = "alloc-stdlib" 220 | version = "0.2.2" 221 | source = "registry+https://github.com/rust-lang/crates.io-index" 222 | checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" 223 | dependencies = [ 224 | "alloc-no-stdlib", 225 | ] 226 | 227 | [[package]] 228 | name = "autocfg" 229 | version = "1.1.0" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 232 | 233 | [[package]] 234 | name = "base64" 235 | version = "0.21.0" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" 238 | 239 | [[package]] 240 | name = "bitflags" 241 | version = "1.3.2" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 244 | 245 | [[package]] 246 | name = "block-buffer" 247 | version = "0.10.3" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" 250 | dependencies = [ 251 | "generic-array", 252 | ] 253 | 254 | [[package]] 255 | name = "brotli" 256 | version = "3.3.4" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" 259 | dependencies = [ 260 | "alloc-no-stdlib", 261 | "alloc-stdlib", 262 | "brotli-decompressor", 263 | ] 264 | 265 | [[package]] 266 | name = "brotli-decompressor" 267 | version = "2.3.4" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" 270 | dependencies = [ 271 | "alloc-no-stdlib", 272 | "alloc-stdlib", 273 | ] 274 | 275 | [[package]] 276 | name = "bytes" 277 | version = "1.3.0" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" 280 | 281 | [[package]] 282 | name = "bytestring" 283 | version = "1.2.0" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "f7f83e57d9154148e355404702e2694463241880b939570d7c97c014da7a69a1" 286 | dependencies = [ 287 | "bytes", 288 | ] 289 | 290 | [[package]] 291 | name = "cc" 292 | version = "1.0.77" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" 295 | dependencies = [ 296 | "jobserver", 297 | ] 298 | 299 | [[package]] 300 | name = "cfg-if" 301 | version = "1.0.0" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 304 | 305 | [[package]] 306 | name = "convert_case" 307 | version = "0.4.0" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 310 | 311 | [[package]] 312 | name = "cookie" 313 | version = "0.16.1" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "344adc371239ef32293cb1c4fe519592fcf21206c79c02854320afcdf3ab4917" 316 | dependencies = [ 317 | "percent-encoding", 318 | "time", 319 | "version_check", 320 | ] 321 | 322 | [[package]] 323 | name = "cpufeatures" 324 | version = "0.2.5" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" 327 | dependencies = [ 328 | "libc", 329 | ] 330 | 331 | [[package]] 332 | name = "crc32fast" 333 | version = "1.3.2" 334 | source = "registry+https://github.com/rust-lang/crates.io-index" 335 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 336 | dependencies = [ 337 | "cfg-if", 338 | ] 339 | 340 | [[package]] 341 | name = "crypto-common" 342 | version = "0.1.6" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 345 | dependencies = [ 346 | "generic-array", 347 | "typenum", 348 | ] 349 | 350 | [[package]] 351 | name = "derive_more" 352 | version = "0.99.17" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 355 | dependencies = [ 356 | "convert_case", 357 | "proc-macro2", 358 | "quote", 359 | "rustc_version", 360 | "syn", 361 | ] 362 | 363 | [[package]] 364 | name = "digest" 365 | version = "0.10.6" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" 368 | dependencies = [ 369 | "block-buffer", 370 | "crypto-common", 371 | ] 372 | 373 | [[package]] 374 | name = "encoding_rs" 375 | version = "0.8.31" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" 378 | dependencies = [ 379 | "cfg-if", 380 | ] 381 | 382 | [[package]] 383 | name = "flate2" 384 | version = "1.0.25" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" 387 | dependencies = [ 388 | "crc32fast", 389 | "miniz_oxide", 390 | ] 391 | 392 | [[package]] 393 | name = "fnv" 394 | version = "1.0.7" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 397 | 398 | [[package]] 399 | name = "form_urlencoded" 400 | version = "1.1.0" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 403 | dependencies = [ 404 | "percent-encoding", 405 | ] 406 | 407 | [[package]] 408 | name = "futures-core" 409 | version = "0.3.25" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" 412 | 413 | [[package]] 414 | name = "futures-sink" 415 | version = "0.3.25" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" 418 | 419 | [[package]] 420 | name = "futures-task" 421 | version = "0.3.25" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" 424 | 425 | [[package]] 426 | name = "futures-util" 427 | version = "0.3.25" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" 430 | dependencies = [ 431 | "futures-core", 432 | "futures-task", 433 | "pin-project-lite", 434 | "pin-utils", 435 | ] 436 | 437 | [[package]] 438 | name = "generic-array" 439 | version = "0.14.6" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" 442 | dependencies = [ 443 | "typenum", 444 | "version_check", 445 | ] 446 | 447 | [[package]] 448 | name = "getrandom" 449 | version = "0.2.8" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" 452 | dependencies = [ 453 | "cfg-if", 454 | "libc", 455 | "wasi", 456 | ] 457 | 458 | [[package]] 459 | name = "h2" 460 | version = "0.3.15" 461 | source = "registry+https://github.com/rust-lang/crates.io-index" 462 | checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" 463 | dependencies = [ 464 | "bytes", 465 | "fnv", 466 | "futures-core", 467 | "futures-sink", 468 | "futures-util", 469 | "http", 470 | "indexmap", 471 | "slab", 472 | "tokio", 473 | "tokio-util", 474 | "tracing", 475 | ] 476 | 477 | [[package]] 478 | name = "hashbrown" 479 | version = "0.12.3" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 482 | 483 | [[package]] 484 | name = "hermit-abi" 485 | version = "0.1.19" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 488 | dependencies = [ 489 | "libc", 490 | ] 491 | 492 | [[package]] 493 | name = "http" 494 | version = "0.2.8" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" 497 | dependencies = [ 498 | "bytes", 499 | "fnv", 500 | "itoa", 501 | ] 502 | 503 | [[package]] 504 | name = "httparse" 505 | version = "1.8.0" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 508 | 509 | [[package]] 510 | name = "httpdate" 511 | version = "1.0.2" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 514 | 515 | [[package]] 516 | name = "idna" 517 | version = "0.3.0" 518 | source = "registry+https://github.com/rust-lang/crates.io-index" 519 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 520 | dependencies = [ 521 | "unicode-bidi", 522 | "unicode-normalization", 523 | ] 524 | 525 | [[package]] 526 | name = "indexmap" 527 | version = "1.9.2" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" 530 | dependencies = [ 531 | "autocfg", 532 | "hashbrown", 533 | ] 534 | 535 | [[package]] 536 | name = "itoa" 537 | version = "1.0.4" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" 540 | 541 | [[package]] 542 | name = "jobserver" 543 | version = "0.1.25" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" 546 | dependencies = [ 547 | "libc", 548 | ] 549 | 550 | [[package]] 551 | name = "language-tags" 552 | version = "0.3.2" 553 | source = "registry+https://github.com/rust-lang/crates.io-index" 554 | checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" 555 | 556 | [[package]] 557 | name = "libc" 558 | version = "0.2.138" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" 561 | 562 | [[package]] 563 | name = "local-channel" 564 | version = "0.1.3" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c" 567 | dependencies = [ 568 | "futures-core", 569 | "futures-sink", 570 | "futures-util", 571 | "local-waker", 572 | ] 573 | 574 | [[package]] 575 | name = "local-waker" 576 | version = "0.1.3" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" 579 | 580 | [[package]] 581 | name = "lock_api" 582 | version = "0.4.9" 583 | source = "registry+https://github.com/rust-lang/crates.io-index" 584 | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" 585 | dependencies = [ 586 | "autocfg", 587 | "scopeguard", 588 | ] 589 | 590 | [[package]] 591 | name = "log" 592 | version = "0.4.17" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 595 | dependencies = [ 596 | "cfg-if", 597 | ] 598 | 599 | [[package]] 600 | name = "memchr" 601 | version = "2.5.0" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 604 | 605 | [[package]] 606 | name = "mime" 607 | version = "0.3.16" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 610 | 611 | [[package]] 612 | name = "miniz_oxide" 613 | version = "0.6.2" 614 | source = "registry+https://github.com/rust-lang/crates.io-index" 615 | checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" 616 | dependencies = [ 617 | "adler", 618 | ] 619 | 620 | [[package]] 621 | name = "mio" 622 | version = "0.8.5" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" 625 | dependencies = [ 626 | "libc", 627 | "log", 628 | "wasi", 629 | "windows-sys", 630 | ] 631 | 632 | [[package]] 633 | name = "num_cpus" 634 | version = "1.14.0" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" 637 | dependencies = [ 638 | "hermit-abi", 639 | "libc", 640 | ] 641 | 642 | [[package]] 643 | name = "once_cell" 644 | version = "1.16.0" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" 647 | 648 | [[package]] 649 | name = "parking_lot" 650 | version = "0.12.1" 651 | source = "registry+https://github.com/rust-lang/crates.io-index" 652 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 653 | dependencies = [ 654 | "lock_api", 655 | "parking_lot_core", 656 | ] 657 | 658 | [[package]] 659 | name = "parking_lot_core" 660 | version = "0.9.5" 661 | source = "registry+https://github.com/rust-lang/crates.io-index" 662 | checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" 663 | dependencies = [ 664 | "cfg-if", 665 | "libc", 666 | "redox_syscall", 667 | "smallvec", 668 | "windows-sys", 669 | ] 670 | 671 | [[package]] 672 | name = "paste" 673 | version = "1.0.11" 674 | source = "registry+https://github.com/rust-lang/crates.io-index" 675 | checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" 676 | 677 | [[package]] 678 | name = "percent-encoding" 679 | version = "2.2.0" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 682 | 683 | [[package]] 684 | name = "pin-project-lite" 685 | version = "0.2.9" 686 | source = "registry+https://github.com/rust-lang/crates.io-index" 687 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 688 | 689 | [[package]] 690 | name = "pin-utils" 691 | version = "0.1.0" 692 | source = "registry+https://github.com/rust-lang/crates.io-index" 693 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 694 | 695 | [[package]] 696 | name = "pkg-config" 697 | version = "0.3.26" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" 700 | 701 | [[package]] 702 | name = "ppv-lite86" 703 | version = "0.2.17" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 706 | 707 | [[package]] 708 | name = "proc-macro2" 709 | version = "1.0.47" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" 712 | dependencies = [ 713 | "unicode-ident", 714 | ] 715 | 716 | [[package]] 717 | name = "quote" 718 | version = "1.0.21" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" 721 | dependencies = [ 722 | "proc-macro2", 723 | ] 724 | 725 | [[package]] 726 | name = "rand" 727 | version = "0.8.5" 728 | source = "registry+https://github.com/rust-lang/crates.io-index" 729 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 730 | dependencies = [ 731 | "libc", 732 | "rand_chacha", 733 | "rand_core", 734 | ] 735 | 736 | [[package]] 737 | name = "rand_chacha" 738 | version = "0.3.1" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 741 | dependencies = [ 742 | "ppv-lite86", 743 | "rand_core", 744 | ] 745 | 746 | [[package]] 747 | name = "rand_core" 748 | version = "0.6.4" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 751 | dependencies = [ 752 | "getrandom", 753 | ] 754 | 755 | [[package]] 756 | name = "redox_syscall" 757 | version = "0.2.16" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 760 | dependencies = [ 761 | "bitflags", 762 | ] 763 | 764 | [[package]] 765 | name = "regex" 766 | version = "1.7.0" 767 | source = "registry+https://github.com/rust-lang/crates.io-index" 768 | checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" 769 | dependencies = [ 770 | "aho-corasick", 771 | "memchr", 772 | "regex-syntax", 773 | ] 774 | 775 | [[package]] 776 | name = "regex-syntax" 777 | version = "0.6.28" 778 | source = "registry+https://github.com/rust-lang/crates.io-index" 779 | checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" 780 | 781 | [[package]] 782 | name = "rust-app" 783 | version = "0.1.0" 784 | dependencies = [ 785 | "actix-web", 786 | "serde", 787 | "serde_json", 788 | ] 789 | 790 | [[package]] 791 | name = "rustc_version" 792 | version = "0.4.0" 793 | source = "registry+https://github.com/rust-lang/crates.io-index" 794 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 795 | dependencies = [ 796 | "semver", 797 | ] 798 | 799 | [[package]] 800 | name = "ryu" 801 | version = "1.0.11" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" 804 | 805 | [[package]] 806 | name = "scopeguard" 807 | version = "1.1.0" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 810 | 811 | [[package]] 812 | name = "semver" 813 | version = "1.0.16" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" 816 | 817 | [[package]] 818 | name = "serde" 819 | version = "1.0.152" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" 822 | dependencies = [ 823 | "serde_derive", 824 | ] 825 | 826 | [[package]] 827 | name = "serde_derive" 828 | version = "1.0.152" 829 | source = "registry+https://github.com/rust-lang/crates.io-index" 830 | checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" 831 | dependencies = [ 832 | "proc-macro2", 833 | "quote", 834 | "syn", 835 | ] 836 | 837 | [[package]] 838 | name = "serde_json" 839 | version = "1.0.93" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" 842 | dependencies = [ 843 | "itoa", 844 | "ryu", 845 | "serde", 846 | ] 847 | 848 | [[package]] 849 | name = "serde_urlencoded" 850 | version = "0.7.1" 851 | source = "registry+https://github.com/rust-lang/crates.io-index" 852 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 853 | dependencies = [ 854 | "form_urlencoded", 855 | "itoa", 856 | "ryu", 857 | "serde", 858 | ] 859 | 860 | [[package]] 861 | name = "sha1" 862 | version = "0.10.5" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" 865 | dependencies = [ 866 | "cfg-if", 867 | "cpufeatures", 868 | "digest", 869 | ] 870 | 871 | [[package]] 872 | name = "signal-hook-registry" 873 | version = "1.4.0" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" 876 | dependencies = [ 877 | "libc", 878 | ] 879 | 880 | [[package]] 881 | name = "slab" 882 | version = "0.4.7" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" 885 | dependencies = [ 886 | "autocfg", 887 | ] 888 | 889 | [[package]] 890 | name = "smallvec" 891 | version = "1.10.0" 892 | source = "registry+https://github.com/rust-lang/crates.io-index" 893 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 894 | 895 | [[package]] 896 | name = "socket2" 897 | version = "0.4.7" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" 900 | dependencies = [ 901 | "libc", 902 | "winapi", 903 | ] 904 | 905 | [[package]] 906 | name = "syn" 907 | version = "1.0.105" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" 910 | dependencies = [ 911 | "proc-macro2", 912 | "quote", 913 | "unicode-ident", 914 | ] 915 | 916 | [[package]] 917 | name = "time" 918 | version = "0.3.17" 919 | source = "registry+https://github.com/rust-lang/crates.io-index" 920 | checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" 921 | dependencies = [ 922 | "itoa", 923 | "serde", 924 | "time-core", 925 | "time-macros", 926 | ] 927 | 928 | [[package]] 929 | name = "time-core" 930 | version = "0.1.0" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" 933 | 934 | [[package]] 935 | name = "time-macros" 936 | version = "0.2.6" 937 | source = "registry+https://github.com/rust-lang/crates.io-index" 938 | checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" 939 | dependencies = [ 940 | "time-core", 941 | ] 942 | 943 | [[package]] 944 | name = "tinyvec" 945 | version = "1.6.0" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 948 | dependencies = [ 949 | "tinyvec_macros", 950 | ] 951 | 952 | [[package]] 953 | name = "tinyvec_macros" 954 | version = "0.1.1" 955 | source = "registry+https://github.com/rust-lang/crates.io-index" 956 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 957 | 958 | [[package]] 959 | name = "tokio" 960 | version = "1.23.0" 961 | source = "registry+https://github.com/rust-lang/crates.io-index" 962 | checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46" 963 | dependencies = [ 964 | "autocfg", 965 | "bytes", 966 | "libc", 967 | "memchr", 968 | "mio", 969 | "parking_lot", 970 | "pin-project-lite", 971 | "signal-hook-registry", 972 | "socket2", 973 | "windows-sys", 974 | ] 975 | 976 | [[package]] 977 | name = "tokio-util" 978 | version = "0.7.4" 979 | source = "registry+https://github.com/rust-lang/crates.io-index" 980 | checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" 981 | dependencies = [ 982 | "bytes", 983 | "futures-core", 984 | "futures-sink", 985 | "pin-project-lite", 986 | "tokio", 987 | "tracing", 988 | ] 989 | 990 | [[package]] 991 | name = "tracing" 992 | version = "0.1.37" 993 | source = "registry+https://github.com/rust-lang/crates.io-index" 994 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 995 | dependencies = [ 996 | "cfg-if", 997 | "log", 998 | "pin-project-lite", 999 | "tracing-core", 1000 | ] 1001 | 1002 | [[package]] 1003 | name = "tracing-core" 1004 | version = "0.1.30" 1005 | source = "registry+https://github.com/rust-lang/crates.io-index" 1006 | checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" 1007 | dependencies = [ 1008 | "once_cell", 1009 | ] 1010 | 1011 | [[package]] 1012 | name = "typenum" 1013 | version = "1.16.0" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 1016 | 1017 | [[package]] 1018 | name = "unicode-bidi" 1019 | version = "0.3.10" 1020 | source = "registry+https://github.com/rust-lang/crates.io-index" 1021 | checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" 1022 | 1023 | [[package]] 1024 | name = "unicode-ident" 1025 | version = "1.0.5" 1026 | source = "registry+https://github.com/rust-lang/crates.io-index" 1027 | checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" 1028 | 1029 | [[package]] 1030 | name = "unicode-normalization" 1031 | version = "0.1.22" 1032 | source = "registry+https://github.com/rust-lang/crates.io-index" 1033 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 1034 | dependencies = [ 1035 | "tinyvec", 1036 | ] 1037 | 1038 | [[package]] 1039 | name = "url" 1040 | version = "2.3.1" 1041 | source = "registry+https://github.com/rust-lang/crates.io-index" 1042 | checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" 1043 | dependencies = [ 1044 | "form_urlencoded", 1045 | "idna", 1046 | "percent-encoding", 1047 | ] 1048 | 1049 | [[package]] 1050 | name = "version_check" 1051 | version = "0.9.4" 1052 | source = "registry+https://github.com/rust-lang/crates.io-index" 1053 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1054 | 1055 | [[package]] 1056 | name = "wasi" 1057 | version = "0.11.0+wasi-snapshot-preview1" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1060 | 1061 | [[package]] 1062 | name = "winapi" 1063 | version = "0.3.9" 1064 | source = "registry+https://github.com/rust-lang/crates.io-index" 1065 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1066 | dependencies = [ 1067 | "winapi-i686-pc-windows-gnu", 1068 | "winapi-x86_64-pc-windows-gnu", 1069 | ] 1070 | 1071 | [[package]] 1072 | name = "winapi-i686-pc-windows-gnu" 1073 | version = "0.4.0" 1074 | source = "registry+https://github.com/rust-lang/crates.io-index" 1075 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1076 | 1077 | [[package]] 1078 | name = "winapi-x86_64-pc-windows-gnu" 1079 | version = "0.4.0" 1080 | source = "registry+https://github.com/rust-lang/crates.io-index" 1081 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1082 | 1083 | [[package]] 1084 | name = "windows-sys" 1085 | version = "0.42.0" 1086 | source = "registry+https://github.com/rust-lang/crates.io-index" 1087 | checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" 1088 | dependencies = [ 1089 | "windows_aarch64_gnullvm", 1090 | "windows_aarch64_msvc", 1091 | "windows_i686_gnu", 1092 | "windows_i686_msvc", 1093 | "windows_x86_64_gnu", 1094 | "windows_x86_64_gnullvm", 1095 | "windows_x86_64_msvc", 1096 | ] 1097 | 1098 | [[package]] 1099 | name = "windows_aarch64_gnullvm" 1100 | version = "0.42.0" 1101 | source = "registry+https://github.com/rust-lang/crates.io-index" 1102 | checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" 1103 | 1104 | [[package]] 1105 | name = "windows_aarch64_msvc" 1106 | version = "0.42.0" 1107 | source = "registry+https://github.com/rust-lang/crates.io-index" 1108 | checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" 1109 | 1110 | [[package]] 1111 | name = "windows_i686_gnu" 1112 | version = "0.42.0" 1113 | source = "registry+https://github.com/rust-lang/crates.io-index" 1114 | checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" 1115 | 1116 | [[package]] 1117 | name = "windows_i686_msvc" 1118 | version = "0.42.0" 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" 1120 | checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" 1121 | 1122 | [[package]] 1123 | name = "windows_x86_64_gnu" 1124 | version = "0.42.0" 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" 1126 | checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" 1127 | 1128 | [[package]] 1129 | name = "windows_x86_64_gnullvm" 1130 | version = "0.42.0" 1131 | source = "registry+https://github.com/rust-lang/crates.io-index" 1132 | checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" 1133 | 1134 | [[package]] 1135 | name = "windows_x86_64_msvc" 1136 | version = "0.42.0" 1137 | source = "registry+https://github.com/rust-lang/crates.io-index" 1138 | checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" 1139 | 1140 | [[package]] 1141 | name = "zstd" 1142 | version = "0.12.3+zstd.1.5.2" 1143 | source = "registry+https://github.com/rust-lang/crates.io-index" 1144 | checksum = "76eea132fb024e0e13fd9c2f5d5d595d8a967aa72382ac2f9d39fcc95afd0806" 1145 | dependencies = [ 1146 | "zstd-safe", 1147 | ] 1148 | 1149 | [[package]] 1150 | name = "zstd-safe" 1151 | version = "6.0.4+zstd.1.5.4" 1152 | source = "registry+https://github.com/rust-lang/crates.io-index" 1153 | checksum = "7afb4b54b8910cf5447638cb54bf4e8a65cbedd783af98b98c62ffe91f185543" 1154 | dependencies = [ 1155 | "libc", 1156 | "zstd-sys", 1157 | ] 1158 | 1159 | [[package]] 1160 | name = "zstd-sys" 1161 | version = "2.0.7+zstd.1.5.4" 1162 | source = "registry+https://github.com/rust-lang/crates.io-index" 1163 | checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5" 1164 | dependencies = [ 1165 | "cc", 1166 | "libc", 1167 | "pkg-config", 1168 | ] 1169 | -------------------------------------------------------------------------------- /rust-app/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust-app" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | actix-web = "4" 10 | serde = {version = "1.0.152", features = ["derive"]} 11 | serde_json = "1.0.93" -------------------------------------------------------------------------------- /rust-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM amd64/rust:1.65.0-bullseye as build 2 | 3 | WORKDIR /app 4 | 5 | COPY . . 6 | 7 | RUN cargo build --release 8 | 9 | FROM debian:11.5-slim 10 | 11 | COPY --from=build /app/target/release/rust-app /rust-app 12 | 13 | CMD ["/rust-app"] 14 | -------------------------------------------------------------------------------- /rust-app/deploy/deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: rust-app 6 | namespace: staging 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: rust-app 12 | template: 13 | metadata: 14 | labels: 15 | app: rust-app 16 | spec: 17 | containers: 18 | - name: rust-app 19 | image: youraccount.dkr.ecr.us-east-1.amazonaws.com/rust-app:0.2 20 | ports: 21 | - name: http 22 | containerPort: 8000 23 | resources: 24 | requests: 25 | memory: 512Mi 26 | cpu: 500m 27 | limits: 28 | memory: 1024Mi 29 | cpu: 1000m 30 | affinity: 31 | podAntiAffinity: 32 | preferredDuringSchedulingIgnoredDuringExecution: 33 | - weight: 100 34 | podAffinityTerm: 35 | labelSelector: 36 | matchExpressions: 37 | - key: app 38 | operator: In 39 | values: 40 | - rust-app 41 | - go-app 42 | - cs-app 43 | topologyKey: topology.kubernetes.io/zone 44 | -------------------------------------------------------------------------------- /rust-app/deploy/ingress.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: networking.k8s.io/v1 3 | kind: Ingress 4 | metadata: 5 | name: rust-app 6 | namespace: staging 7 | spec: 8 | ingressClassName: external-ingress-nginx 9 | rules: 10 | - host: rust-app.thedeltafarmers.com 11 | http: 12 | paths: 13 | - path: / 14 | pathType: Prefix 15 | backend: 16 | service: 17 | name: rust-app 18 | port: 19 | number: 8000 20 | -------------------------------------------------------------------------------- /rust-app/deploy/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: staging 6 | labels: 7 | monitoring: prometheus 8 | -------------------------------------------------------------------------------- /rust-app/deploy/service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | namespace: staging 6 | name: rust-app 7 | labels: 8 | app: rust-app 9 | spec: 10 | type: ClusterIP 11 | ports: 12 | - name: http 13 | port: 8000 14 | protocol: TCP 15 | selector: 16 | app: rust-app 17 | -------------------------------------------------------------------------------- /rust-app/src/main.rs: -------------------------------------------------------------------------------- 1 | use actix_web::{web, App, HttpResponse, HttpServer}; 2 | use serde::{Serialize, Deserialize}; 3 | 4 | #[derive(Serialize, Deserialize)] 5 | struct Device { 6 | id: i32, 7 | mac: String, 8 | firmware: String, 9 | } 10 | 11 | fn fibonacci(n: u32) -> u32 { 12 | match n { 13 | 1 | 2 => 1, 14 | 3 => 2, 15 | _ => fibonacci(n - 1) + fibonacci(n - 2), 16 | } 17 | } 18 | 19 | async fn get_devices() -> HttpResponse { 20 | let mut devices = Vec::new(); 21 | 22 | devices.push(Device {id: 1, mac: String::from("5F-33-CC-1F-43-82"), firmware: String::from("2.1.6")}); 23 | devices.push(Device {id: 2, mac: String::from("EF-2B-C4-F5-D6-34"), firmware: String::from("2.1.6")}); 24 | 25 | HttpResponse::Ok().json(devices) 26 | } 27 | 28 | async fn create_device() -> HttpResponse { 29 | let number = 40; 30 | 31 | let fib = fibonacci(number); 32 | let location = format!("/devices/{}", fib); 33 | 34 | HttpResponse::Created().append_header(("location", location)).finish() 35 | } 36 | 37 | #[actix_web::main] 38 | async fn main() -> std::io::Result<()> { 39 | HttpServer::new(|| { 40 | App::new() 41 | .route("/devices", web::get().to(get_devices)) 42 | .route("/devices", web::post().to(create_device)) 43 | }) 44 | .bind("0.0.0.0:8000")? 45 | .run() 46 | .await 47 | } -------------------------------------------------------------------------------- /terraform/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/hashicorp/aws" { 5 | version = "4.46.0" 6 | constraints = "~> 4.46" 7 | hashes = [ 8 | "h1:WFBUQj7XI7gknCtGR+3yDhdlUiDYrONOA8HA7h2yWqY=", 9 | "h1:m7RCtncaQbSD9VhNTX2xbuZY3TlYnUrluvmYZeYHb1s=", 10 | "zh:1678e6a4bdb3d81a6713adc62ca0fdb8250c584e10c10d1daca72316e9db8df2", 11 | "zh:329903acf86ef6072502736dff4c43c2b50f762a958f76aa924e2d74c7fca1e3", 12 | "zh:33db8131fe0ec7e1d9f30bc9f65c2440e9c1f708d681b6062757a351f1df7ce6", 13 | "zh:3a3b010bc393784c16f4b6cdce7f76db93d5efa323fce4920bfea9e9ba6abe44", 14 | "zh:979e2713a5759a7483a065e149e3cb69db9225326fc0457fa3fc3a48aed0c63f", 15 | "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", 16 | "zh:9efcf0067e16ad53da7504178a05eb2118770b4ae00c193c10ecad4cbfce308e", 17 | "zh:a10655bf1b6376ab7f3e55efadf54dc70f7bd07ca11369557c312095076f9d62", 18 | "zh:b0394dd42cbd2a718a7dd7ae0283f04769aaf8b3d52664e141da59c0171a11ab", 19 | "zh:b958e614c2cf6d9c05a6ad5e94dc5c04b97ebfb84415da068be5a081b5ebbe24", 20 | "zh:ba5069e624210c63ad9e633a8eb0108b21f2322bc4967ba2b82d09168c466888", 21 | "zh:d7dfa597a17186e7f4d741dd7111849f1c0dd6f7ebc983043d8262d2fb37b408", 22 | "zh:e8a641ca2c99f96d64fa2725875e797273984981d3e54772a2823541c44e3cd3", 23 | "zh:f89898b7067c4246293a8007f59f5cfcac7b8dd251d39886c7a53ba596251466", 24 | "zh:fb1e1df1d5cc208e08a850f8e84423bce080f01f5e901791c79df369d3ed52f2", 25 | ] 26 | } 27 | 28 | provider "registry.terraform.io/hashicorp/helm" { 29 | version = "2.7.1" 30 | hashes = [ 31 | "h1:L5qLTfZH7PnZt9+YnS7iYmPBEDQOpEjZiF0v50BRNi8=", 32 | "h1:OGZRkgiLBWmoA8/a9xZnEs5gsC5JhW+75++MkCPQbqw=", 33 | "zh:13e2467092deeff01c4cfa2b54ba4510aa7a9b06c58f22c4215b0f4333858364", 34 | "zh:4549843db4fdf5d8150e8c0734e67b54b5c3bcfc914e3221e6952f428fb984d2", 35 | "zh:55b5f83ed52f93dd00a73c33c948326052efd700350c19e63bb1679b12bfcda6", 36 | "zh:749397e41393289eb0ef6efd0a75911d29b8aa7f48e5d6813b4b350dad91acbd", 37 | "zh:7a4a2c95b055f6c8e70d1fc7a4cc4fd6e4f04845be36e40d42d31dfc13db37b8", 38 | "zh:8143e5b8218857052505c805b570889b862c618ce6cbfbddb98938ff7a5901d3", 39 | "zh:856d94b3b34d6204d66c6de4feab4737c74dba037ad64e4c613e8eec61d17f1a", 40 | "zh:b9b037f1edda209022df1c7fc906786970524873e27b061f3355cb9bbed2cf08", 41 | "zh:c433b27f52a0600490af07f8b217ab0b1048ba347d68e6fe478aba18634e78d9", 42 | "zh:da133748368c6e27b433cd7faeb7b800536c8651e7af0415452901dfc7577dbf", 43 | "zh:eecc63c2dec8aafa2ffd7426800c3e1a5e31e848be01ea9511ad0184dce15945", 44 | "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", 45 | ] 46 | } 47 | 48 | provider "registry.terraform.io/hashicorp/tls" { 49 | version = "4.0.4" 50 | hashes = [ 51 | "h1:GZcFizg5ZT2VrpwvxGBHQ/hO9r6g0vYdQqx3bFD3anY=", 52 | "h1:Wd3RqmQW60k2QWPN4sK5CtjGuO1d+CRNXgC+D4rKtXc=", 53 | "zh:23671ed83e1fcf79745534841e10291bbf34046b27d6e68a5d0aab77206f4a55", 54 | "zh:45292421211ffd9e8e3eb3655677700e3c5047f71d8f7650d2ce30242335f848", 55 | "zh:59fedb519f4433c0fdb1d58b27c210b27415fddd0cd73c5312530b4309c088be", 56 | "zh:5a8eec2409a9ff7cd0758a9d818c74bcba92a240e6c5e54b99df68fff312bbd5", 57 | "zh:5e6a4b39f3171f53292ab88058a59e64825f2b842760a4869e64dc1dc093d1fe", 58 | "zh:810547d0bf9311d21c81cc306126d3547e7bd3f194fc295836acf164b9f8424e", 59 | "zh:824a5f3617624243bed0259d7dd37d76017097dc3193dac669be342b90b2ab48", 60 | "zh:9361ccc7048be5dcbc2fafe2d8216939765b3160bd52734f7a9fd917a39ecbd8", 61 | "zh:aa02ea625aaf672e649296bce7580f62d724268189fe9ad7c1b36bb0fa12fa60", 62 | "zh:c71b4cd40d6ec7815dfeefd57d88bc592c0c42f5e5858dcc88245d371b4b8b1e", 63 | "zh:dabcd52f36b43d250a3d71ad7abfa07b5622c69068d989e60b79b2bb4f220316", 64 | "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", 65 | ] 66 | } 67 | -------------------------------------------------------------------------------- /terraform/00-provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "us-east-1" 3 | } 4 | 5 | terraform { 6 | required_providers { 7 | aws = { 8 | source = "hashicorp/aws" 9 | version = "~> 4.46" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /terraform/01-vpc.tf: -------------------------------------------------------------------------------- 1 | resource "aws_vpc" "main" { 2 | cidr_block = "10.0.0.0/16" 3 | 4 | tags = { 5 | Name = "main" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /terraform/02-igw.tf: -------------------------------------------------------------------------------- 1 | resource "aws_internet_gateway" "igw" { 2 | vpc_id = aws_vpc.main.id 3 | 4 | tags = { 5 | Name = "igw" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /terraform/03-subnets.tf: -------------------------------------------------------------------------------- 1 | resource "aws_subnet" "private_us_east_1a" { 2 | vpc_id = aws_vpc.main.id 3 | cidr_block = "10.0.0.0/19" 4 | availability_zone = "us-east-1a" 5 | 6 | tags = { 7 | "Name" = "private-us-east-1a" 8 | "kubernetes.io/role/internal-elb" = "1" 9 | "kubernetes.io/cluster/demo" = "owned" 10 | } 11 | } 12 | 13 | resource "aws_subnet" "private_us_east_1b" { 14 | vpc_id = aws_vpc.main.id 15 | cidr_block = "10.0.32.0/19" 16 | availability_zone = "us-east-1b" 17 | 18 | tags = { 19 | "Name" = "private-us-east-1b" 20 | "kubernetes.io/role/internal-elb" = "1" 21 | "kubernetes.io/cluster/demo" = "owned" 22 | } 23 | } 24 | 25 | resource "aws_subnet" "public_us_east_1a" { 26 | vpc_id = aws_vpc.main.id 27 | cidr_block = "10.0.64.0/19" 28 | availability_zone = "us-east-1a" 29 | map_public_ip_on_launch = true 30 | 31 | tags = { 32 | "Name" = "public-us-east-1a" 33 | "kubernetes.io/role/elb" = "1" 34 | "kubernetes.io/cluster/demo" = "owned" 35 | } 36 | } 37 | 38 | resource "aws_subnet" "public_us_east_1b" { 39 | vpc_id = aws_vpc.main.id 40 | cidr_block = "10.0.96.0/19" 41 | availability_zone = "us-east-1b" 42 | map_public_ip_on_launch = true 43 | 44 | tags = { 45 | "Name" = "public-us-east-1b" 46 | "kubernetes.io/role/elb" = "1" 47 | "kubernetes.io/cluster/demo" = "owned" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /terraform/04-nat.tf: -------------------------------------------------------------------------------- 1 | resource "aws_eip" "nat" { 2 | vpc = true 3 | 4 | tags = { 5 | Name = "nat" 6 | } 7 | } 8 | 9 | resource "aws_nat_gateway" "nat" { 10 | allocation_id = aws_eip.nat.id 11 | subnet_id = aws_subnet.public_us_east_1a.id 12 | 13 | tags = { 14 | Name = "nat" 15 | } 16 | 17 | depends_on = [aws_internet_gateway.igw] 18 | } 19 | -------------------------------------------------------------------------------- /terraform/05-routes.tf: -------------------------------------------------------------------------------- 1 | resource "aws_route_table" "private" { 2 | vpc_id = aws_vpc.main.id 3 | 4 | route { 5 | cidr_block = "0.0.0.0/0" 6 | nat_gateway_id = aws_nat_gateway.nat.id 7 | } 8 | 9 | tags = { 10 | Name = "private" 11 | } 12 | } 13 | 14 | resource "aws_route_table" "public" { 15 | vpc_id = aws_vpc.main.id 16 | 17 | route { 18 | cidr_block = "0.0.0.0/0" 19 | gateway_id = aws_internet_gateway.igw.id 20 | } 21 | 22 | tags = { 23 | Name = "public" 24 | } 25 | } 26 | 27 | resource "aws_route_table_association" "private_us_east_1a" { 28 | subnet_id = aws_subnet.private_us_east_1a.id 29 | route_table_id = aws_route_table.private.id 30 | } 31 | 32 | resource "aws_route_table_association" "private_us_east_1b" { 33 | subnet_id = aws_subnet.private_us_east_1b.id 34 | route_table_id = aws_route_table.private.id 35 | } 36 | 37 | resource "aws_route_table_association" "public_us_east_1a" { 38 | subnet_id = aws_subnet.public_us_east_1a.id 39 | route_table_id = aws_route_table.public.id 40 | } 41 | 42 | resource "aws_route_table_association" "public_us_east_1b" { 43 | subnet_id = aws_subnet.public_us_east_1b.id 44 | route_table_id = aws_route_table.public.id 45 | } 46 | -------------------------------------------------------------------------------- /terraform/06-eks.tf: -------------------------------------------------------------------------------- 1 | resource "aws_iam_role" "demo" { 2 | name = "eks-cluster-demo" 3 | 4 | assume_role_policy = <