diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d577aaf..8ebdb3ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,3 +41,8 @@ and this project adheres to [Semantic Versioning v2.0.0](https://semver.org/spec - Add SonarCloud scan to Azure DevOps PR validation - Add separate build pipelines in Azure DevOps - Split pipelines by folders: pr validation, build, infrastructure +- Update Cloudflare step: add only DNS record for ingress +- Add deployed project URLs to README +- Platform: Change PostgeSQL to be cluster IP +- Disable terraform log info +- Add AKS node pool name diff --git a/README.md b/README.md index 228d70d9..bca7f8d4 100644 --- a/README.md +++ b/README.md @@ -57,36 +57,6 @@ EventTriangleAPI offers realtime communication using SignalR. ![./img/infrastructure_diagram.png](./img/infrastructure_diagram.png) -## Screenshots - -### Transactions - -![./img/transactions.png](./img/transactions.png) - -### Credit Cards - -![./img/cards.png](./img/cards.png) - -### Deposit - -![./img/deposit.png](./img/deposit.png) - -### Contacts - -![./img/contacts.png](./img/contacts.png) - -### Support - -![./img/support.png](./img/support.png) - -### Tickets - -![./img/tickets.png](./img/tickets.png) - -### Users - -![./img/users.png](./img/users.png) - ## Technology stack - **SDK:** `.NET 8` @@ -109,6 +79,13 @@ EventTriangleAPI offers realtime communication using SignalR. ## Useful links +### Deployments + +- https://auth-eventtriangle.razumovsky.me/app/transactions +- https://auth-eventtriangle.razumovsky.me/swagger/index.html + +### Management + - Docker: https://hub.docker.com/u/kaminome - Azure DevOps: https://dev.azure.com/EventTriangle/EventTriangleAPI - Renovate: https://developer.mend.io/github/EventTriangle/EventTriangleAPI @@ -133,3 +110,33 @@ From `src` folder run: - `docker build --build-arg FRONT_API_URL="http://localhost:7000/" -t eventtriangle/auth:1.0 -f ./authorization/Dockerfile .` - `docker build -t eventtriangle/consumer:1.0 -f ./consumer/Dockerfile . ` - `docker build -t eventtriangle/sender:1.0 -f ./sender/Dockerfile .` + +## Screenshots + +### Transactions + +![./img/transactions.png](./img/transactions.png) + +### Credit Cards + +![./img/cards.png](./img/cards.png) + +### Deposit + +![./img/deposit.png](./img/deposit.png) + +### Contacts + +![./img/contacts.png](./img/contacts.png) + +### Support + +![./img/support.png](./img/support.png) + +### Tickets + +![./img/tickets.png](./img/tickets.png) + +### Users + +![./img/users.png](./img/users.png) diff --git a/azure-pipelines/infrastructure/configure-aks-cluster.yml b/azure-pipelines/infrastructure/configure-aks-cluster.yml index f9a6a2f1..c2a144fc 100644 --- a/azure-pipelines/infrastructure/configure-aks-cluster.yml +++ b/azure-pipelines/infrastructure/configure-aks-cluster.yml @@ -26,11 +26,11 @@ variables: value: 'false' stages: - - template: templates/configure-cluster-stages.yml + - template: ../templates/configure-cluster-stages.yml parameters: vmImage: windows-latest environment: aks - workingDirectory: $(System.DefaultWorkingDirectory)/kubernetes + workingDirectory: $(System.DefaultWorkingDirectory)/platform serviceConnection: Azure_Connection azureResourceGroup: $(library-aks-resource-group) kubernetesCluster: $(library-aks-cluster-name) diff --git a/azure-pipelines/infrastructure/terraform-create.yml b/azure-pipelines/infrastructure/terraform-create.yml index 4dc4f165..3cfc2057 100644 --- a/azure-pipelines/infrastructure/terraform-create.yml +++ b/azure-pipelines/infrastructure/terraform-create.yml @@ -23,12 +23,12 @@ variables: - name: System.Debug value: 'false' - name: planStageName - value: "Terraform_Plan_AKS_Cluster" + value: "Terraform_Plan" - name: applyStageName - value: "Terraform_Apply_AKS_Cluster" + value: "Terraform_Apply" stages: - - template: templates/terraform-plan-stages.yml + - template: ../templates/terraform-plan-stages.yml parameters: stageName: ${{ variables.planStageName }} VmImage: windows-latest @@ -45,7 +45,7 @@ stages: tenantId: $(library-tenant-id) destroy: false - - template: templates/terraform-apply-stages.yml + - template: ../templates/terraform-apply-stages.yml parameters: stageName: ${{ variables.applyStageName }} VmImage: windows-latest diff --git a/azure-pipelines/infrastructure/terraform-destroy.yml b/azure-pipelines/infrastructure/terraform-destroy.yml index 5b9ccd5f..f726b6d7 100644 --- a/azure-pipelines/infrastructure/terraform-destroy.yml +++ b/azure-pipelines/infrastructure/terraform-destroy.yml @@ -18,12 +18,12 @@ variables: - name: System.Debug value: 'false' - name: planStageName - value: "Terraform_Plan_Destroy_AKS_Cluster" + value: "Terraform_Plan_Destroy" - name: applyStageName - value: "Terraform_Apply_Destroy_AKS_Cluster" + value: "Terraform_Destroy" stages: - - template: templates/terraform-plan-stages.yml + - template: ../templates/terraform-plan-stages.yml parameters: stageName: ${{ variables.planStageName }} VmImage: windows-latest @@ -40,7 +40,7 @@ stages: tenantId: $(library-tenant-id) destroy: true - - template: templates/terraform-apply-stages.yml + - template: ../templates/terraform-apply-stages.yml parameters: stageName: ${{ variables.applyStageName }} VmImage: windows-latest diff --git a/azure-pipelines/pr-validation/pr-validation-auth.yml b/azure-pipelines/pr-validation/pr-validation-auth.yml index 2af10d43..09846853 100644 --- a/azure-pipelines/pr-validation/pr-validation-auth.yml +++ b/azure-pipelines/pr-validation/pr-validation-auth.yml @@ -7,13 +7,14 @@ pr: - main paths: include: - - build + - azure-pipelines + - platform + - helm + - cloudflare - src/authorization/EventTriangleAPI.Authorization.BusinessLogic - src/authorization/EventTriangleAPI.Authorization.Presentation - src/shared/EventTriangleAPI.Shared.Application - src/shared/EventTriangleAPI.Shared.DTO - exclude: - - '**/*.md' variables: - name: appName @@ -46,5 +47,5 @@ stages: shouldPushToAcr: true acrRegistryUrl: 'acrsharedd01.azurecr.io' acrServiceConnection: 'Azure_ACR_Connection' - sonarCloudEnabled: true + sonarCloudEnabled: false workingDirectoryForDocker: '$(System.DefaultWorkingDirectory)/src' diff --git a/azure-pipelines/pr-validation/pr-validation-consumer.yml b/azure-pipelines/pr-validation/pr-validation-consumer.yml index 0a3594f6..d83a43d7 100644 --- a/azure-pipelines/pr-validation/pr-validation-consumer.yml +++ b/azure-pipelines/pr-validation/pr-validation-consumer.yml @@ -7,7 +7,10 @@ pr: - main paths: include: - - build + - azure-pipelines + - platform + - helm + - cloudflare - src/consumer/EventTriangleAPI.Consumer.Application - src/consumer/EventTriangleAPI.Consumer.BusinessLogic - src/consumer/EventTriangleAPI.Consumer.Domain @@ -16,8 +19,6 @@ pr: - src/consumer/EventTriangleAPI.Consumer.UnitTests - src/shared/EventTriangleAPI.Shared.Application - src/shared/EventTriangleAPI.Shared.DTO - exclude: - - '**/*.md' variables: - name: appName diff --git a/azure-pipelines/pr-validation/pr-validation-sender.yml b/azure-pipelines/pr-validation/pr-validation-sender.yml index 7a20dd79..769be103 100644 --- a/azure-pipelines/pr-validation/pr-validation-sender.yml +++ b/azure-pipelines/pr-validation/pr-validation-sender.yml @@ -7,7 +7,10 @@ pr: - main paths: include: - - build + - azure-pipelines + - platform + - helm + - cloudflare - src/sender/EventTriangleAPI.Sender.Application - src/sender/EventTriangleAPI.Sender.BusinessLogic - src/sender/EventTriangleAPI.Sender.Domain @@ -16,8 +19,6 @@ pr: - src/sender/EventTriangleAPI.Sender.UnitTests - src/shared/EventTriangleAPI.Shared.Application - src/shared/EventTriangleAPI.Shared.DTO - exclude: - - '**/*.md' variables: - name: appName diff --git a/azure-pipelines/templates/configure-cluster-stages.yml b/azure-pipelines/templates/configure-cluster-stages.yml index 91cc93fd..2cbd9c4b 100644 --- a/azure-pipelines/templates/configure-cluster-stages.yml +++ b/azure-pipelines/templates/configure-cluster-stages.yml @@ -100,7 +100,7 @@ stages: displayName: 'Deploy Postgres' inputs: targetType: 'inline' - script: 'kubectl apply -f ./pgsql-deployment-load-balancer --namespace ${{ parameters.namespace }}' + script: 'kubectl apply -f ./pgsql-deployment --namespace ${{ parameters.namespace }}' pwsh: true workingDirectory: ${{ parameters.workingDirectory }} @@ -113,17 +113,13 @@ stages: pwsh: true workingDirectory: ${{ parameters.workingDirectory }} - - task: PowerShell@2 - displayName: 'Deploy RabbitMQ' - inputs: - targetType: 'filePath' - filePath: ${{ parameters.workingDirectory }}/helm-install-rabbit-mq/deploy-rabbitmq-helm.ps1 - arguments: '-HelmReleaseName event-rabbitmq - -Namespace ${{ parameters.namespace }} - -RabbitMqUsername ${{ parameters.rabbitMqUser }} - -RabbitMqPassword ${{ parameters.rabbitMqPassword }}' - pwsh: true - workingDirectory: ${{ parameters.workingDirectory }} + - pwsh: | + kubectl apply -f "https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml" + Write-Host "Waiting 60 sec for Operator to provision..." + Start-Sleep 60 + kubectl apply -f ./helm-install-rabbit-mq/rabbit.yaml + workingDirectory: ${{ parameters.workingDirectory }} + displayName: 'Install Rabbit MQ' - task: PowerShell@2 displayName: 'Deploy CertManager' @@ -167,3 +163,10 @@ stages: arguments: '-ApiToken ${{ parameters.cloudflareApiKey }} -ZoneName ${{ parameters.cloudflareZone }}' pwsh: true workingDirectory: '$(System.DefaultWorkingDirectory)/cloudflare' + + - pwsh: | + helm upgrade --install auth-app .\auth-service-chart\ --values .\auth-service-chart\values.yaml --namespace "event-triangle" + helm upgrade --install consumer-app .\consumer-service-chart\ --values .\consumer-service-chart\values.yaml --namespace "event-triangle" + helm upgrade --install sender-app .\sender-service-chart\ --values .\sender-service-chart\values.yaml --namespace "event-triangle" + workingDirectory: $(System.DefaultWorkingDirectory)\helm + displayName: Deploy Web Apps diff --git a/azure-pipelines/templates/terraform-apply-stages.yml b/azure-pipelines/templates/terraform-apply-stages.yml index 91330f16..6991c4c6 100644 --- a/azure-pipelines/templates/terraform-apply-stages.yml +++ b/azure-pipelines/templates/terraform-apply-stages.yml @@ -72,9 +72,6 @@ stages: pool: vmImage: ${{ parameters.VmImage }} environment: ${{ parameters.environment }} - variables: - - name: 'TF_LOG' - value: 'INFO' strategy: runOnce: deploy: diff --git a/azure-pipelines/templates/terraform-plan-stages.yml b/azure-pipelines/templates/terraform-plan-stages.yml index d7e9ad4f..1c42bc73 100644 --- a/azure-pipelines/templates/terraform-plan-stages.yml +++ b/azure-pipelines/templates/terraform-plan-stages.yml @@ -66,9 +66,6 @@ stages: displayName: ${{ parameters.stageName }} pool: vmImage: ${{ parameters.VmImage }} - variables: - - name: 'TF_LOG' - value: 'INFO' steps: - checkout: self fetchDepth: 0 diff --git a/cloudflare/Cloudflare_curl.ps1 b/cloudflare/Cloudflare_curl.ps1 new file mode 100644 index 00000000..8d11179a --- /dev/null +++ b/cloudflare/Cloudflare_curl.ps1 @@ -0,0 +1,8 @@ +curl https://api.cloudflare.com/client/v4/zones -H "X-Auth-Email: $env:CLOUDFLARE_EMAIL" -H "X-Auth-Key: $env:CLOUDFLARE_API_KEY" + +curl https://api.cloudflare.com/client/v4/zones -H "Authorization: Bearer $env:CLOUDFLARE_API_KEY" -H "Content-Type: application/json" + +curl https://api.cloudflare.com/client/v4/user/tokens/verify -H "Authorization: Bearer $env:CLOUDFLARE_API_KEY" -H "Content-Type: application/json" + +curl https://api.cloudflare.com/client/v4/zones/d8bdf4c7860b59eddfd9fcc7bf864b47/dns_records ` + -H "Authorization: Bearer $env:CLOUDFLARE_API_KEY" -H "Content-Type: application/json" diff --git a/cloudflare/Get-CloudflareDnsRecords.ps1 b/cloudflare/Get-CloudflareDnsRecords.ps1 new file mode 100644 index 00000000..060db7eb --- /dev/null +++ b/cloudflare/Get-CloudflareDnsRecords.ps1 @@ -0,0 +1,27 @@ +param ( + [Parameter(Mandatory = $true)] + [string]$ApiToken, + + [Parameter(Mandatory = $true)] + [string]$ZoneId +) + +$url = "https://api.cloudflare.com/client/v4/zones/$ZoneId/dns_records" + +# Perform the API request +$response = $( curl $url -H "Authorization: Bearer $ApiToken" -H "Content-Type: application/json" ) + +# Parse the JSON response +$json = $response | ConvertFrom-Json + +# Create a hashtable to hold the records +$dnsRecords = @{} + +# Loop through the result and populate the hashtable +$json.result | ForEach-Object { + # Use the DNS record id as the key and the name as the value + $dnsRecords[$_.name] = $_.id +} + +# Return the hashtable +return $dnsRecords diff --git a/cloudflare/Get-CloudflareZoneId.ps1 b/cloudflare/Get-CloudflareZoneId.ps1 new file mode 100644 index 00000000..e1042ebf --- /dev/null +++ b/cloudflare/Get-CloudflareZoneId.ps1 @@ -0,0 +1,33 @@ +param ( + [Parameter(Mandatory = $true)] + [string]$ApiToken, + + [Parameter(Mandatory = $true)] + [string]$ZoneName +) + +$ErrorActionPreference = "Stop" + +$url = "https://api.cloudflare.com/client/v4/zones" + +# Perform the API request +$response = $( curl $url -H "Authorization: Bearer $ApiToken" -H "Content-Type: application/json" ) + +# Parse the JSON response +$json = $response | ConvertFrom-Json + +# Filter the result for the zone named 'razumovsky.me' +$zone = $json.result | Where-Object { $_.name -eq "$ZoneName" } + +# Output the Zone ID +if ($zone) +{ + return $zone.id +} +else +{ + Write-Output "Zone '$ZoneName' not found." +} + + + diff --git a/cloudflare/Get-NewDnsEntries.ps1 b/cloudflare/Get-NewDnsEntries.ps1 new file mode 100644 index 00000000..91f2a96d --- /dev/null +++ b/cloudflare/Get-NewDnsEntries.ps1 @@ -0,0 +1,9 @@ + +$ingressService = $( kubectl get service "event-ingress-ingress-nginx-controller" -n "event-triangle" -o json ) | ConvertFrom-Json +$ingressPublicIp = $ingressService.status.loadBalancer.ingress[0].ip + +$dnsRecords = @{} + +$dnsRecords["auth-eventtriangle.razumovsky.me"] = $ingressPublicIp + +return $dnsRecords diff --git a/cloudflare/Main.ps1 b/cloudflare/Main.ps1 new file mode 100644 index 00000000..38f9f70b --- /dev/null +++ b/cloudflare/Main.ps1 @@ -0,0 +1,81 @@ +param ( + [Parameter(Mandatory = $true)] + [string]$ApiToken, + + [Parameter(Mandatory = $true)] + [string]$ZoneName +) + +# Set error handling and preferences +$ErrorActionPreference = "Stop" + +Write-Host "Starting Cloudflare DNS Records Update Script..." -ForegroundColor Cyan + +# Step 1: Get Zone ID +Write-Host "Fetching Zone ID for Zone Name: $ZoneName..." -ForegroundColor Yellow +$zoneId = $(./Get-CloudflareZoneId.ps1 -ApiToken $ApiToken -ZoneName $ZoneName) + +if (-not $zoneId) { + Write-Error "Failed to fetch Zone ID. Exiting script." + exit 1 +} + +Write-Host "Zone ID Retrieved: $zoneId" -ForegroundColor Green + +# Step 2: Get DNS Records +Write-Host "Fetching existing DNS records for Zone ID: $zoneId..." -ForegroundColor Yellow +$dnsRecords = $(.\Get-CloudflareDnsRecords.ps1 -ApiToken $ApiToken -ZoneId "$zoneId") + +if (-not $dnsRecords -or -not ($dnsRecords -is [hashtable])) { + Write-Error "Failed to fetch DNS records or records are not in the expected format. Exiting script." + exit 1 +} + +Write-Host "DNS Records Retrieved: $($dnsRecords.Count) records found." -ForegroundColor Green + +# Step 3: Get New DNS Entries +Write-Host "Fetching new DNS entries to update..." -ForegroundColor Yellow +$newDnsEntries = $(.\Get-NewDnsEntries.ps1) + +if (-not $newDnsEntries -or -not ($newDnsEntries -is [hashtable])) { + Write-Error "Failed to fetch new DNS entries or entries are not in the expected format. Exiting script." + exit 1 +} + +Write-Host "New DNS Entries Retrieved: $($newDnsEntries.Count) entries to process." -ForegroundColor Green + +# Step 4: Process Each New DNS Entry +Write-Host "Starting to process new DNS entries..." -ForegroundColor Cyan +foreach ($entry in $newDnsEntries.GetEnumerator()) { + $dnsName = $entry.Name + $ipAddress = $entry.Value + + Write-Host "`nProcessing Entry: $dnsName => $ipAddress" -ForegroundColor Cyan + + # Check if the DNS name exists in the current DNS records + if ($dnsRecords.ContainsKey($dnsName)) { + # Get the record ID for the existing DNS record + $recordId = $dnsRecords[$dnsName] + + Write-Host "Found existing DNS record for $dnsName. Record ID: $recordId" -ForegroundColor Green + Write-Host "Updating DNS record for $dnsName with IP Address: $ipAddress" -ForegroundColor Yellow + + # Update the DNS record + try { + .\Update-CloudflareDnsRecord.ps1 -ApiToken $ApiToken ` + -DnsName $dnsName ` + -ZoneId $zoneId ` + -RecordId $recordId ` + -IpAddress $ipAddress + + Write-Host "Successfully updated DNS record for $dnsName." -ForegroundColor Green + } catch { + Write-Error "Failed to update DNS record for $dnsName. Error: $_" + } + } else { + Write-Host "DNS name $dnsName does not exist in Cloudflare. Skipping..." -ForegroundColor Red + } +} + +# Final Step: Script Completion +Write-Host "`nDNS records update process completed successfully!" -ForegroundColor Green diff --git a/cloudflare/Update-CloudflareDnsRecord.ps1 b/cloudflare/Update-CloudflareDnsRecord.ps1 new file mode 100644 index 00000000..64755543 --- /dev/null +++ b/cloudflare/Update-CloudflareDnsRecord.ps1 @@ -0,0 +1,58 @@ +param ( + [Parameter(Mandatory = $true)] + [string]$ApiToken, + + [Parameter(Mandatory = $true)] + [string]$DnsName, + + [Parameter(Mandatory = $true)] + [string]$ZoneId, + + [Parameter(Mandatory = $true)] + [string]$RecordId, + + [Parameter(Mandatory = $true)] + [string]$IpAddress +) + +$url = "https://api.cloudflare.com/client/v4/zones/$ZoneId/dns_records/$RecordId" + +$body = @{ + comment = "Sent from Powershell $( $( Get-Date ).DateTime )" + content = $IpAddress + name = $DnsName + proxied = $false + settings = @{ + ipv4_only = $false + ipv6_only = $false + } + ttl = 1 + type = "A" +} | ConvertTo-Json -Depth 4 + +# Perform the API request +$response = curl $url ` + -X PATCH ` + -H "Authorization: Bearer $ApiToken" ` + -H "Content-Type: application/json" ` + -d $body + +$responseJson = $response | ConvertFrom-Json + +# Check the response +if ($responseJson.success -eq $true) +{ + Write-Host "DNS record updated successfully." + Write-Host "Response: $response" +} +else +{ + Write-Host "Failed to update DNS record." + Write-Host "Response: $( $response )" +} + +#.\Update-CloudflareDnsRecord.ps1 -ApiToken $env:CLOUDFLARE_API_KEY ` +# -DnsName "auth-eventtriangle.razumovsky.me" ` +# -ZoneId $zoneId ` +# -RecordId "98b014141c8d4bae0db9800617c04076" ` +# -IpAddress "172.205.36.169" diff --git a/helm/auth-service-chart/templates/deployment.yaml b/helm/auth-service-chart/templates/deployment.yaml index 47c7b3d6..adec7965 100644 --- a/helm/auth-service-chart/templates/deployment.yaml +++ b/helm/auth-service-chart/templates/deployment.yaml @@ -22,6 +22,8 @@ spec: - containerPort: {{ .containerPort }} {{- end }} env: + - name: ASPNETCORE_ENVIRONMENT + value: "Docker" {{- range .Values.env }} - name: {{ .name }} valueFrom: diff --git a/helm/auth-service-chart/values.yaml b/helm/auth-service-chart/values.yaml index 0719439a..ab1dcc2d 100644 --- a/helm/auth-service-chart/values.yaml +++ b/helm/auth-service-chart/values.yaml @@ -21,10 +21,15 @@ env: refName: connection-creds key: AuthDatabaseConnectionString - - name: ASPNETCORE_ENVIRONMENT - type: configMapKeyRef - refName: auth-service-chart-configmap - key: ASPNETCORE_ENVIRONMENT + - name: RedisPassword + type: secretKeyRef + refName: connection-creds + key: RedisPassword + + - name: RedisUrl + type: secretKeyRef + refName: connection-creds + key: RedisUrl service: type: ClusterIP diff --git a/helm/consumer-service-chart/templates/configmap.yaml b/helm/consumer-service-chart/templates/configmap.yaml deleted file mode 100644 index 7908f4b0..00000000 --- a/helm/consumer-service-chart/templates/configmap.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap - namespace: {{ .Values.namespace }} - labels: - app: {{ .Release.Name }} -data: - ASPNETCORE_ENVIRONMENT: {{ .Values.configMap.ASPNETCORE_ENVIRONMENT | quote }} diff --git a/helm/consumer-service-chart/templates/deployment.yaml b/helm/consumer-service-chart/templates/deployment.yaml index 45f0c44c..9afab752 100644 --- a/helm/consumer-service-chart/templates/deployment.yaml +++ b/helm/consumer-service-chart/templates/deployment.yaml @@ -20,6 +20,8 @@ spec: ports: - containerPort: {{ .Values.ports.containerPort }} env: + - name: ASPNETCORE_ENVIRONMENT + value: "Docker" - name: RabbitMqHost valueFrom: secretKeyRef: @@ -40,8 +42,3 @@ spec: secretKeyRef: name: {{ .Values.env.DatabaseConnectionString.secretName }} key: {{ .Values.env.DatabaseConnectionString.key }} - - name: ASPNETCORE_ENVIRONMENT - valueFrom: - configMapKeyRef: - name: {{ .Values.env.ASPNETCORE_ENVIRONMENT.configMapName }} - key: {{ .Values.env.ASPNETCORE_ENVIRONMENT.key }} diff --git a/helm/consumer-service-chart/values.yaml b/helm/consumer-service-chart/values.yaml index fd5a16c9..8223e598 100644 --- a/helm/consumer-service-chart/values.yaml +++ b/helm/consumer-service-chart/values.yaml @@ -13,24 +13,17 @@ ports: env: RabbitMqHost: - secretName: connection-creds - key: RabbitMqHost + secretName: event-rabbitmq-default-user + key: host RabbitMqUsername: - secretName: connection-creds - key: RabbitMqUsername + secretName: event-rabbitmq-default-user + key: username RabbitMqPassword: - secretName: connection-creds - key: RabbitMqPassword + secretName: event-rabbitmq-default-user + key: password DatabaseConnectionString: secretName: connection-creds key: ConsumerDatabaseConnectionString - - ASPNETCORE_ENVIRONMENT: - configMapName: consumer-service-chart-configmap - key: ASPNETCORE_ENVIRONMENT - -configMap: - ASPNETCORE_ENVIRONMENT: Docker diff --git a/helm/helm-install-rabbit-mq/deploy-rabbitmq-example.ps1 b/helm/helm-install-rabbit-mq/deploy-rabbitmq-example.ps1 deleted file mode 100644 index 1adfb975..00000000 --- a/helm/helm-install-rabbit-mq/deploy-rabbitmq-example.ps1 +++ /dev/null @@ -1,21 +0,0 @@ -az aks get-credentials --resource-group $(terraform output -raw rg_name) --name $(terraform output -raw aks_name) --subscription $(terraform output -raw subscription) - -helm repo add bitnami https://charts.bitnami.com/bitnami - -helm repo update - -helm install event-rabbitmq bitnami/rabbitmq ` - --namespace event-triangle ` - --set auth.username=guest ` - --set auth.password=guest ` - --set service.type=LoadBalancer - -helm upgrade event-rabbitmq bitnami/rabbitmq ` - --set auth.username=guest ` - --set auth.password=guest - -helm uninstall event-rabbitmq - -kubectl get endpoints - -kubectl describe service "event-rabbitmq" diff --git a/helm/sender-service-chart/templates/configmap.yaml b/helm/sender-service-chart/templates/configmap.yaml deleted file mode 100644 index 7908f4b0..00000000 --- a/helm/sender-service-chart/templates/configmap.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap - namespace: {{ .Values.namespace }} - labels: - app: {{ .Release.Name }} -data: - ASPNETCORE_ENVIRONMENT: {{ .Values.configMap.ASPNETCORE_ENVIRONMENT | quote }} diff --git a/helm/sender-service-chart/templates/deployment.yaml b/helm/sender-service-chart/templates/deployment.yaml index 4702fdfa..a4a763e2 100644 --- a/helm/sender-service-chart/templates/deployment.yaml +++ b/helm/sender-service-chart/templates/deployment.yaml @@ -22,6 +22,8 @@ spec: - containerPort: {{ .targetPort }} {{- end }} env: + - name: ASPNETCORE_ENVIRONMENT + value: "Docker" {{- range .Values.env }} - name: {{ .name }} valueFrom: diff --git a/helm/sender-service-chart/templates/service.yaml b/helm/sender-service-chart/templates/service.yaml index 058df458..262f6415 100644 --- a/helm/sender-service-chart/templates/service.yaml +++ b/helm/sender-service-chart/templates/service.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: Service metadata: - name: event-triangle-sender-service + name: {{ .Release.Name }}-service namespace: {{ .Values.namespace }} spec: selector: diff --git a/helm/sender-service-chart/values.yaml b/helm/sender-service-chart/values.yaml index 12423c2a..9f82d55b 100644 --- a/helm/sender-service-chart/values.yaml +++ b/helm/sender-service-chart/values.yaml @@ -18,28 +18,20 @@ service: env: - name: RabbitMqHost type: secretKeyRef - refName: connection-creds - key: RabbitMqHost + refName: event-rabbitmq-default-user + key: host - name: RabbitMqUsername type: secretKeyRef - refName: connection-creds - key: RabbitMqUsername + refName: event-rabbitmq-default-user + key: username - name: RabbitMqPassword type: secretKeyRef - refName: connection-creds - key: RabbitMqPassword + refName: event-rabbitmq-default-user + key: password - name: DatabaseConnectionString type: secretKeyRef refName: connection-creds key: SenderDatabaseConnectionString - - - name: ASPNETCORE_ENVIRONMENT - type: configMapKeyRef - refName: sender-service-chart-configmap - key: ASPNETCORE_ENVIRONMENT - -configMap: - ASPNETCORE_ENVIRONMENT: Docker diff --git a/helm/helm-install-cert-manager/cert-manager-commands.ps1 b/platform/helm-install-cert-manager/cert-manager-commands.ps1 similarity index 100% rename from helm/helm-install-cert-manager/cert-manager-commands.ps1 rename to platform/helm-install-cert-manager/cert-manager-commands.ps1 diff --git a/helm/helm-install-cert-manager/deploy-cert-manager-helm.ps1 b/platform/helm-install-cert-manager/deploy-cert-manager-helm.ps1 similarity index 100% rename from helm/helm-install-cert-manager/deploy-cert-manager-helm.ps1 rename to platform/helm-install-cert-manager/deploy-cert-manager-helm.ps1 diff --git a/helm/helm-install-grafana-prometheus/Example.ps1 b/platform/helm-install-grafana-prometheus/Example.ps1 similarity index 100% rename from helm/helm-install-grafana-prometheus/Example.ps1 rename to platform/helm-install-grafana-prometheus/Example.ps1 diff --git a/helm/helm-install-grafana-prometheus/monitoring-http-nginx-ingress.yaml b/platform/helm-install-grafana-prometheus/monitoring-http-nginx-ingress.yaml similarity index 100% rename from helm/helm-install-grafana-prometheus/monitoring-http-nginx-ingress.yaml rename to platform/helm-install-grafana-prometheus/monitoring-http-nginx-ingress.yaml diff --git a/helm/helm-install-nginx-ingress/deploy-ingress-helm.ps1 b/platform/helm-install-nginx-ingress/deploy-ingress-helm.ps1 similarity index 100% rename from helm/helm-install-nginx-ingress/deploy-ingress-helm.ps1 rename to platform/helm-install-nginx-ingress/deploy-ingress-helm.ps1 diff --git a/helm/helm-install-nginx-ingress/install-nginx-ingress-example.ps1 b/platform/helm-install-nginx-ingress/install-nginx-ingress-example.ps1 similarity index 100% rename from helm/helm-install-nginx-ingress/install-nginx-ingress-example.ps1 rename to platform/helm-install-nginx-ingress/install-nginx-ingress-example.ps1 diff --git a/platform/helm-install-rabbit-mq/deploy-rabbitmq-example.ps1 b/platform/helm-install-rabbit-mq/deploy-rabbitmq-example.ps1 new file mode 100644 index 00000000..71e00967 --- /dev/null +++ b/platform/helm-install-rabbit-mq/deploy-rabbitmq-example.ps1 @@ -0,0 +1,3 @@ +kubectl apply -f "https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml" + +kubectl apply -f rabbit.yaml diff --git a/helm/helm-install-rabbit-mq/deploy-rabbitmq-helm.ps1 b/platform/helm-install-rabbit-mq/deploy-rabbitmq-helm.ps1 similarity index 100% rename from helm/helm-install-rabbit-mq/deploy-rabbitmq-helm.ps1 rename to platform/helm-install-rabbit-mq/deploy-rabbitmq-helm.ps1 diff --git a/platform/helm-install-rabbit-mq/rabbit.yaml b/platform/helm-install-rabbit-mq/rabbit.yaml new file mode 100644 index 00000000..e56144f1 --- /dev/null +++ b/platform/helm-install-rabbit-mq/rabbit.yaml @@ -0,0 +1,7 @@ +apiVersion: rabbitmq.com/v1beta1 +kind: RabbitmqCluster +metadata: + name: event-rabbitmq + namespace: event-triangle +spec: + replicas: 1 diff --git a/helm/helm-install-redis/Commands.ps1 b/platform/helm-install-redis/Commands.ps1 similarity index 100% rename from helm/helm-install-redis/Commands.ps1 rename to platform/helm-install-redis/Commands.ps1 diff --git a/kubernetes/namespace/namespace.yaml b/platform/namespace/namespace.yaml similarity index 100% rename from kubernetes/namespace/namespace.yaml rename to platform/namespace/namespace.yaml diff --git a/kubernetes/pgsql-deployment-load-balancer/pgsql-deployment.yaml b/platform/pgsql-deployment/pgsql-deployment.yaml similarity index 100% rename from kubernetes/pgsql-deployment-load-balancer/pgsql-deployment.yaml rename to platform/pgsql-deployment/pgsql-deployment.yaml diff --git a/kubernetes/pgsql-deployment-load-balancer/pgsql-pv-claim.yaml b/platform/pgsql-deployment/pgsql-pv-claim.yaml similarity index 100% rename from kubernetes/pgsql-deployment-load-balancer/pgsql-pv-claim.yaml rename to platform/pgsql-deployment/pgsql-pv-claim.yaml diff --git a/kubernetes/pgsql-deployment-load-balancer/pgsql-pv.yaml b/platform/pgsql-deployment/pgsql-pv.yaml similarity index 100% rename from kubernetes/pgsql-deployment-load-balancer/pgsql-pv.yaml rename to platform/pgsql-deployment/pgsql-pv.yaml diff --git a/kubernetes/pgsql-deployment-load-balancer/pgsql-service.yaml b/platform/pgsql-deployment/pgsql-service.yaml similarity index 90% rename from kubernetes/pgsql-deployment-load-balancer/pgsql-service.yaml rename to platform/pgsql-deployment/pgsql-service.yaml index 23ea023c..c5c4d5bb 100644 --- a/kubernetes/pgsql-deployment-load-balancer/pgsql-service.yaml +++ b/platform/pgsql-deployment/pgsql-service.yaml @@ -7,7 +7,7 @@ metadata: labels: app: postgresdb spec: - type: LoadBalancer + type: ClusterIP ports: - port: 5432 selector: diff --git a/kubernetes/scripts/print-ip.ps1 b/platform/scripts/print-ip.ps1 similarity index 100% rename from kubernetes/scripts/print-ip.ps1 rename to platform/scripts/print-ip.ps1 diff --git a/kubernetes/scripts/wait-deployments.ps1 b/platform/scripts/wait-deployments.ps1 similarity index 100% rename from kubernetes/scripts/wait-deployments.ps1 rename to platform/scripts/wait-deployments.ps1 diff --git a/kubernetes/secrets/connection-secrets.yaml b/platform/secrets/connection-secrets.yaml similarity index 81% rename from kubernetes/secrets/connection-secrets.yaml rename to platform/secrets/connection-secrets.yaml index 23c8edee..57991ca1 100644 --- a/kubernetes/secrets/connection-secrets.yaml +++ b/platform/secrets/connection-secrets.yaml @@ -4,16 +4,14 @@ metadata: name: connection-creds namespace: event-triangle type: Opaque -stringData: # takes plain text secrets +stringData: EVENT_TRIANGLE_AD_CLIENT_SECRET: "{{library-azure-ad-secret}}" SenderDatabaseConnectionString: "Server=postgres-service;User Id={{POSTGRES_USER}};Password={{POSTGRES_PASSWORD}};Database=SenderDb;" AuthDatabaseConnectionString: "Server=postgres-service;User Id={{POSTGRES_USER}};Password={{POSTGRES_PASSWORD}};Database=AuthorizationDb;" ConsumerDatabaseConnectionString: "Server=postgres-service;User Id={{POSTGRES_USER}};Password={{POSTGRES_PASSWORD}};Database=ConsumerDb;" - RabbitMqHost: "event-rabbitmq" + RabbitMqHost: "event-rabbitmq.event-triangle.svc" POSTGRES_USER: "{{POSTGRES_USER}}" POSTGRES_PASSWORD: "{{POSTGRES_PASSWORD}}" POSTGRES_DB: "{{POSTGRES_DB}}" - RabbitMqUsername: "{{library-rabbitmq-user}}" - RabbitMqPassword: "{{library-rabbitmq-password}}" RedisUrl: "{{library-redis-url}}" RedisPassword: "{{library-redis-password}}" diff --git a/src/authorization/EventTriangleAPI.Authorization.Domain/Entities/Validation/UserEntityValidator.cs b/src/authorization/EventTriangleAPI.Authorization.Domain/Entities/Validation/UserEntityValidator.cs index 21d8e573..2b294b21 100644 --- a/src/authorization/EventTriangleAPI.Authorization.Domain/Entities/Validation/UserEntityValidator.cs +++ b/src/authorization/EventTriangleAPI.Authorization.Domain/Entities/Validation/UserEntityValidator.cs @@ -13,8 +13,13 @@ public UserEntityValidator() private bool ValidateEmail(string email) { - if (email == null) return false; + if (email == null) + { + return false; + } + + Console.WriteLine($"UserEntityValidator -> ValidateEmail -> Received: {email}."); return Regex.IsMatch(email, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"); } -} \ No newline at end of file +} diff --git a/terraform/locals.tf b/terraform/locals.tf deleted file mode 100644 index aecb64d0..00000000 --- a/terraform/locals.tf +++ /dev/null @@ -1,7 +0,0 @@ -locals { - resource_group_name = "${var.resource_group_name}-${var.prefix}" - aks_name = "${var.cluster_name}-${var.prefix}" - prometheus_name = "prometheus-aks-${var.prefix}" - grafana_name = "grafana-aks-${var.prefix}" - workspace_name = "loganalytics-${var.prefix}" -} diff --git a/terraform/main.tf b/terraform/main.tf index e48479a0..f17aea7e 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -1,5 +1,14 @@ data "azurerm_client_config" "current" {} +locals { + resource_group_name = "${var.resource_group_name}-${var.prefix}" + aks_node_resource_group_name = "${var.resource_group_name}-node-${var.prefix}" + aks_name = "${var.cluster_name}-${var.prefix}" + prometheus_name = "prometheus-aks-${var.prefix}" + grafana_name = "grafana-aks-${var.prefix}" + workspace_name = "loganalytics-${var.prefix}" +} + resource "azurerm_resource_group" "public" { location = var.resource_group_location name = local.resource_group_name @@ -15,16 +24,17 @@ module "log_analytics" { } module "aks" { - source = "./modules/aks" - aks_name = local.aks_name - default_node_pool_type = var.default_node_pool_type - default_node_pool_vm_size = var.default_node_pool_vm_size - kubernetes_version = var.kubernetes_version - log_analytics_workspace_id = length(module.log_analytics) > 0 ? module.log_analytics[0].id : null - resource_group_location = azurerm_resource_group.public.location - resource_group_name = azurerm_resource_group.public.name - system_node_count = var.system_node_count - should_deploy_log_analytics = var.should_deploy_log_analytics + source = "./modules/aks" + aks_name = local.aks_name + default_node_pool_type = var.default_node_pool_type + default_node_pool_vm_size = var.default_node_pool_vm_size + kubernetes_version = var.kubernetes_version + log_analytics_workspace_id = length(module.log_analytics) > 0 ? module.log_analytics[0].id : null + resource_group_location = azurerm_resource_group.public.location + resource_group_name = azurerm_resource_group.public.name + aks_node_resource_group_name = local.aks_node_resource_group_name + system_node_count = var.system_node_count + should_deploy_log_analytics = var.should_deploy_log_analytics depends_on = [ module.log_analytics diff --git a/terraform/modules/aks/main.tf b/terraform/modules/aks/main.tf index 0548e031..c31f7296 100644 --- a/terraform/modules/aks/main.tf +++ b/terraform/modules/aks/main.tf @@ -4,6 +4,7 @@ resource "azurerm_kubernetes_cluster" "aks" { location = var.resource_group_location resource_group_name = var.resource_group_name dns_prefix = var.aks_name + node_resource_group = var.aks_node_resource_group_name default_node_pool { name = "systempool" diff --git a/terraform/modules/aks/variables.tf b/terraform/modules/aks/variables.tf index c7f10bc7..2a6d45dd 100644 --- a/terraform/modules/aks/variables.tf +++ b/terraform/modules/aks/variables.tf @@ -42,3 +42,7 @@ variable "log_analytics_workspace_id" { type = string description = "The ID of the Log Analytics workspace to use for the AKS cluster" } + +variable "aks_node_resource_group_name" { + type = string +} diff --git a/terraform/terraform.auto.tfvars.json b/terraform/terraform.auto.tfvars.json index adf2cf65..c820c251 100644 --- a/terraform/terraform.auto.tfvars.json +++ b/terraform/terraform.auto.tfvars.json @@ -1,5 +1,5 @@ { - "resource_group_name": "rg-aks-terraform", + "resource_group_name": "rg-aks", "resource_group_location": "northeurope", "prefix": "d01", "kubernetes_version": "1.35.1",