diff --git a/.editorconfig b/.editorconfig index 087a0613..cb305623 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,10 +10,7 @@ trim_trailing_whitespace = true insert_final_newline = true end_of_line = lf -[*.yml] -indent_size = 2 - -[*.yaml] +[*.{yml,yaml,json,tf,md}] indent_size = 2 [*.{cs,vb}] diff --git a/CHANGELOG.md b/CHANGELOG.md index d983bb9e..b1d514ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,3 +31,4 @@ and this project adheres to [Semantic Versioning v2.0.0](https://semver.org/spec - Fix encoding - Merge plan and plan-destroy terraform pipelines - Configure HPA for services +- Fix the error Unable to unprotect the message.State. diff --git a/build/configure-aks-cluster.yml b/build/configure-aks-cluster.yml index 377e8e20..f9a6a2f1 100644 --- a/build/configure-aks-cluster.yml +++ b/build/configure-aks-cluster.yml @@ -39,5 +39,6 @@ stages: rabbitMqPassword: $(library-rabbitmq-password) cloudflareApiKey: $(cloudflare-api-key) cloudflareZone: $(cloudflare-zone-name) + redisPassword: $(library-redis-password) transformTargetFiles: | secrets/connection-secrets.yaml diff --git a/build/templates/configure-cluster-stages.yml b/build/templates/configure-cluster-stages.yml index 4fd8a8c6..91cc93fd 100644 --- a/build/templates/configure-cluster-stages.yml +++ b/build/templates/configure-cluster-stages.yml @@ -43,6 +43,10 @@ parameters: displayName: 'Zone name of DNS in cloudflare (e.g razumovsky.me)' type: string + - name: redisPassword + displayName: 'Password for Redis HELM release.' + type: string + stages: - stage: 'Configure_AKS_${{ parameters.environment }}' displayName: 'Configure_AKS_${{ parameters.environment }}' @@ -130,6 +134,20 @@ stages: pwsh: true workingDirectory: ${{ parameters.workingDirectory }} + - task: PowerShell@2 + displayName: 'Deploy Redis' + inputs: + targetType: 'inline' + script: | + helm repo add bitnami https://charts.bitnami.com/bitnami + helm repo update + helm upgrade --install event-redis bitnami/redis ` + --namespace ${{ parameters.namespace }} ` + --set auth.enabled=true ` + --set auth.password="${{ parameters.redisPassword }}" + pwsh: true + workingDirectory: ${{ parameters.workingDirectory }} + - task: PowerShell@2 displayName: 'Wait for deployments' inputs: diff --git a/kubernetes/auth-deployment-cluster-ip/auth-deployment.yaml b/kubernetes/auth-deployment-cluster-ip/auth-deployment.yaml index f5e595a8..ad3a524d 100644 --- a/kubernetes/auth-deployment-cluster-ip/auth-deployment.yaml +++ b/kubernetes/auth-deployment-cluster-ip/auth-deployment.yaml @@ -8,7 +8,7 @@ spec: selector: matchLabels: app: event-triangle-auth-api - replicas: 1 + replicas: 3 strategy: type: RollingUpdate rollingUpdate: @@ -46,5 +46,17 @@ spec: name: connection-creds key: AuthDatabaseConnectionString + - name: RedisUrl + valueFrom: + secretKeyRef: + name: connection-creds + key: RedisUrl + + - name: RedisPassword + valueFrom: + secretKeyRef: + name: connection-creds + key: RedisPassword + - name: ASPNETCORE_ENVIRONMENT value: "Docker" diff --git a/kubernetes/auth-deployment-cluster-ip/hpa.yaml b/kubernetes/auth-deployment-cluster-ip/hpa.yaml index 7a1728a0..00df96ab 100644 --- a/kubernetes/auth-deployment-cluster-ip/hpa.yaml +++ b/kubernetes/auth-deployment-cluster-ip/hpa.yaml @@ -1,4 +1,4 @@ -apiVersion: autoscaling/v2 +apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: event-triangle-auth-hpa diff --git a/kubernetes/consumer-deployment-cluster-ip/hpa.yaml b/kubernetes/consumer-deployment-cluster-ip/hpa.yaml index 7116d190..da6b1aaf 100644 --- a/kubernetes/consumer-deployment-cluster-ip/hpa.yaml +++ b/kubernetes/consumer-deployment-cluster-ip/hpa.yaml @@ -1,4 +1,4 @@ -apiVersion: autoscaling/v2 +apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: event-triangle-consumer-hpa diff --git a/kubernetes/helm-install-grafana-prometheus/Example.ps1 b/kubernetes/helm-install-grafana-prometheus/Example.ps1 index 64696310..0bf0ea70 100644 --- a/kubernetes/helm-install-grafana-prometheus/Example.ps1 +++ b/kubernetes/helm-install-grafana-prometheus/Example.ps1 @@ -1,4 +1,4 @@ -helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update kubectl create namespace monitoring helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring --set grafana.service.type=ClusterIP --set prometheus.service.type=ClusterIP diff --git a/kubernetes/helm-install-redis/Commands.ps1 b/kubernetes/helm-install-redis/Commands.ps1 new file mode 100644 index 00000000..c7f1f4d9 --- /dev/null +++ b/kubernetes/helm-install-redis/Commands.ps1 @@ -0,0 +1,20 @@ +helm repo add bitnami https://charts.bitnami.com/bitnami +helm repo update + +# Simple install command +helm upgrade --install event-redis bitnami/redis --namespace event-triangle + +# Set password as a parameter +helm upgrade --install event-redis bitnami/redis ` + --namespace event-triangle ` + --set auth.enabled=true ` + --set auth.password="MySecureRedisPassword" + +# Get the base64 encoded password from the Kubernetes secret +$encodedPassword = kubectl get secret --namespace event-triangle event-redis -o jsonpath="{.data.redis-password}" + +# Decode the base64 string +$decodedPassword = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($encodedPassword)) + +# Set the decoded password into the variable +$REDIS_PASSWORD = $decodedPassword diff --git a/kubernetes/secrets/connection-secrets.yaml b/kubernetes/secrets/connection-secrets.yaml index a89afc1e..23c8edee 100644 --- a/kubernetes/secrets/connection-secrets.yaml +++ b/kubernetes/secrets/connection-secrets.yaml @@ -14,4 +14,6 @@ stringData: # takes plain text secrets POSTGRES_PASSWORD: "{{POSTGRES_PASSWORD}}" POSTGRES_DB: "{{POSTGRES_DB}}" RabbitMqUsername: "{{library-rabbitmq-user}}" - RabbitMqPassword: "{{library-rabbitmq-password}}" \ No newline at end of file + RabbitMqPassword: "{{library-rabbitmq-password}}" + RedisUrl: "{{library-redis-url}}" + RedisPassword: "{{library-redis-password}}" diff --git a/kubernetes/sender-deployment-cluster-ip/hpa.yaml b/kubernetes/sender-deployment-cluster-ip/hpa.yaml index 165d8d71..20d0194f 100644 --- a/kubernetes/sender-deployment-cluster-ip/hpa.yaml +++ b/kubernetes/sender-deployment-cluster-ip/hpa.yaml @@ -1,4 +1,4 @@ -apiVersion: autoscaling/v2 +apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: event-triangle-sender-hpa diff --git a/src/authorization/EventTriangleAPI.Authorization.Domain/Constants/AppSettingsConstants.cs b/src/authorization/EventTriangleAPI.Authorization.Domain/Constants/AppSettingsConstants.cs index ee2788f7..65e1caf5 100644 --- a/src/authorization/EventTriangleAPI.Authorization.Domain/Constants/AppSettingsConstants.cs +++ b/src/authorization/EventTriangleAPI.Authorization.Domain/Constants/AppSettingsConstants.cs @@ -7,7 +7,7 @@ public static class AppSettingsConstants public const string AzureAdSelection = "AzureAd"; public const string ReverseProxySelection = "ReverseProxy"; - + public const string AdSecretKey = "EVENT_TRIANGLE_AD_CLIENT_SECRET"; public const string DevFrontendUrl = "DevFrontendUrl"; @@ -15,4 +15,8 @@ public static class AppSettingsConstants public const string AllowedOrigins = "AllowedOrigins"; public const string GrpcChannelAddresses = "GrpcChannelAddresses"; -} \ No newline at end of file + + public const string RedisUrl = "RedisUrl"; + + public const string RedisPassword = "RedisPassword"; +} diff --git a/src/authorization/EventTriangleAPI.Authorization.Presentation/EventTriangleAPI.Authorization.Presentation.csproj b/src/authorization/EventTriangleAPI.Authorization.Presentation/EventTriangleAPI.Authorization.Presentation.csproj index 22c5841d..6315872c 100644 --- a/src/authorization/EventTriangleAPI.Authorization.Presentation/EventTriangleAPI.Authorization.Presentation.csproj +++ b/src/authorization/EventTriangleAPI.Authorization.Presentation/EventTriangleAPI.Authorization.Presentation.csproj @@ -7,7 +7,10 @@ + + + diff --git a/src/authorization/EventTriangleAPI.Authorization.Presentation/Program.cs b/src/authorization/EventTriangleAPI.Authorization.Presentation/Program.cs index 4a7bc2fb..d0690a61 100644 --- a/src/authorization/EventTriangleAPI.Authorization.Presentation/Program.cs +++ b/src/authorization/EventTriangleAPI.Authorization.Presentation/Program.cs @@ -3,8 +3,10 @@ using EventTriangleAPI.Authorization.Persistence; using EventTriangleAPI.Authorization.Presentation.DependencyInjection; using EventTriangleAPI.Shared.DTO.Models; +using Microsoft.AspNetCore.DataProtection; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Caching.Memory; +using StackExchange.Redis; var builder = WebApplication.CreateBuilder(args); @@ -55,6 +57,34 @@ builder.Logging.AddFilter("Grpc", LogLevel.Debug); +// redis configs start + +var redisUrl = builder.Configuration[AppSettingsConstants.RedisUrl]; + +if (string.IsNullOrEmpty(redisUrl)) +{ + throw new ArgumentNullException(nameof(redisUrl)); +} + +var redisPassword = builder.Configuration[AppSettingsConstants.RedisPassword]; + +if (string.IsNullOrEmpty(redisPassword)) +{ + throw new ArgumentNullException(nameof(redisPassword)); +} + +var redis = ConnectionMultiplexer.Connect(new ConfigurationOptions +{ + EndPoints = { redisUrl }, + Password = redisPassword, + AbortOnConnectFail = false +}); + +builder.Services.AddDataProtection() + .PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys"); + +// redis configs end + var app = builder.Build(); app.UseSwagger(); @@ -91,4 +121,4 @@ app.Map(SpaRouting.Tickets, config => config.UseSpa(spa => spa.Options.SourcePath = "/wwwroot")); app.Map(SpaRouting.Users, config => config.UseSpa(spa => spa.Options.SourcePath = "/wwwroot")); -app.Run(); \ No newline at end of file +app.Run(); diff --git a/src/authorization/EventTriangleAPI.Authorization.Presentation/appsettings.Docker.json b/src/authorization/EventTriangleAPI.Authorization.Presentation/appsettings.Docker.json index df2848a6..e1193faa 100644 --- a/src/authorization/EventTriangleAPI.Authorization.Presentation/appsettings.Docker.json +++ b/src/authorization/EventTriangleAPI.Authorization.Presentation/appsettings.Docker.json @@ -7,9 +7,14 @@ } }, "AllowedHosts": "*", - "AllowedOrigins": ["http://localhost:4200", "http://localhost:7000"], + "AllowedOrigins": [ + "http://localhost:4200", + "http://localhost:7000" + ], "DatabaseConnectionString": "Server=db;User Id=postgres;Password=postgres;Database=AuthorizationDb;", "DevFrontendUrl": "http://localhost:4200", + "RedisUrl": "event-redis-master.event-triangle.svc.cluster.local", + "RedisPassword": "", "AzureAd": { "Authority": "https://login.microsoftonline.com/b40a105f-0643-4922-8e60-10fc1abf9c4b/v2.0/", "Instance": "https://login.microsoftonline.com", @@ -24,7 +29,7 @@ "GrpcChannelAddresses": "http://event-triangle-sender-service:81", "ReverseProxy": { "Routes": { - "route1" : { + "route1": { "ClusterId": "cluster1", "Match": { "Path": "/sender/{**catch-all}" @@ -35,7 +40,7 @@ } ] }, - "route2" : { + "route2": { "ClusterId": "cluster2", "Match": { "Path": "/consumer/{**catch-all}" diff --git a/src/authorization/EventTriangleAPI.Authorization.Presentation/appsettings.json b/src/authorization/EventTriangleAPI.Authorization.Presentation/appsettings.json index aadd9a9d..3ad853fd 100644 --- a/src/authorization/EventTriangleAPI.Authorization.Presentation/appsettings.json +++ b/src/authorization/EventTriangleAPI.Authorization.Presentation/appsettings.json @@ -7,9 +7,14 @@ } }, "AllowedHosts": "*", - "AllowedOrigins": ["http://localhost:4200", "https://localhost:7000"], + "AllowedOrigins": [ + "http://localhost:4200", + "https://localhost:7000" + ], "DatabaseConnectionString": "Server=localhost;User Id=postgres;Password=postgres;Database=AuthorizationDb;", "DevFrontendUrl": "http://localhost:4200", + "RedisUrl": "event-redis-master.event-triangle.svc.cluster.local", + "RedisPassword": "", "AzureAd": { "Authority": "https://login.microsoftonline.com/b40a105f-0643-4922-8e60-10fc1abf9c4b/v2.0/", "Instance": "https://login.microsoftonline.com", @@ -24,7 +29,7 @@ "GrpcChannelAddresses": "https://localhost:7002", "ReverseProxy": { "Routes": { - "route1" : { + "route1": { "ClusterId": "cluster1", "Match": { "Path": "/sender/{**catch-all}" @@ -35,7 +40,7 @@ } ] }, - "route2" : { + "route2": { "ClusterId": "cluster2", "Match": { "Path": "/consumer/{**catch-all}" @@ -64,4 +69,4 @@ } } } -} \ No newline at end of file +} diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl index 03ed0f10..9b6fb28a 100644 --- a/terraform/.terraform.lock.hcl +++ b/terraform/.terraform.lock.hcl @@ -2,22 +2,22 @@ # Manual edits may be lost in future updates. provider "registry.terraform.io/azure/azapi" { - version = "2.2.0" + version = "2.3.0" constraints = ">= 1.9.0" hashes = [ - "h1:0g8xm3nzzdnu1gc6d8/U/eP20YtaWHAhDqZA/TA3iOQ=", - "zh:062be5d8272cac297a88c2057449f449ea6906c4121ba3dfdeb5cecb3ff91178", - "zh:1fd9abec3ffcbf8d0244408334e9bfc8f49ada50978cd73ee0ed5f8560987267", - "zh:48e84b0302af99d7e7f4248a724088fb1c34aeee78c9ca63ec5a9464ec5054a0", - "zh:4e7302883fd9dd83bfbbcd72ebd55f83d8b16ccc6d12d1573d578058e604d5cf", - "zh:5b6e181e32cbf62f5d2ce34f9d6d9ffe17192e24943450bbe335e1baf0494e66", - "zh:62d525d426c6d5f10109ab04a9abc231b204ea413238f5690f69b420a8b8583a", - "zh:90aab23497ec9c7af44ad9ea1a1d6063dc3331334915e1c549527a73c2c6948d", - "zh:91ecf30a01df5e832191e0c55c87f8403a1f584796fd70f9c9c913d35c2e2a37", - "zh:bc3a5db5e4b9695a69dff47cf1e7184eaf5564d3dc50f231cbcbf535dd140d19", - "zh:cb566bec2676511bf4722e24d0dfc9bf58aff78af38b8e0864970f20d263118f", - "zh:d4fa0c1462b389cee313e1c152e00f5dfc175a1be3615d3b23b526a8581e39a5", - "zh:f8136b0f41045a1e5a6dedc6b6fb055faee3d825f84a3192312e3ac5d057ff72", + "h1:WxzoM2CU6MKt9q9Wk2ppsCmpuYXZ45h5ejl43cNdPWQ=", + "zh:038dfc9190827e4fe5635d7f81a44bb568e19c37847896ad2af8cc580ac28f77", + "zh:14b438540f81fc40957885009df0fed93bb9c771a9a8d37dd1d29bd8c5d85545", + "zh:1bb16bd852f28a1f369e199104330efefdfaccacf55bcae829235f553343f58b", + "zh:22a1138f522b1fd9b924e7bfbee66063f8d616a0ce6a0a0bdcc77b445350e1b6", + "zh:488746623bc1be052663a407589e3101c6c2d2d7e9ad56b5d69d4773f77a6f0e", + "zh:49a207406ee3b211fa89bacec844db58157fdb764bedf216706af05bb9068bd0", + "zh:55115837d92f0d4dce803c6180fab10f93314134e5e0a8aadcc977348fbc4b9c", + "zh:9ac58303d128c6c2a7a68984273ec76ceee9d14fca030cd22ae176e7b936495a", + "zh:aadb9712d3358790d96dead8ea73eb09a7e971be8b81765fbbb3af4219f77d63", + "zh:e39fe6b9f06819ec9a18d69ddb3c681cdbaadf184d2c8d6739f56f1e47d5947b", + "zh:e68f46ac504f1641bc419f4cfee5003fc596932598e09fa56a09a3d52f3851e4", + "zh:f50b37fb8f0b57cc97f99ff48018e2f97a7aa9d72f06cba3e3b2919d61d5f483", ] } @@ -42,22 +42,22 @@ provider "registry.terraform.io/hashicorp/azuread" { } provider "registry.terraform.io/hashicorp/azurerm" { - version = "4.21.1" + version = "4.22.0" constraints = ">= 3.71.0" hashes = [ - "h1:K4QidQiHvsJfLhTb7gwQuvGZuGZnXSD3ccQXWIV6cvE=", - "zh:0ba8a63b1b2572a8b04c122fd76fdca9a529b4ca3364cc1c8883341300285bf8", - "zh:1ba2e24a88aa54a87bde2c0519e3bf39a245c6ec1759fd671e96342b0bedc6c7", - "zh:22664d3bcad2c9ebecfb1165b076d2733c8a369a0f6d2b7f8f8ad2ee7eb64f03", - "zh:32128a565a615386e9020694d8ae9741ae6159ae46eaf0bfbd91b4fa45791af0", - "zh:33e7afa34ff2b0936abcad831e0971de58f9ac0debc024033dedcd9d01b5a1db", - "zh:540b27a9860d8a027dd1bc88bbf7a7b296e9476ff9f837fc0e48ff7e8a05d110", - "zh:6f8462409ab025182844b88b0c3c3b5368e06677a7e44f4edbcc473cd3cd873e", - "zh:7ab962e4d8401f0016199e97f7ca48cb9e9ee9e74a548579175ac1e6cd5c6189", - "zh:7b8f98dc6e26c9e5395ac1246c3876c1327d8e47b9894b3c8650a0f7b67bbc06", - "zh:8c40a9ec1b1f43cd60e6758316b7d2cb08bd2fa87260a37031de1156aa9c2a83", - "zh:c4908c33c404050528e0c0bd4d0567d139ddeb0f6f37f61a3c9c8c4e1af2fe2a", + "h1:8xp/VLfi/NyhkrUvOj91v3vRE1CBpM0QoTrapWreXSs=", + "zh:00c97ee99dd556d1187a7918790d30fb2dd023596781a71c748800a5c3ba47aa", + "zh:23713d8814661ed211dc43c9a5f130fc7bee5fa9956249ff2649a4ade0cb6a6b", + "zh:3b72a837582cf481f33880942f2abb43a7c0ec504005902b019afe4ea1f58fc4", + "zh:5b462c028ce8e494f8e2b70880b3b8c48228871d0b3dd1df19dbc449f015a302", + "zh:631c148e9aa3b084650444b39efaa1d75f51069a349ba4e5111451ac9a3b431b", + "zh:76243dec930b34ed79c53982f2d728f84cece8ea50d2a1a2867ed41caeaec622", + "zh:ac5be3494d1e9cc7e6a99c83b42054b87b6776726660afd420c62f8ea9899ff8", + "zh:bf2b054ad3ed0a0b416edff34faf4cf0b903699985046521c8c06264a01c2c0b", + "zh:ce9833fb5b7de2ef5076b3c5a877f73d0f7cf2cb4ca6f45b8b28cfd975c47a31", + "zh:e2703a53f8b059c7330467ce2268065c10c8ae5dd370bdb62a8be5ecabd801cf", "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:fcfc741bbba7e6eaa825959376f7ab484b8fa0d837450338e871c58b2141794a", ] } diff --git a/terraform/.tflint.hcl b/terraform/.tflint.hcl index 55f77586..4d40abe4 100644 --- a/terraform/.tflint.hcl +++ b/terraform/.tflint.hcl @@ -1,4 +1,4 @@ -plugin "terraform" { +plugin "terraform" { enabled = true preset = "recommended" }