diff --git a/.gitignore b/.gitignore index 0561893e..c7f52a2b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,9 @@ *.lock.info *.conf *.txt +terraform-azdo-libraries/.terraform +terraform-azdo-libraries/*.lock.hcl +terraform-azdo-libraries/*.tfvars.json # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..ca33898b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,53 @@ +{ + "editor.mouseWheelZoom": true, + "editor.fontSize": 13, + "editor.rulers": [ + 80 + ], + "editor.wordWrap": "off", + "window.zoomLevel": 0, + "editor.fontFamily": "JetBrains Mono, Consolas, 'Courier New', monospace", + "editor.fontLigatures": true, + "editor.lineHeight": 1.6, + "editor.letterSpacing": 0.2, + "files.autoSave": "afterDelay", + "files.autoSaveDelay": 1000, + "[latex]": { + "editor.defaultFormatter": "James-Yu.latex-workshop", + "editor.formatOnSave": true + }, + "latex-workshop.formatting.latex": "tex-fmt", + "latex-workshop.latex.autoBuild.run": "never", + "cSpell.language": "en", + "cSpell.enabled": true, + "cSpell.words": [ + "Bohner", + "Butzer", + "Cereceda", + "choco", + "Creds", + "DOCKERHUB", + "Eulerian", + "eventtriangleapi", + "Faulhaber", + "fluxcd", + "gitversion", + "howpublished", + "Kolosov", + "Mathematica", + "OEIS", + "opencover", + "ORCID", + "pandoc", + "Postge", + "Principia", + "Refactorization", + "Riordan", + "SOURCEBRANCHNAME", + "tabl", + "updatebuildnumber", + "vstest", + "Worpitzky", + "Zenodo" + ] +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ebdb3ea..281f2dca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning v2.0.0](https://semver.org/spec/v2.0.0.html). -## [1.0.0] - In Progress +## [1.0.0] - 18-Apr-2026 ### Changed @@ -46,3 +46,12 @@ and this project adheres to [Semantic Versioning v2.0.0](https://semver.org/spec - Platform: Change PostgeSQL to be cluster IP - Disable terraform log info - Add AKS node pool name +- Platform updates +- Azure DevOps library terraform +- Wrap platform postgres deployment to powershell script +- Update verify encoding script +- Rename platform pipeline +- Run SonarCloud scan only if source branch is main (add if condition) +- For Docker CI/CD build: add one more tag with short commit sha +- Add build pipelines trigger on tag +- Docker script add logs diff --git a/azure-pipelines/build/build-auth.yml b/azure-pipelines/build/build-auth.yml index e237384c..a2bddb1d 100644 --- a/azure-pipelines/build/build-auth.yml +++ b/azure-pipelines/build/build-auth.yml @@ -3,6 +3,9 @@ trigger: branches: include: - main + tags: + include: + - v* pr: none @@ -25,8 +28,7 @@ stages: solution: '$(System.DefaultWorkingDirectory)/EventTriangleAPI.sln' buildConfiguration: 'Release' backendProjectPath: '$(System.DefaultWorkingDirectory)/src/authorization/EventTriangleAPI.Authorization.Presentation' - unitTestsProjectPath: '$(System.DefaultWorkingDirectory)/src/authorization/EventTriangleAPI.Authorization.UnitTests/EventTriangleAPI.Authorization.UnitTests.csproj' - shouldRunUnitTests: true + shouldRunUnitTests: false shouldRunIntegrationTests: true integrationTestsProjectPath: '$(System.DefaultWorkingDirectory)/src/authorization/EventTriangleAPI.Authorization.IntegrationTests/EventTriangleAPI.Authorization.IntegrationTests.csproj' dockerRegistryUrl: 'docker.io/kaminome' @@ -37,5 +39,4 @@ stages: shouldPushToAcr: true acrRegistryUrl: 'acrsharedd01.azurecr.io' acrServiceConnection: 'Azure_ACR_Connection' - sonarCloudEnabled: true workingDirectoryForDocker: '$(System.DefaultWorkingDirectory)/src' diff --git a/azure-pipelines/build/build-consumer.yml b/azure-pipelines/build/build-consumer.yml index 8cecde6f..1cb23e1e 100644 --- a/azure-pipelines/build/build-consumer.yml +++ b/azure-pipelines/build/build-consumer.yml @@ -3,6 +3,9 @@ trigger: branches: include: - main + tags: + include: + - v* pr: none @@ -36,5 +39,4 @@ stages: shouldPushToAcr: true acrRegistryUrl: 'acrsharedd01.azurecr.io' acrServiceConnection: 'Azure_ACR_Connection' - sonarCloudEnabled: false workingDirectoryForDocker: '$(System.DefaultWorkingDirectory)/src' diff --git a/azure-pipelines/build/build-sender.yml b/azure-pipelines/build/build-sender.yml index 25b62170..b5f54900 100644 --- a/azure-pipelines/build/build-sender.yml +++ b/azure-pipelines/build/build-sender.yml @@ -3,6 +3,9 @@ trigger: branches: include: - main + tags: + include: + - v* pr: none @@ -36,5 +39,4 @@ stages: shouldPushToAcr: true acrRegistryUrl: 'acrsharedd01.azurecr.io' acrServiceConnection: 'Azure_ACR_Connection' - sonarCloudEnabled: false workingDirectoryForDocker: '$(System.DefaultWorkingDirectory)/src' diff --git a/azure-pipelines/infrastructure/configure-aks-cluster.yml b/azure-pipelines/infrastructure/configure-platform.yml similarity index 61% rename from azure-pipelines/infrastructure/configure-aks-cluster.yml rename to azure-pipelines/infrastructure/configure-platform.yml index c2a144fc..e77fe984 100644 --- a/azure-pipelines/infrastructure/configure-aks-cluster.yml +++ b/azure-pipelines/infrastructure/configure-platform.yml @@ -16,29 +16,27 @@ trigger: none pr: none variables: - - group: Azure_Terraform_Integration - - group: Postgres_Rabbit_Connection_Credentials - - group: Terraform_Auto_Tfvars_Json_Transform + - group: Terraform_Azure_Credentials + - group: Cloudflare_API_Key + - group: Postgres_Settings + - group: Redis_Credentials - group: AKS_Settings - - group: Cloudflare_configuration - group: Prefix_Library + - group: Entra_ID_Auth_Secret - name: System.Debug value: 'false' stages: - - template: ../templates/configure-cluster-stages.yml + - template: ../templates/configure-platform-stages.yml parameters: vmImage: windows-latest - environment: aks + environment: dev workingDirectory: $(System.DefaultWorkingDirectory)/platform serviceConnection: Azure_Connection azureResourceGroup: $(library-aks-resource-group) kubernetesCluster: $(library-aks-cluster-name) - namespace: 'event-triangle' - rabbitMqUser: $(library-rabbitmq-user) - rabbitMqPassword: $(library-rabbitmq-password) + namespace: $(library-aks-namespace) cloudflareApiKey: $(cloudflare-api-key) cloudflareZone: $(cloudflare-zone-name) redisPassword: $(library-redis-password) - transformTargetFiles: | - secrets/connection-secrets.yaml + entraIdAuthSecret: $(library-entra-id-auth-secret) diff --git a/azure-pipelines/infrastructure/terraform-create.yml b/azure-pipelines/infrastructure/terraform-create.yml index 3cfc2057..01ae9216 100644 --- a/azure-pipelines/infrastructure/terraform-create.yml +++ b/azure-pipelines/infrastructure/terraform-create.yml @@ -16,7 +16,8 @@ trigger: none pr: none variables: - - group: Azure_Terraform_Integration + - group: Terraform_Azure_Credentials + - group: Terraform_Backend_StateFile_Settings - group: Terraform_Auto_Tfvars_Json_Transform - group: AKS_Settings - group: Prefix_Library @@ -26,6 +27,8 @@ variables: value: "Terraform_Plan" - name: applyStageName value: "Terraform_Apply" + # - name: TF_LOG + # value: 'INFO' stages: - template: ../templates/terraform-plan-stages.yml @@ -59,6 +62,6 @@ stages: clientId: $(library-client-id) clientSecret: $(library-client-secret) tenantId: $(library-tenant-id) - environment: 'aks' + environment: dev dependsOn: [ '${{ variables.planStageName }}' ] condition: ${{ variables.planStageName }} diff --git a/azure-pipelines/infrastructure/terraform-destroy.yml b/azure-pipelines/infrastructure/terraform-destroy.yml index f726b6d7..19a60682 100644 --- a/azure-pipelines/infrastructure/terraform-destroy.yml +++ b/azure-pipelines/infrastructure/terraform-destroy.yml @@ -11,16 +11,19 @@ trigger: none pr: none variables: - - group: Azure_Terraform_Integration + - group: Terraform_Azure_Credentials + - group: Terraform_Backend_StateFile_Settings - group: Terraform_Auto_Tfvars_Json_Transform - - group: Prefix_Library - group: AKS_Settings + - group: Prefix_Library - name: System.Debug value: 'false' - name: planStageName value: "Terraform_Plan_Destroy" - name: applyStageName value: "Terraform_Destroy" + # - name: TF_LOG + # value: 'INFO' stages: - template: ../templates/terraform-plan-stages.yml @@ -54,6 +57,6 @@ stages: clientId: $(library-client-id) clientSecret: $(library-client-secret) tenantId: $(library-tenant-id) - environment: 'aks' + environment: dev dependsOn: [ '${{ variables.planStageName }}' ] condition: ${{ variables.planStageName }} diff --git a/azure-pipelines/pr-validation/pr-validation-auth.yml b/azure-pipelines/pr-validation/pr-validation-auth.yml index 09846853..b76d17d4 100644 --- a/azure-pipelines/pr-validation/pr-validation-auth.yml +++ b/azure-pipelines/pr-validation/pr-validation-auth.yml @@ -35,8 +35,7 @@ stages: solution: '$(System.DefaultWorkingDirectory)/EventTriangleAPI.sln' buildConfiguration: 'Release' backendProjectPath: '$(System.DefaultWorkingDirectory)/src/authorization/EventTriangleAPI.Authorization.Presentation' - unitTestsProjectPath: '$(System.DefaultWorkingDirectory)/src/authorization/EventTriangleAPI.Authorization.UnitTests/EventTriangleAPI.Authorization.UnitTests.csproj' - shouldRunUnitTests: true + shouldRunUnitTests: false shouldRunIntegrationTests: true integrationTestsProjectPath: '$(System.DefaultWorkingDirectory)/src/authorization/EventTriangleAPI.Authorization.IntegrationTests/EventTriangleAPI.Authorization.IntegrationTests.csproj' dockerRegistryUrl: 'docker.io/kaminome' @@ -47,5 +46,4 @@ stages: shouldPushToAcr: true acrRegistryUrl: 'acrsharedd01.azurecr.io' acrServiceConnection: 'Azure_ACR_Connection' - 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 d83a43d7..162df5df 100644 --- a/azure-pipelines/pr-validation/pr-validation-consumer.yml +++ b/azure-pipelines/pr-validation/pr-validation-consumer.yml @@ -50,5 +50,4 @@ stages: shouldPushToAcr: true acrRegistryUrl: 'acrsharedd01.azurecr.io' acrServiceConnection: 'Azure_ACR_Connection' - sonarCloudEnabled: false workingDirectoryForDocker: '$(System.DefaultWorkingDirectory)/src' diff --git a/azure-pipelines/pr-validation/pr-validation-sender.yml b/azure-pipelines/pr-validation/pr-validation-sender.yml index 769be103..f567d09f 100644 --- a/azure-pipelines/pr-validation/pr-validation-sender.yml +++ b/azure-pipelines/pr-validation/pr-validation-sender.yml @@ -50,5 +50,4 @@ stages: shouldPushToAcr: true acrRegistryUrl: 'acrsharedd01.azurecr.io' acrServiceConnection: 'Azure_ACR_Connection' - sonarCloudEnabled: false workingDirectoryForDocker: '$(System.DefaultWorkingDirectory)/src' diff --git a/azure-pipelines/templates/configure-cluster-stages.yml b/azure-pipelines/templates/configure-cluster-stages.yml deleted file mode 100644 index 2cbd9c4b..00000000 --- a/azure-pipelines/templates/configure-cluster-stages.yml +++ /dev/null @@ -1,172 +0,0 @@ -parameters: - - name: vmImage - default: 'windows-latest' - type: string - - - name: environment - type: string - - - name: serviceConnection - type: string - - - name: azureResourceGroup - type: string - - - name: kubernetesCluster - type: string - - - name: namespace - type: string - default: 'event-triangle' - - - name: workingDirectory - displayName: 'Working directory for Kubernetes' - type: string - - - name: transformTargetFiles - displayName: 'Target files for token replacement' - type: string - - - name: rabbitMqUser - displayName: 'RabbitMQ User' - type: string - - - name: rabbitMqPassword - displayName: 'RabbitMQ Password' - type: string - - - name: cloudflareApiKey - displayName: 'Cloudflare API Token' - type: string - - - name: cloudflareZone - 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 }}' - jobs: - - deployment: 'Configure_AKS_${{ parameters.environment }}' - displayName: 'Configure_AKS_${{ parameters.environment }}' - pool: - vmImage: ${{ parameters.vmImage }} - environment: ${{ parameters.environment }} - strategy: - runOnce: - deploy: - steps: - - checkout: self - fetchDepth: 0 - - - task: Kubernetes@1 - displayName: 'Kubernetes Login' - inputs: - connectionType: 'Azure Resource Manager' - azureSubscriptionEndpoint: ${{ parameters.serviceConnection }} - azureResourceGroup: ${{ parameters.azureResourceGroup }} - kubernetesCluster: ${{ parameters.kubernetesCluster }} - command: 'login' - - - task: replacetokens@5 - displayName: 'Replace tokens in secrets' - inputs: - rootDirectory: ${{ parameters.workingDirectory }} - targetFiles: ${{ parameters.transformTargetFiles }} - tokenPattern: 'doublebraces' - writeBOM: false - - - task: PowerShell@2 - displayName: 'Deploy Namespace' - inputs: - targetType: 'inline' - script: 'kubectl apply -f ./namespace' - pwsh: true - workingDirectory: ${{ parameters.workingDirectory }} - - - task: PowerShell@2 - displayName: 'Deploy Secrets' - inputs: - targetType: 'inline' - script: 'kubectl apply -f ./secrets --namespace ${{ parameters.namespace }}' - pwsh: true - workingDirectory: ${{ parameters.workingDirectory }} - - - task: PowerShell@2 - displayName: 'Deploy Postgres' - inputs: - targetType: 'inline' - script: 'kubectl apply -f ./pgsql-deployment --namespace ${{ parameters.namespace }}' - pwsh: true - workingDirectory: ${{ parameters.workingDirectory }} - - - task: PowerShell@2 - displayName: 'Deploy Nginx Ingress' - inputs: - targetType: 'filePath' - filePath: ${{ parameters.workingDirectory }}/helm-install-nginx-ingress/deploy-ingress-helm.ps1 - arguments: '-HelmReleaseName "event-ingress" -Namespace ${{ parameters.namespace }}' - 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' - inputs: - targetType: 'filePath' - filePath: ${{ parameters.workingDirectory }}/helm-install-cert-manager/deploy-cert-manager-helm.ps1 - arguments: '-HelmReleaseName cert-manager -Namespace ${{ parameters.namespace }}' - 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: - targetType: 'filePath' - filePath: ${{ parameters.workingDirectory }}/scripts/wait-deployments.ps1 - arguments: '-Namespace ${{ parameters.namespace }} - -RabbitRelease event-rabbitmq - -PostgresDeployment postgresdb' - pwsh: true - workingDirectory: ${{ parameters.workingDirectory }} - - - task: PowerShell@2 - displayName: 'Configure Cloudflare DNS' - inputs: - targetType: 'filePath' - filePath: $(System.DefaultWorkingDirectory)/cloudflare/Main.ps1 - 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/configure-platform-stages.yml b/azure-pipelines/templates/configure-platform-stages.yml new file mode 100644 index 00000000..8469a404 --- /dev/null +++ b/azure-pipelines/templates/configure-platform-stages.yml @@ -0,0 +1,177 @@ +parameters: + - name: vmImage + default: 'windows-latest' + type: string + + - name: environment + type: string + + - name: serviceConnection + type: string + + - name: azureResourceGroup + type: string + + - name: kubernetesCluster + type: string + + - name: namespace + type: string + + - name: workingDirectory + displayName: 'Working directory for Platform' + type: string + + - name: cloudflareApiKey + displayName: 'Cloudflare API Token' + type: string + + - name: cloudflareZone + displayName: 'Zone name of DNS in cloudflare (e.g razumovsky.me)' + type: string + + - name: redisPassword + displayName: 'Password for Redis HELM release.' + type: string + + - name: entraIdAuthSecret + type: string + +stages: + - stage: 'Configure_Platform_${{ parameters.environment }}' + displayName: 'Configure_Platform_${{ parameters.environment }}' + jobs: + - deployment: 'Configure_Platform_${{ parameters.environment }}' + displayName: 'Configure_Platform_${{ parameters.environment }}' + pool: + vmImage: ${{ parameters.vmImage }} + environment: ${{ parameters.environment }} + strategy: + runOnce: + deploy: + steps: + - checkout: self + fetchDepth: 0 + + - task: Kubernetes@1 + displayName: 'Kubernetes Login' + inputs: + connectionType: 'Azure Resource Manager' + azureSubscriptionEndpoint: ${{ parameters.serviceConnection }} + azureResourceGroup: ${{ parameters.azureResourceGroup }} + kubernetesCluster: ${{ parameters.kubernetesCluster }} + command: 'login' + + - pwsh: | + choco --version + choco install flux -y + flux -v + displayName: 'Choco install Flux CLI' + + - pwsh: | + kubectl apply -f ./fluxcd/flux-install.yaml + displayName: 'Configure Flux for AKS' + workingDirectory: ${{ parameters.workingDirectory }} + + - pwsh: | + kubectl apply -f ./fluxcd/git-repository.yaml + displayName: 'Configure Flux GitRepository' + workingDirectory: ${{ parameters.workingDirectory }} + + - task: PowerShell@2 + displayName: 'Deploy Namespace' + inputs: + targetType: 'inline' + script: 'kubectl create namespace ${{ parameters.namespace }} --dry-run=client -o yaml | kubectl apply -f -' + pwsh: true + workingDirectory: ${{ parameters.workingDirectory }} + + - task: PowerShell@2 + displayName: 'Deploy Postgres' + inputs: + targetType: 'filePath' + filePath: '${{ parameters.workingDirectory }}/postgres/Deploy-Postgres.ps1' + arguments: '-HelmReleaseName "pgsql-dev" -Namespace "pgsql-dev"' + pwsh: true + workingDirectory: ${{ parameters.workingDirectory }} + + - task: PowerShell@2 + displayName: 'Deploy Nginx Ingress' + inputs: + targetType: 'filePath' + filePath: ${{ parameters.workingDirectory }}/nginx-ingress/Install-Nginx-Ingress.ps1 + arguments: '-HelmReleaseName "nginx-ingress-dev" -Namespace "ing-dev"' + pwsh: true + workingDirectory: ${{ parameters.workingDirectory }} + + - task: PowerShell@2 + displayName: 'Install RabbitMq' + inputs: + targetType: 'filePath' + filePath: ${{ parameters.workingDirectory }}/rabbitmq/Install-RabbitMq.ps1 + arguments: '-RabbitMqNamespace "rabbitmq-dev" -RabbitMqClusterName "rabbitmq-cluster"' + pwsh: true + workingDirectory: ${{ parameters.workingDirectory }} + + - task: PowerShell@2 + displayName: 'Deploy CertManager' + inputs: + targetType: 'filePath' + filePath: ${{ parameters.workingDirectory }}/cert-manager/Install-Cert-Manager.ps1 + arguments: '-HelmReleaseName "cert-manager" -Namespace "cert-manager-dev"' + pwsh: true + workingDirectory: ${{ parameters.workingDirectory }} + + - task: PowerShell@2 + displayName: 'Deploy Redis' + inputs: + targetType: 'filePath' + filePath: ${{ parameters.workingDirectory }}/redis/Install-Redis.ps1 + arguments: '-Namespace "redis-dev" -HelmRelease "redis-server-dev" -Password "${{ parameters.redisPassword }}"' + pwsh: true + workingDirectory: ${{ parameters.workingDirectory }} + + - task: PowerShell@2 + displayName: 'Configure Cloudflare DNS' + inputs: + targetType: 'filePath' + filePath: $(System.DefaultWorkingDirectory)/cloudflare/Main.ps1 + arguments: '-ApiToken ${{ parameters.cloudflareApiKey }} -ZoneName ${{ parameters.cloudflareZone }}' + pwsh: true + workingDirectory: '$(System.DefaultWorkingDirectory)/cloudflare' + + - pwsh: | + helm upgrade --install auth-secrets .\auth-secrets ` + --values .\auth-secrets\values.yaml ` + --set entra_id_auth_secret=${{ parameters.entraIdAuthSecret }} ` + --set namespace=${{ parameters.namespace }} ` + --namespace "${{ parameters.namespace }}" ` + --create-namespace + workingDirectory: $(System.DefaultWorkingDirectory)/helm + displayName: Deploy Auth Secrets + + - pwsh: | + $creds=.\Get-RabbitMq-Credentials.ps1 + $username=$creds["username"] + $password=$creds["password"] + helm upgrade --install consumer-secrets .\consumer-secrets\ ` + --values .\consumer-secrets\values.yaml ` + --set rabbitmq_username="$username" ` + --set rabbitmq_password="$password" ` + --namespace "${{ parameters.namespace }}" ` + --create-namespace + workingDirectory: $(System.DefaultWorkingDirectory)/helm + displayName: Deploy Consumer Secrets + + - pwsh: | + $creds=.\Get-RabbitMq-Credentials.ps1 + $username=$creds["username"] + $password=$creds["password"] + helm upgrade --install sender-secrets .\sender-secrets\ ` + --values .\sender-secrets\values.yaml ` + --set rabbitmq_username="$username" ` + --set rabbitmq_password="$password" ` + --namespace "event-triangle-dev" ` + --create-namespace + workingDirectory: $(System.DefaultWorkingDirectory)/helm + displayName: Deploy Sender Secrets diff --git a/azure-pipelines/templates/docker-build-push-jobs.yml b/azure-pipelines/templates/docker-build-push-jobs.yml index 2a341592..d4fda61b 100644 --- a/azure-pipelines/templates/docker-build-push-jobs.yml +++ b/azure-pipelines/templates/docker-build-push-jobs.yml @@ -23,6 +23,7 @@ parameters: - name: unitTestsProjectPath displayName: 'Unit tests project path' + default: '' type: string - name: shouldRunUnitTests @@ -76,11 +77,6 @@ parameters: default: 'https://auth.eventtriangle.razumovsky.me/' type: string - - name: sonarCloudEnabled - displayName: 'Is SonarCloud scan enabled' - default: false - type: boolean - jobs: - job: ${{ parameters.JobName }} displayName: ${{ parameters.JobName }} @@ -103,6 +99,28 @@ jobs: Action: '##vso[build.updatebuildnumber]' BuildVersion: $(version_step.semVer) + - pwsh: | + Write-Host "=== ENV VARIABLES ===" + Get-ChildItem Env: | Sort-Object Name + + Write-Host "=== PIPELINE VARIABLES ===" + Write-Host "FullSemVer: $(version_step.FullSemVer)" + Write-Host "SemVer: $(version_step.SemVer)" + Write-Host "ShortSha: $(version_step.ShortSha)" + + Write-Host "=== PIPELINE VARIABLES ===" + Write-Host "Build Source branch: $env:BUILD_SOURCEBRANCHNAME" + displayName: Debug environment + + - task: PowerShell@2 + displayName: 'Debug branch condition' + condition: ne(variables['Build.SourceBranchName'], 'main') + inputs: + targetType: 'inline' + script: | + Write-Host "Running because branch is NOT main" + Write-Host "Branch: $env:BUILD_SOURCEBRANCHNAME" + - task: DotNetCoreCLI@2 displayName: 'Dotnet restore' inputs: @@ -111,18 +129,18 @@ jobs: arguments: '--verbosity minimal' nugetConfigPath: 'nuget.config' - - ${{ if eq(parameters.sonarCloudEnabled, true) }}: - - task: SonarCloudPrepare@4 - inputs: - SonarCloud: SonarCloud_Service_Connection - organization: event-triangle - scannerMode: dotnet - projectKey: event-triangle-api - projectName: eventtriangleapi - extraProperties: | - sonar.cs.vstest.reportsPaths=$(Agent.TempDirectory)/**/*.trx - sonar.cs.opencover.reportsPaths=$(Agent.TempDirectory)/**/*opencover.xml - sonar.exclusions=**/Properties/**, **/bin/**, **/obj/**, **/Migrations/** + - task: SonarCloudPrepare@4 + condition: eq(variables['Build.SourceBranchName'], 'main') + inputs: + SonarCloud: SonarCloud_Service_Connection + organization: event-triangle + scannerMode: dotnet + projectKey: event-triangle-api + projectName: eventtriangleapi + extraProperties: | + sonar.cs.vstest.reportsPaths=$(Agent.TempDirectory)/**/*.trx + sonar.cs.opencover.reportsPaths=$(Agent.TempDirectory)/**/*opencover.xml + sonar.exclusions=**/Properties/**, **/bin/**, **/obj/**, **/Migrations/** - task: DotNetCoreCLI@2 displayName: 'Build solution' @@ -131,30 +149,30 @@ jobs: projects: '${{ parameters.solution }}' arguments: '-c ${{ parameters.buildConfiguration }} -p:Version=$(version_step.semVer) --no-restore' - - ${{ if eq(parameters.sonarCloudEnabled, true) }}: - - task: SonarCloudAnalyze@4 - inputs: {} - - - ${{ if eq(parameters.sonarCloudEnabled, true) }}: - - task: SonarCloudPublish@4 - inputs: - pollingTimeoutSec: "300" - - - ${{ if eq(parameters.shouldRunUnitTests, true) }}: - - task: DotnetCoreCLI@2 - displayName: 'Run unit tests' - inputs: - command: 'test' - projects: '${{ parameters.unitTestsProjectPath }}' - arguments: '--no-build --configuration ${{ parameters.buildConfiguration }} --collect "Code Coverage"' - - - ${{ if eq(parameters.shouldRunIntegrationTests, true) }}: - - task: DotNetCoreCLI@2 - displayName: 'Run integration tests' - inputs: - command: 'test' - projects: '${{ parameters.integrationTestsProjectPath }}' - arguments: '--no-build --configuration ${{ parameters.buildConfiguration }} --collect "Code Coverage"' + - task: SonarCloudAnalyze@4 + condition: and(succeeded(), eq(variables['Build.SourceBranchName'], 'main')) + inputs: {} + + - task: SonarCloudPublish@4 + condition: and(succeeded(), eq(variables['Build.SourceBranchName'], 'main')) + inputs: + pollingTimeoutSec: "300" + + - task: DotnetCoreCLI@2 + displayName: 'Run unit tests' + condition: and(succeeded(), eq(${{ parameters.shouldRunUnitTests }}, true)) + inputs: + command: 'test' + projects: '${{ parameters.unitTestsProjectPath }}' + arguments: '--no-build --configuration ${{ parameters.buildConfiguration }} --collect "Code Coverage"' + + - task: DotNetCoreCLI@2 + displayName: 'Run integration tests' + condition: and(succeeded(), eq(${{ parameters.shouldRunIntegrationTests }}, true)) + inputs: + command: 'test' + projects: '${{ parameters.integrationTestsProjectPath }}' + arguments: '--no-build --configuration ${{ parameters.buildConfiguration }} --collect "Code Coverage"' - task: PowerShell@2 displayName: 'Build Docker Image' @@ -167,7 +185,8 @@ jobs: -DockerBuildParameterUrl ${{ parameters.dockerBuildParameterUrl }} -DockerfilePath ${{ parameters.dockerfilePath }} -GitVersion $(version_step.semVer) - -WorkingDirectory ${{ parameters.workingDirectoryForDocker }}" + -WorkingDirectory ${{ parameters.workingDirectoryForDocker }} + -CommitSha $(version_step.ShortSha)" errorActionPreference: 'stop' pwsh: true @@ -179,15 +198,17 @@ jobs: repository: ${{ parameters.dockerRegistryUrl }}/${{ parameters.imageRepository }} tags: | $(version_step.semVer) + $(version_step.semVer)-$(version_step.ShortSha) latest - - ${{ if eq(parameters.shouldPushToAcr, true) }}: - - task: Docker@2 - displayName: 'Push to ACR' - inputs: - command: push - containerRegistry: ${{ parameters.acrServiceConnection }} - repository: ${{ parameters.imageRepository }} - tags: | - $(version_step.semVer) - latest + - task: Docker@2 + displayName: 'Push to ACR' + condition: and(succeeded(), eq(${{ parameters.shouldPushToAcr }}, true)) + inputs: + command: push + containerRegistry: ${{ parameters.acrServiceConnection }} + repository: ${{ parameters.imageRepository }} + tags: | + $(version_step.semVer) + $(version_step.semVer)-$(version_step.ShortSha) + latest diff --git a/azure-pipelines/templates/terraform-apply-stages.yml b/azure-pipelines/templates/terraform-apply-stages.yml index 6991c4c6..8b26c798 100644 --- a/azure-pipelines/templates/terraform-apply-stages.yml +++ b/azure-pipelines/templates/terraform-apply-stages.yml @@ -114,7 +114,7 @@ stages: workingDirectory: ${{ parameters.workingDirectory }} - powershell: | - terraform apply -auto-approve main.tfplan + terraform apply -parallelism=15 -auto-approve "main.tfplan" displayName: 'Terraform Apply' workingDirectory: ${{ parameters.workingDirectory }} env: diff --git a/cloudflare/Get-CloudflareDnsRecords.ps1 b/cloudflare/Get-CloudflareDnsRecords.ps1 index 060db7eb..10c74104 100644 --- a/cloudflare/Get-CloudflareDnsRecords.ps1 +++ b/cloudflare/Get-CloudflareDnsRecords.ps1 @@ -9,7 +9,7 @@ param ( $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" ) +$response = $( curl -s -S $url -H "Authorization: Bearer $ApiToken" -H "Content-Type: application/json" ) # Parse the JSON response $json = $response | ConvertFrom-Json diff --git a/cloudflare/Get-CloudflareZoneId.ps1 b/cloudflare/Get-CloudflareZoneId.ps1 index e1042ebf..feae9bb3 100644 --- a/cloudflare/Get-CloudflareZoneId.ps1 +++ b/cloudflare/Get-CloudflareZoneId.ps1 @@ -11,7 +11,7 @@ $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" ) +$response = $( curl -s -S $url -H "Authorization: Bearer $ApiToken" -H "Content-Type: application/json" ) # Parse the JSON response $json = $response | ConvertFrom-Json diff --git a/cloudflare/Get-NewDnsEntries.ps1 b/cloudflare/Get-NewDnsEntries.ps1 index 91f2a96d..3fec7e6d 100644 --- a/cloudflare/Get-NewDnsEntries.ps1 +++ b/cloudflare/Get-NewDnsEntries.ps1 @@ -1,5 +1,5 @@ -$ingressService = $( kubectl get service "event-ingress-ingress-nginx-controller" -n "event-triangle" -o json ) | ConvertFrom-Json +$ingressService = $( kubectl get service "nginx-ingress-dev-ingress-nginx-controller" -n "ing-dev" -o json ) | ConvertFrom-Json $ingressPublicIp = $ingressService.status.loadBalancer.ingress[0].ip $dnsRecords = @{} diff --git a/cloudflare/Main.ps1 b/cloudflare/Main.ps1 index 38f9f70b..11e1feb6 100644 --- a/cloudflare/Main.ps1 +++ b/cloudflare/Main.ps1 @@ -9,10 +9,10 @@ param ( # Set error handling and preferences $ErrorActionPreference = "Stop" -Write-Host "Starting Cloudflare DNS Records Update Script..." -ForegroundColor Cyan +Write-Host "Starting Cloudflare DNS Records Update Script..." # Step 1: Get Zone ID -Write-Host "Fetching Zone ID for Zone Name: $ZoneName..." -ForegroundColor Yellow +Write-Host "Fetching Zone ID for Zone Name: $ZoneName..." $zoneId = $(./Get-CloudflareZoneId.ps1 -ApiToken $ApiToken -ZoneName $ZoneName) if (-not $zoneId) { @@ -20,10 +20,10 @@ if (-not $zoneId) { exit 1 } -Write-Host "Zone ID Retrieved: $zoneId" -ForegroundColor Green +Write-Host "Zone ID Retrieved: $zoneId" # Step 2: Get DNS Records -Write-Host "Fetching existing DNS records for Zone ID: $zoneId..." -ForegroundColor Yellow +Write-Host "Fetching existing DNS records for Zone ID: $zoneId..." $dnsRecords = $(.\Get-CloudflareDnsRecords.ps1 -ApiToken $ApiToken -ZoneId "$zoneId") if (-not $dnsRecords -or -not ($dnsRecords -is [hashtable])) { @@ -31,10 +31,10 @@ if (-not $dnsRecords -or -not ($dnsRecords -is [hashtable])) { exit 1 } -Write-Host "DNS Records Retrieved: $($dnsRecords.Count) records found." -ForegroundColor Green +Write-Host "DNS Records Retrieved: $($dnsRecords.Count) records found." # Step 3: Get New DNS Entries -Write-Host "Fetching new DNS entries to update..." -ForegroundColor Yellow +Write-Host "Fetching new DNS entries to update..." $newDnsEntries = $(.\Get-NewDnsEntries.ps1) if (-not $newDnsEntries -or -not ($newDnsEntries -is [hashtable])) { @@ -42,23 +42,23 @@ if (-not $newDnsEntries -or -not ($newDnsEntries -is [hashtable])) { exit 1 } -Write-Host "New DNS Entries Retrieved: $($newDnsEntries.Count) entries to process." -ForegroundColor Green +Write-Host "New DNS Entries Retrieved: $($newDnsEntries.Count) entries to process." # Step 4: Process Each New DNS Entry -Write-Host "Starting to process new DNS entries..." -ForegroundColor Cyan +Write-Host "Starting to process new DNS entries..." foreach ($entry in $newDnsEntries.GetEnumerator()) { $dnsName = $entry.Name $ipAddress = $entry.Value - Write-Host "`nProcessing Entry: $dnsName => $ipAddress" -ForegroundColor Cyan + Write-Host "`nProcessing Entry: $dnsName => $ipAddress" # 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 + Write-Host "Found existing DNS record for $dnsName. Record ID: $recordId" + Write-Host "Updating DNS record for $dnsName with IP Address: $ipAddress" # Update the DNS record try { @@ -68,7 +68,7 @@ foreach ($entry in $newDnsEntries.GetEnumerator()) { -RecordId $recordId ` -IpAddress $ipAddress - Write-Host "Successfully updated DNS record for $dnsName." -ForegroundColor Green + Write-Host "Successfully updated DNS record for $dnsName => $ipAddress" -ForegroundColor Green } catch { Write-Error "Failed to update DNS record for $dnsName. Error: $_" } diff --git a/cloudflare/Update-CloudflareDnsRecord.ps1 b/cloudflare/Update-CloudflareDnsRecord.ps1 index 64755543..b5a3656f 100644 --- a/cloudflare/Update-CloudflareDnsRecord.ps1 +++ b/cloudflare/Update-CloudflareDnsRecord.ps1 @@ -31,7 +31,7 @@ $body = @{ } | ConvertTo-Json -Depth 4 # Perform the API request -$response = curl $url ` +$response = curl -s -S $url ` -X PATCH ` -H "Authorization: Bearer $ApiToken" ` -H "Content-Type: application/json" ` @@ -42,13 +42,13 @@ $responseJson = $response | ConvertFrom-Json # Check the response if ($responseJson.success -eq $true) { - Write-Host "DNS record updated successfully." - Write-Host "Response: $response" + Write-Host "DNS record updated successfully." -ForegroundColor Green + exit 0 } else { - Write-Host "Failed to update DNS record." - Write-Host "Response: $( $response )" + Write-Host "Failed to update DNS record." -ForegroundColor Red + exit 1 } #.\Update-CloudflareDnsRecord.ps1 -ApiToken $env:CLOUDFLARE_API_KEY ` diff --git a/helm/Get-RabbitMq-Credentials.ps1 b/helm/Get-RabbitMq-Credentials.ps1 new file mode 100644 index 00000000..d5a44a10 --- /dev/null +++ b/helm/Get-RabbitMq-Credentials.ps1 @@ -0,0 +1,29 @@ +$ErrorActionPreference = "Stop" + +$InitialLocation = Get-Location + +Write-Host "Setting location to PSScriptRoot ..." + +Set-Location $PSScriptRoot + +$Username = kubectl get secret rabbitmq-cluster-default-user -n rabbitmq-dev -o jsonpath="{.data.username}" + +Write-Host "Successfully retrieved username value." + +$Password = kubectl get secret rabbitmq-cluster-default-user -n rabbitmq-dev -o jsonpath="{.data.password}" + +Write-Host "Successfully retrieved password value." + +$UsernameDecode = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Username)) +$PasswordDecode = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Password)) + +$Creds = @{} + +$Creds["username"] = $UsernameDecode +$Creds["password"] = $PasswordDecode + +Write-Host "Changing location to initial ..." + +Set-Location $InitialLocation + +return $Creds \ No newline at end of file diff --git a/helm/auth-service-chart/.helmignore b/helm/auth-secrets/.helmignore similarity index 100% rename from helm/auth-service-chart/.helmignore rename to helm/auth-secrets/.helmignore diff --git a/helm/auth-secrets/Chart.yaml b/helm/auth-secrets/Chart.yaml new file mode 100644 index 00000000..d7fd7497 --- /dev/null +++ b/helm/auth-secrets/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: auth-app +description: A Helm chart for auth secrets. +type: application +version: 1.0.0 +appVersion: "1.0.0" diff --git a/helm/auth-secrets/templates/secrets.yaml b/helm/auth-secrets/templates/secrets.yaml new file mode 100644 index 00000000..11640ede --- /dev/null +++ b/helm/auth-secrets/templates/secrets.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }} + namespace: {{ .Values.namespace }} +type: Opaque +stringData: + EVENT_TRIANGLE_AD_CLIENT_SECRET: {{ .Values.entra_id_auth_secret | quote }} + AuthDatabaseConnectionString: "Server={{ .Values.postgres_host }};User Id={{ .Values.postgres_user }};Password={{ .Values.postgres_password }};Database=AuthorizationDb;" + RabbitMqHost: {{ .Values.rabbit_mq_host | quote }} + RedisUrl: {{ .Values.redis_url | quote }} + RedisPassword: {{ .Values.redis_password | quote }} diff --git a/helm/auth-secrets/values.yaml b/helm/auth-secrets/values.yaml new file mode 100644 index 00000000..f15c6e4b --- /dev/null +++ b/helm/auth-secrets/values.yaml @@ -0,0 +1,10 @@ +namespace: event-triangle-dev + +entra_id_auth_secret: "My_3nt4ra_s3cr3t" +rabbit_mq_host: "rabbitmq-cluster.rabbitmq-dev.svc" +redis_url: "redis-server-dev-master.redis-dev.svc" +redis_password: "Rx9nJ781GMe5" + +postgres_host: "pgsql-dev-service.pgsql-dev.svc" +postgres_user: "postgres" +postgres_password: "s8SefXkZZlqd" diff --git a/helm/auth-service-chart/Chart.yaml b/helm/auth-service-chart/Chart.yaml deleted file mode 100644 index 34c693ac..00000000 --- a/helm/auth-service-chart/Chart.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v2 -name: event-triangle-auth -description: A Helm chart for event-triangle-auth -type: application -version: 1.0.0 -appVersion: "1.0.0" diff --git a/helm/auth-service-chart/templates/certificate-issuer.yaml b/helm/auth-service-chart/templates/certificate-issuer.yaml deleted file mode 100644 index e1df9079..00000000 --- a/helm/auth-service-chart/templates/certificate-issuer.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: ClusterIssuer -metadata: - name: letsencrypt-prod -spec: - acme: - server: https://acme-v02.api.letsencrypt.org/directory - email: kolosovp94@gmail.com - privateKeySecretRef: - name: letsencrypt-prod - solvers: - - http01: - ingress: - class: nginx diff --git a/helm/auth-service-chart/templates/configmap.yaml b/helm/auth-service-chart/templates/configmap.yaml deleted file mode 100644 index 24878199..00000000 --- a/helm/auth-service-chart/templates/configmap.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ .Release.Name }}-configmap - namespace: {{ .Values.namespace }} - labels: - app: {{ .Release.Name }} -data: -{{- range $key, $value := .Values.configmap.data }} - {{ $key }}: "{{ $value }}" -{{- end }} diff --git a/helm/auth-service-chart/templates/deployment.yaml b/helm/auth-service-chart/templates/deployment.yaml deleted file mode 100644 index adec7965..00000000 --- a/helm/auth-service-chart/templates/deployment.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Release.Name }}-deployment - namespace: {{ .Values.namespace }} -spec: - replicas: {{ .Values.replicaCount }} - selector: - matchLabels: - app: {{ .Release.Name }} - template: - metadata: - labels: - app: {{ .Release.Name }} - spec: - containers: - - name: {{ .Release.Name }} - image: {{ .Values.image.repository }}:{{ .Values.image.tag }} - imagePullPolicy: {{ .Values.image.pullPolicy }} - ports: - {{- range .Values.ports }} - - containerPort: {{ .containerPort }} - {{- end }} - env: - - name: ASPNETCORE_ENVIRONMENT - value: "Docker" - {{- range .Values.env }} - - name: {{ .name }} - valueFrom: - {{ .type }}: - name: {{ .refName }} - key: {{ .key }} - {{- end }} diff --git a/helm/auth-service-chart/templates/ingress.yaml b/helm/auth-service-chart/templates/ingress.yaml deleted file mode 100644 index 7d684abd..00000000 --- a/helm/auth-service-chart/templates/ingress.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: ing-event-triangle-auth - namespace: event-triangle - annotations: - nginx.ingress.kubernetes.io/enable-cors: 'true' - nginx.ingress.kubernetes.io/cors-allow-headers: 'Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Accept-Language' - nginx.ingress.kubernetes.io/cors-max-age: '600' - nginx.ingress.kubernetes.io/proxy-body-size: '12m' - nginx.ingress.kubernetes.io/rewrite-target: '/' - nginx.ingress.kubernetes.io/use-regex: 'true' - kubernetes.io/tls-acme: 'true' - nginx.ingress.kubernetes.io/ssl-redirect: 'true' - cert-manager.io/cluster-issuer: letsencrypt-prod -spec: - ingressClassName: nginx - tls: - - hosts: - - auth-eventtriangle.razumovsky.me - secretName: razumovsky-me-tls - rules: - - host: auth-eventtriangle.razumovsky.me - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: {{ .Release.Name }}-service - port: - number: 80 diff --git a/helm/auth-service-chart/templates/service.yaml b/helm/auth-service-chart/templates/service.yaml deleted file mode 100644 index 09c4af87..00000000 --- a/helm/auth-service-chart/templates/service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ .Release.Name }}-service - namespace: {{ .Values.namespace }} -spec: - selector: - app: {{ .Release.Name }} - ports: - {{- range .Values.service.ports }} - - name: {{ .name }} - protocol: {{ .protocol }} - port: {{ .port }} - targetPort: {{ .targetPort }} - {{- end }} - type: {{ .Values.service.type }} diff --git a/helm/auth-service-chart/values.yaml b/helm/auth-service-chart/values.yaml deleted file mode 100644 index ab1dcc2d..00000000 --- a/helm/auth-service-chart/values.yaml +++ /dev/null @@ -1,48 +0,0 @@ -namespace: event-triangle -replicaCount: 1 - -image: - repository: kaminome/auth-service - tag: latest - pullPolicy: Always - -ports: - - containerPort: 80 - - containerPort: 81 - -env: - - name: EVENT_TRIANGLE_AD_CLIENT_SECRET - type: secretKeyRef - refName: connection-creds - key: EVENT_TRIANGLE_AD_CLIENT_SECRET - - - name: DatabaseConnectionString - type: secretKeyRef - refName: connection-creds - key: AuthDatabaseConnectionString - - - name: RedisPassword - type: secretKeyRef - refName: connection-creds - key: RedisPassword - - - name: RedisUrl - type: secretKeyRef - refName: connection-creds - key: RedisUrl - -service: - type: ClusterIP - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 8080 - - name: grpc - protocol: TCP - port: 81 - targetPort: 81 - -configmap: - data: - ASPNETCORE_ENVIRONMENT: "Docker" diff --git a/helm/consumer-service-chart/.helmignore b/helm/consumer-secrets/.helmignore similarity index 100% rename from helm/consumer-service-chart/.helmignore rename to helm/consumer-secrets/.helmignore diff --git a/helm/consumer-secrets/Chart.yaml b/helm/consumer-secrets/Chart.yaml new file mode 100644 index 00000000..335aa8c5 --- /dev/null +++ b/helm/consumer-secrets/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: consumer-app +description: A Helm chart for consumer secrets +type: application +version: 1.0.0 +appVersion: "1.0.0" diff --git a/helm/consumer-secrets/templates/secrets.yaml b/helm/consumer-secrets/templates/secrets.yaml new file mode 100644 index 00000000..01f0e449 --- /dev/null +++ b/helm/consumer-secrets/templates/secrets.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }} + namespace: {{ .Values.namespace }} +type: Opaque +stringData: + ConsumerDatabaseConnectionString: "Server={{ .Values.postgres_host }};User Id={{ .Values.postgres_user }};Password={{ .Values.postgres_password }};Database=ConsumerDb;" + RabbitMqHost: {{ .Values.rabbit_mq_host | quote }} + RabbitMqUsername: {{ .Values.rabbitmq_username | quote }} + RabbitMqPassword: {{ .Values.rabbitmq_password | quote }} diff --git a/helm/consumer-secrets/values.yaml b/helm/consumer-secrets/values.yaml new file mode 100644 index 00000000..c16fa7e2 --- /dev/null +++ b/helm/consumer-secrets/values.yaml @@ -0,0 +1,10 @@ +namespace: event-triangle-dev + +rabbit_mq_host: "rabbitmq-cluster.rabbitmq-dev.svc" +rabbitmq_username: "rabbitmq-user" +rabbitmq_password: "myPa55w0rd" + + +postgres_host: "pgsql-dev-service.pgsql-dev.svc" +postgres_user: "postgres" +postgres_password: "s8SefXkZZlqd" diff --git a/helm/consumer-service-chart/Chart.yaml b/helm/consumer-service-chart/Chart.yaml deleted file mode 100644 index 33ce1b2c..00000000 --- a/helm/consumer-service-chart/Chart.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v2 -name: event-triangle-consumer -description: A Helm chart for event-triangle-consumer -type: application -version: 1.0.0 -appVersion: "1.0.0" diff --git a/helm/consumer-service-chart/templates/deployment.yaml b/helm/consumer-service-chart/templates/deployment.yaml deleted file mode 100644 index 9afab752..00000000 --- a/helm/consumer-service-chart/templates/deployment.yaml +++ /dev/null @@ -1,44 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Release.Name }}-deployment - namespace: {{ .Values.namespace }} -spec: - replicas: {{ .Values.replicaCount }} - selector: - matchLabels: - app: {{ .Release.Name }} - template: - metadata: - labels: - app: {{ .Release.Name }} - spec: - containers: - - name: {{ .Release.Name }} - image: {{ .Values.image.repository }}:{{ .Values.image.tag }} - imagePullPolicy: {{ .Values.image.pullPolicy }} - ports: - - containerPort: {{ .Values.ports.containerPort }} - env: - - name: ASPNETCORE_ENVIRONMENT - value: "Docker" - - name: RabbitMqHost - valueFrom: - secretKeyRef: - name: {{ .Values.env.RabbitMqHost.secretName }} - key: {{ .Values.env.RabbitMqHost.key }} - - name: RabbitMqUsername - valueFrom: - secretKeyRef: - name: {{ .Values.env.RabbitMqUsername.secretName }} - key: {{ .Values.env.RabbitMqUsername.key }} - - name: RabbitMqPassword - valueFrom: - secretKeyRef: - name: {{ .Values.env.RabbitMqPassword.secretName }} - key: {{ .Values.env.RabbitMqPassword.key }} - - name: DatabaseConnectionString - valueFrom: - secretKeyRef: - name: {{ .Values.env.DatabaseConnectionString.secretName }} - key: {{ .Values.env.DatabaseConnectionString.key }} diff --git a/helm/consumer-service-chart/templates/service.yaml b/helm/consumer-service-chart/templates/service.yaml deleted file mode 100644 index 78c04805..00000000 --- a/helm/consumer-service-chart/templates/service.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: event-triangle-consumer-service - namespace: {{ .Values.namespace }} -spec: - selector: - app: {{ .Release.Name }} - ports: - - protocol: TCP - port: {{ .Values.ports.servicePort }} - targetPort: {{ .Values.ports.targetPort }} - type: ClusterIP diff --git a/helm/consumer-service-chart/values.yaml b/helm/consumer-service-chart/values.yaml deleted file mode 100644 index 8223e598..00000000 --- a/helm/consumer-service-chart/values.yaml +++ /dev/null @@ -1,29 +0,0 @@ -namespace: event-triangle -replicaCount: 1 - -image: - repository: kaminome/consumer-service - tag: latest - pullPolicy: Always - -ports: - containerPort: 80 - servicePort: 80 - targetPort: 8080 - -env: - RabbitMqHost: - secretName: event-rabbitmq-default-user - key: host - - RabbitMqUsername: - secretName: event-rabbitmq-default-user - key: username - - RabbitMqPassword: - secretName: event-rabbitmq-default-user - key: password - - DatabaseConnectionString: - secretName: connection-creds - key: ConsumerDatabaseConnectionString diff --git a/helm/sender-service-chart/.helmignore b/helm/sender-secrets/.helmignore similarity index 100% rename from helm/sender-service-chart/.helmignore rename to helm/sender-secrets/.helmignore diff --git a/helm/sender-secrets/Chart.yaml b/helm/sender-secrets/Chart.yaml new file mode 100644 index 00000000..b59a0030 --- /dev/null +++ b/helm/sender-secrets/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: sender-app +description: A Helm chart for sender secrets +type: application +version: 1.0.0 +appVersion: "1.0.0" diff --git a/helm/sender-secrets/templates/secrets.yaml b/helm/sender-secrets/templates/secrets.yaml new file mode 100644 index 00000000..74d95946 --- /dev/null +++ b/helm/sender-secrets/templates/secrets.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }} + namespace: {{ .Values.namespace }} +type: Opaque +stringData: + SenderDatabaseConnectionString: "Server={{ .Values.postgres_host }};User Id={{ .Values.postgres_user }};Password={{ .Values.postgres_password }};Database=SenderDb;" + RabbitMqHost: {{ .Values.rabbit_mq_host | quote }} + RabbitMqUsername: {{ .Values.rabbitmq_username | quote }} + RabbitMqPassword: {{ .Values.rabbitmq_password | quote }} diff --git a/helm/sender-secrets/values.yaml b/helm/sender-secrets/values.yaml new file mode 100644 index 00000000..c16fa7e2 --- /dev/null +++ b/helm/sender-secrets/values.yaml @@ -0,0 +1,10 @@ +namespace: event-triangle-dev + +rabbit_mq_host: "rabbitmq-cluster.rabbitmq-dev.svc" +rabbitmq_username: "rabbitmq-user" +rabbitmq_password: "myPa55w0rd" + + +postgres_host: "pgsql-dev-service.pgsql-dev.svc" +postgres_user: "postgres" +postgres_password: "s8SefXkZZlqd" diff --git a/helm/sender-service-chart/Chart.yaml b/helm/sender-service-chart/Chart.yaml deleted file mode 100644 index 7c8265b9..00000000 --- a/helm/sender-service-chart/Chart.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v2 -name: event-triangle-sender -description: A Helm chart for event-triangle-sender -type: application -version: 1.0.0 -appVersion: "1.0.0" diff --git a/helm/sender-service-chart/templates/deployment.yaml b/helm/sender-service-chart/templates/deployment.yaml deleted file mode 100644 index a4a763e2..00000000 --- a/helm/sender-service-chart/templates/deployment.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Release.Name }}-deployment - namespace: {{ .Values.namespace }} -spec: - replicas: {{ .Values.replicaCount }} - selector: - matchLabels: - app: {{ .Release.Name }} - template: - metadata: - labels: - app: {{ .Release.Name }} - spec: - containers: - - name: {{ .Release.Name }} - image: {{ .Values.image.repository }}:{{ .Values.image.tag }} - imagePullPolicy: {{ .Values.image.pullPolicy }} - ports: - {{- range .Values.service.ports }} - - containerPort: {{ .targetPort }} - {{- end }} - env: - - name: ASPNETCORE_ENVIRONMENT - value: "Docker" - {{- range .Values.env }} - - name: {{ .name }} - valueFrom: - {{ .type }}: - name: {{ .refName }} - key: {{ .key }} - {{- end }} diff --git a/helm/sender-service-chart/templates/service.yaml b/helm/sender-service-chart/templates/service.yaml deleted file mode 100644 index 262f6415..00000000 --- a/helm/sender-service-chart/templates/service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ .Release.Name }}-service - namespace: {{ .Values.namespace }} -spec: - selector: - app: {{ .Release.Name }} - ports: - {{- range .Values.service.ports }} - - name: {{ .name }} - protocol: TCP - port: {{ .port }} - targetPort: {{ .targetPort }} - {{- end }} - type: {{ .Values.service.type }} diff --git a/helm/sender-service-chart/values.yaml b/helm/sender-service-chart/values.yaml deleted file mode 100644 index 9f82d55b..00000000 --- a/helm/sender-service-chart/values.yaml +++ /dev/null @@ -1,37 +0,0 @@ -replicaCount: 1 -namespace: event-triangle -image: - repository: kaminome/sender-service - tag: latest - pullPolicy: Always - -service: - ports: - - name: http - port: 80 - targetPort: 80 - - name: grpc - port: 81 - targetPort: 81 - type: ClusterIP - -env: - - name: RabbitMqHost - type: secretKeyRef - refName: event-rabbitmq-default-user - key: host - - - name: RabbitMqUsername - type: secretKeyRef - refName: event-rabbitmq-default-user - key: username - - - name: RabbitMqPassword - type: secretKeyRef - refName: event-rabbitmq-default-user - key: password - - - name: DatabaseConnectionString - type: secretKeyRef - refName: connection-creds - key: SenderDatabaseConnectionString diff --git a/nuget.config b/nuget.config index 4c0db7eb..31f07936 100644 --- a/nuget.config +++ b/nuget.config @@ -1,4 +1,4 @@ - + diff --git a/platform/helm-install-cert-manager/deploy-cert-manager-helm.ps1 b/platform/cert-manager/Install-Cert-Manager.ps1 similarity index 75% rename from platform/helm-install-cert-manager/deploy-cert-manager-helm.ps1 rename to platform/cert-manager/Install-Cert-Manager.ps1 index 3b9fc4b2..25ff1ed9 100644 --- a/platform/helm-install-cert-manager/deploy-cert-manager-helm.ps1 +++ b/platform/cert-manager/Install-Cert-Manager.ps1 @@ -21,10 +21,10 @@ helm repo add jetstack https://charts.jetstack.io helm repo update Write-Output "Applying cert-manager custom resource definitions (CRDs) ..." -kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.12.0/cert-manager.crds.yaml +kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/latest/download/cert-manager.crds.yaml Write-Output "Installing cert-manager helm chart ..." -helm install $HelmReleaseName jetstack/cert-manager --namespace $Namespace +helm upgrade --install $HelmReleaseName jetstack/cert-manager --namespace $Namespace --create-namespace # example call: -# .\deploy-cert-manager-helm.ps1 -HelmReleaseName "cert-manager" -Namespace "event-triangle" \ No newline at end of file +# .\cert-manager\Install-Cert-Manager.ps1 -HelmReleaseName "cert-manager" -Namespace "cert-manager-dev" diff --git a/platform/fluxcd/flux-install.yaml b/platform/fluxcd/flux-install.yaml new file mode 100644 index 00000000..ba2b2068 --- /dev/null +++ b/platform/fluxcd/flux-install.yaml @@ -0,0 +1,6433 @@ +--- +# This manifest was generated by flux. DO NOT EDIT. +# Flux Version: v2.8.5 +# Components: source-controller,kustomize-controller,helm-controller,notification-controller +# Generated by: flux install --namespace flux-system --export | Out-File "flux-install.yaml" +apiVersion: v1 +kind: Namespace +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + pod-security.kubernetes.io/warn: restricted + pod-security.kubernetes.io/warn-version: latest + name: flux-system +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: allow-egress + namespace: flux-system +spec: + egress: + - {} + ingress: + - from: + - podSelector: {} + podSelector: {} + policyTypes: + - Ingress + - Egress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: allow-scraping + namespace: flux-system +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 8080 + protocol: TCP + podSelector: {} + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: allow-webhooks + namespace: flux-system +spec: + ingress: + - from: + - namespaceSelector: {} + podSelector: + matchLabels: + app: notification-controller + policyTypes: + - Ingress +--- +apiVersion: v1 +kind: ResourceQuota +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: critical-pods-flux-system + namespace: flux-system +spec: + hard: + pods: "1000" + scopeSelector: + matchExpressions: + - operator: In + scopeName: PriorityClass + values: + - system-node-critical + - system-cluster-critical +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: crd-controller-flux-system +rules: +- apiGroups: + - source.toolkit.fluxcd.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - kustomize.toolkit.fluxcd.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - helm.toolkit.fluxcd.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - notification.toolkit.fluxcd.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - image.toolkit.fluxcd.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - source.extensions.fluxcd.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - "" + resources: + - namespaces + - secrets + - configmaps + - serviceaccounts + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - update + - patch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - serviceaccounts/token + verbs: + - create +- nonResourceURLs: + - /livez/ping + verbs: + - head +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + name: flux-edit-flux-system +rules: +- apiGroups: + - notification.toolkit.fluxcd.io + - source.toolkit.fluxcd.io + - source.extensions.fluxcd.io + - helm.toolkit.fluxcd.io + - image.toolkit.fluxcd.io + - kustomize.toolkit.fluxcd.io + resources: + - '*' + verbs: + - create + - delete + - deletecollection + - patch + - update +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + rbac.authorization.k8s.io/aggregate-to-admin: "true" + rbac.authorization.k8s.io/aggregate-to-edit: "true" + rbac.authorization.k8s.io/aggregate-to-view: "true" + name: flux-view-flux-system +rules: +- apiGroups: + - notification.toolkit.fluxcd.io + - source.toolkit.fluxcd.io + - source.extensions.fluxcd.io + - helm.toolkit.fluxcd.io + - image.toolkit.fluxcd.io + - kustomize.toolkit.fluxcd.io + resources: + - '*' + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: cluster-reconciler-flux-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: kustomize-controller + namespace: flux-system +- kind: ServiceAccount + name: helm-controller + namespace: flux-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: crd-controller-flux-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: crd-controller-flux-system +subjects: +- kind: ServiceAccount + name: kustomize-controller + namespace: flux-system +- kind: ServiceAccount + name: helm-controller + namespace: flux-system +- kind: ServiceAccount + name: source-controller + namespace: flux-system +- kind: ServiceAccount + name: notification-controller + namespace: flux-system +- kind: ServiceAccount + name: image-reflector-controller + namespace: flux-system +- kind: ServiceAccount + name: image-automation-controller + namespace: flux-system +- kind: ServiceAccount + name: source-watcher + namespace: flux-system +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: buckets.source.toolkit.fluxcd.io +spec: + group: source.toolkit.fluxcd.io + names: + kind: Bucket + listKind: BucketList + plural: buckets + singular: bucket + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.endpoint + name: Endpoint + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: Bucket is the Schema for the buckets API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + BucketSpec specifies the required configuration to produce an Artifact for + an object storage bucket. + properties: + bucketName: + description: BucketName is the name of the object storage bucket. + type: string + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + bucket. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + This field is only supported for the `generic` provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + endpoint: + description: Endpoint is the object storage address the BucketName + is located at. + type: string + ignore: + description: |- + Ignore overrides the set of excluded patterns in the .sourceignore format + (which is the same as .gitignore). If not provided, a default will be used, + consult the documentation for your version to find out what those are. + type: string + insecure: + description: Insecure allows connecting to a non-TLS HTTP Endpoint. + type: boolean + interval: + description: |- + Interval at which the Bucket Endpoint is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + prefix: + description: Prefix to use for server-side filtering of files in the + Bucket. + type: string + provider: + default: generic + description: |- + Provider of the object storage bucket. + Defaults to 'generic', which expects an S3 (API) compatible object + storage. + enum: + - generic + - aws + - gcp + - azure + type: string + proxySecretRef: + description: |- + ProxySecretRef specifies the Secret containing the proxy configuration + to use while communicating with the Bucket server. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + region: + description: Region of the Endpoint where the BucketName is located + in. + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials + for the Bucket. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate + the bucket. This field is only supported for the 'gcp' and 'aws' providers. + For more information about workload identity: + https://fluxcd.io/flux/components/source/buckets/#workload-identity + type: string + sts: + description: |- + STS specifies the required configuration to use a Security Token + Service for fetching temporary credentials to authenticate in a + Bucket provider. + + This field is only supported for the `aws` and `generic` providers. + properties: + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + STS endpoint. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + This field is only supported for the `ldap` provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + endpoint: + description: |- + Endpoint is the HTTP/S endpoint of the Security Token Service from + where temporary credentials will be fetched. + pattern: ^(http|https)://.*$ + type: string + provider: + description: Provider of the Security Token Service. + enum: + - aws + - ldap + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials + for the STS endpoint. This Secret must contain the fields `username` + and `password` and is supported only for the `ldap` provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - endpoint + - provider + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + Bucket. + type: boolean + timeout: + default: 60s + description: Timeout for fetch operations, defaults to 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + required: + - bucketName + - endpoint + - interval + type: object + x-kubernetes-validations: + - message: STS configuration is only supported for the 'aws' and 'generic' + Bucket providers + rule: self.provider == 'aws' || self.provider == 'generic' || !has(self.sts) + - message: '''aws'' is the only supported STS provider for the ''aws'' + Bucket provider' + rule: self.provider != 'aws' || !has(self.sts) || self.sts.provider + == 'aws' + - message: '''ldap'' is the only supported STS provider for the ''generic'' + Bucket provider' + rule: self.provider != 'generic' || !has(self.sts) || self.sts.provider + == 'ldap' + - message: spec.sts.secretRef is not required for the 'aws' STS provider + rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.secretRef)' + - message: spec.sts.certSecretRef is not required for the 'aws' STS provider + rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.certSecretRef)' + - message: ServiceAccountName is not supported for the 'generic' Bucket + provider + rule: self.provider != 'generic' || !has(self.serviceAccountName) + - message: cannot set both .spec.secretRef and .spec.serviceAccountName + rule: '!has(self.secretRef) || !has(self.serviceAccountName)' + status: + default: + observedGeneration: -1 + description: BucketStatus records the observed state of a Bucket. + properties: + artifact: + description: Artifact represents the last successful Bucket reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the Bucket. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation of + the Bucket object. + format: int64 + type: integer + observedIgnore: + description: |- + ObservedIgnore is the observed exclusion patterns used for constructing + the source artifact. + type: string + url: + description: |- + URL is the dynamic fetch link for the latest Artifact. + It is provided on a "best effort" basis, and using the precise + BucketStatus.Artifact data is recommended. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: externalartifacts.source.toolkit.fluxcd.io +spec: + group: source.toolkit.fluxcd.io + names: + kind: ExternalArtifact + listKind: ExternalArtifactList + plural: externalartifacts + singular: externalartifact + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + - jsonPath: .spec.sourceRef.name + name: Source + type: string + name: v1 + schema: + openAPIV3Schema: + description: ExternalArtifact is the Schema for the external artifacts API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ExternalArtifactSpec defines the desired state of ExternalArtifact + properties: + sourceRef: + description: |- + SourceRef points to the Kubernetes custom resource for + which the artifact is generated. + properties: + apiVersion: + description: API version of the referent, if not specified the + Kubernetes preferred version will be used. + type: string + kind: + description: Kind of the referent. + type: string + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - kind + - name + type: object + type: object + status: + description: ExternalArtifactStatus defines the observed state of ExternalArtifact + properties: + artifact: + description: Artifact represents the output of an ExternalArtifact + reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the ExternalArtifact. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: gitrepositories.source.toolkit.fluxcd.io +spec: + group: source.toolkit.fluxcd.io + names: + kind: GitRepository + listKind: GitRepositoryList + plural: gitrepositories + shortNames: + - gitrepo + singular: gitrepository + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: GitRepository is the Schema for the gitrepositories API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + GitRepositorySpec specifies the required configuration to produce an + Artifact for a Git repository. + properties: + ignore: + description: |- + Ignore overrides the set of excluded patterns in the .sourceignore format + (which is the same as .gitignore). If not provided, a default will be used, + consult the documentation for your version to find out what those are. + type: string + include: + description: |- + Include specifies a list of GitRepository resources which Artifacts + should be included in the Artifact produced for this GitRepository. + items: + description: |- + GitRepositoryInclude specifies a local reference to a GitRepository which + Artifact (sub-)contents must be included, and where they should be placed. + properties: + fromPath: + description: |- + FromPath specifies the path to copy contents from, defaults to the root + of the Artifact. + type: string + repository: + description: |- + GitRepositoryRef specifies the GitRepository which Artifact contents + must be included. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + toPath: + description: |- + ToPath specifies the path to copy contents to, defaults to the name of + the GitRepositoryRef. + type: string + required: + - repository + type: object + type: array + interval: + description: |- + Interval at which the GitRepository URL is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + provider: + description: |- + Provider used for authentication, can be 'azure', 'github', 'generic'. + When not specified, defaults to 'generic'. + enum: + - generic + - azure + - github + type: string + proxySecretRef: + description: |- + ProxySecretRef specifies the Secret containing the proxy configuration + to use while communicating with the Git server. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + recurseSubmodules: + description: |- + RecurseSubmodules enables the initialization of all submodules within + the GitRepository as cloned from the URL, using their default settings. + type: boolean + ref: + description: |- + Reference specifies the Git reference to resolve and monitor for + changes, defaults to the 'master' branch. + properties: + branch: + description: Branch to check out, defaults to 'master' if no other + field is defined. + type: string + commit: + description: |- + Commit SHA to check out, takes precedence over all reference fields. + + This can be combined with Branch to shallow clone the branch, in which + the commit is expected to exist. + type: string + name: + description: |- + Name of the reference to check out; takes precedence over Branch, Tag and SemVer. + + It must be a valid Git reference: https://git-scm.com/docs/git-check-ref-format#_description + Examples: "refs/heads/main", "refs/tags/v0.1.0", "refs/pull/420/head", "refs/merge-requests/1/head" + type: string + semver: + description: SemVer tag expression to check out, takes precedence + over Tag. + type: string + tag: + description: Tag to check out, takes precedence over Branch. + type: string + type: object + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials for + the GitRepository. + For HTTPS repositories the Secret must contain 'username' and 'password' + fields for basic auth or 'bearerToken' field for token auth. + For SSH repositories the Secret must contain 'identity' + and 'known_hosts' fields. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the Kubernetes ServiceAccount used to + authenticate to the GitRepository. This field is only supported for 'azure' provider. + type: string + sparseCheckout: + description: |- + SparseCheckout specifies a list of directories to checkout when cloning + the repository. If specified, only these directories are included in the + Artifact produced for this GitRepository. + items: + type: string + type: array + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + GitRepository. + type: boolean + timeout: + default: 60s + description: Timeout for Git operations like cloning, defaults to + 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + url: + description: URL specifies the Git repository URL, it can be an HTTP/S + or SSH address. + pattern: ^(http|https|ssh)://.*$ + type: string + verify: + description: |- + Verification specifies the configuration to verify the Git commit + signature(s). + properties: + mode: + default: HEAD + description: |- + Mode specifies which Git object(s) should be verified. + + The variants "head" and "HEAD" both imply the same thing, i.e. verify + the commit that the HEAD of the Git repository points to. The variant + "head" solely exists to ensure backwards compatibility. + enum: + - head + - HEAD + - Tag + - TagAndHEAD + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing the public keys of trusted Git + authors. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - secretRef + type: object + required: + - interval + - url + type: object + x-kubernetes-validations: + - message: serviceAccountName can only be set when provider is 'azure' + rule: '!has(self.serviceAccountName) || (has(self.provider) && self.provider + == ''azure'')' + status: + default: + observedGeneration: -1 + description: GitRepositoryStatus records the observed state of a Git repository. + properties: + artifact: + description: Artifact represents the last successful GitRepository + reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the GitRepository. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + includedArtifacts: + description: |- + IncludedArtifacts contains a list of the last successfully included + Artifacts as instructed by GitRepositorySpec.Include. + items: + description: Artifact represents the output of a Source reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of + ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI + annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: |- + ObservedGeneration is the last observed generation of the GitRepository + object. + format: int64 + type: integer + observedIgnore: + description: |- + ObservedIgnore is the observed exclusion patterns used for constructing + the source artifact. + type: string + observedInclude: + description: |- + ObservedInclude is the observed list of GitRepository resources used to + produce the current Artifact. + items: + description: |- + GitRepositoryInclude specifies a local reference to a GitRepository which + Artifact (sub-)contents must be included, and where they should be placed. + properties: + fromPath: + description: |- + FromPath specifies the path to copy contents from, defaults to the root + of the Artifact. + type: string + repository: + description: |- + GitRepositoryRef specifies the GitRepository which Artifact contents + must be included. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + toPath: + description: |- + ToPath specifies the path to copy contents to, defaults to the name of + the GitRepositoryRef. + type: string + required: + - repository + type: object + type: array + observedRecurseSubmodules: + description: |- + ObservedRecurseSubmodules is the observed resource submodules + configuration used to produce the current Artifact. + type: boolean + observedSparseCheckout: + description: |- + ObservedSparseCheckout is the observed list of directories used to + produce the current Artifact. + items: + type: string + type: array + sourceVerificationMode: + description: |- + SourceVerificationMode is the last used verification mode indicating + which Git object(s) have been verified. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: helmcharts.source.toolkit.fluxcd.io +spec: + group: source.toolkit.fluxcd.io + names: + kind: HelmChart + listKind: HelmChartList + plural: helmcharts + shortNames: + - hc + singular: helmchart + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.chart + name: Chart + type: string + - jsonPath: .spec.version + name: Version + type: string + - jsonPath: .spec.sourceRef.kind + name: Source Kind + type: string + - jsonPath: .spec.sourceRef.name + name: Source Name + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: HelmChart is the Schema for the helmcharts API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: HelmChartSpec specifies the desired state of a Helm chart. + properties: + chart: + description: |- + Chart is the name or path the Helm chart is available at in the + SourceRef. + type: string + ignoreMissingValuesFiles: + description: |- + IgnoreMissingValuesFiles controls whether to silently ignore missing values + files rather than failing. + type: boolean + interval: + description: |- + Interval at which the HelmChart SourceRef is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + reconcileStrategy: + default: ChartVersion + description: |- + ReconcileStrategy determines what enables the creation of a new artifact. + Valid values are ('ChartVersion', 'Revision'). + See the documentation of the values for an explanation on their behavior. + Defaults to ChartVersion when omitted. + enum: + - ChartVersion + - Revision + type: string + sourceRef: + description: SourceRef is the reference to the Source the chart is + available at. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: |- + Kind of the referent, valid values are ('HelmRepository', 'GitRepository', + 'Bucket'). + enum: + - HelmRepository + - GitRepository + - Bucket + type: string + name: + description: Name of the referent. + type: string + required: + - kind + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + source. + type: boolean + valuesFiles: + description: |- + ValuesFiles is an alternative list of values files to use as the chart + values (values.yaml is not included by default), expected to be a + relative path in the SourceRef. + Values files are merged in the order of this list with the last file + overriding the first. Ignored when omitted. + items: + type: string + type: array + verify: + description: |- + Verify contains the secret name containing the trusted public keys + used to verify the signature and specifies which provider to use to check + whether OCI image is authentic. + This field is only supported when using HelmRepository source with spec.type 'oci'. + Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified. + properties: + matchOIDCIdentity: + description: |- + MatchOIDCIdentity specifies the identity matching criteria to use + while verifying an OCI artifact which was signed using Cosign keyless + signing. The artifact's identity is deemed to be verified if any of the + specified matchers match against the identity. + items: + description: |- + OIDCIdentityMatch specifies options for verifying the certificate identity, + i.e. the issuer and the subject of the certificate. + properties: + issuer: + description: |- + Issuer specifies the regex pattern to match against to verify + the OIDC issuer in the Fulcio certificate. The pattern must be a + valid Go regular expression. + type: string + subject: + description: |- + Subject specifies the regex pattern to match against to verify + the identity subject in the Fulcio certificate. The pattern must + be a valid Go regular expression. + type: string + required: + - issuer + - subject + type: object + type: array + provider: + default: cosign + description: Provider specifies the technology used to sign the + OCI Artifact. + enum: + - cosign + - notation + type: string + secretRef: + description: |- + SecretRef specifies the Kubernetes Secret containing the + trusted public keys. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + version: + default: '*' + description: |- + Version is the chart version semver expression, ignored for charts from + GitRepository and Bucket sources. Defaults to latest when omitted. + type: string + required: + - chart + - interval + - sourceRef + type: object + x-kubernetes-validations: + - message: spec.verify is only supported when spec.sourceRef.kind is 'HelmRepository' + rule: '!has(self.verify) || self.sourceRef.kind == ''HelmRepository''' + status: + default: + observedGeneration: -1 + description: HelmChartStatus records the observed state of the HelmChart. + properties: + artifact: + description: Artifact represents the output of the last successful + reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the HelmChart. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedChartName: + description: |- + ObservedChartName is the last observed chart name as specified by the + resolved chart reference. + type: string + observedGeneration: + description: |- + ObservedGeneration is the last observed generation of the HelmChart + object. + format: int64 + type: integer + observedSourceArtifactRevision: + description: |- + ObservedSourceArtifactRevision is the last observed Artifact.Revision + of the HelmChartSpec.SourceRef. + type: string + observedValuesFiles: + description: |- + ObservedValuesFiles are the observed value files of the last successful + reconciliation. + It matches the chart in the last successfully reconciled artifact. + items: + type: string + type: array + url: + description: |- + URL is the dynamic fetch link for the latest Artifact. + It is provided on a "best effort" basis, and using the precise + BucketStatus.Artifact data is recommended. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: helmrepositories.source.toolkit.fluxcd.io +spec: + group: source.toolkit.fluxcd.io + names: + kind: HelmRepository + listKind: HelmRepositoryList + plural: helmrepositories + shortNames: + - helmrepo + singular: helmrepository + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: HelmRepository is the Schema for the helmrepositories API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + HelmRepositorySpec specifies the required configuration to produce an + Artifact for a Helm repository index YAML. + properties: + accessFrom: + description: |- + AccessFrom specifies an Access Control List for allowing cross-namespace + references to this object. + NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 + properties: + namespaceSelectors: + description: |- + NamespaceSelectors is the list of namespace selectors to which this ACL applies. + Items in this list are evaluated using a logical OR operation. + items: + description: |- + NamespaceSelector selects the namespaces to which this ACL applies. + An empty map of MatchLabels matches all namespaces in a cluster. + properties: + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: array + required: + - namespaceSelectors + type: object + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + registry. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + + It takes precedence over the values specified in the Secret referred + to by `.spec.secretRef`. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + insecure: + description: |- + Insecure allows connecting to a non-TLS HTTP container registry. + This field is only taken into account if the .spec.type field is set to 'oci'. + type: boolean + interval: + description: |- + Interval at which the HelmRepository URL is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + passCredentials: + description: |- + PassCredentials allows the credentials from the SecretRef to be passed + on to a host that does not match the host as defined in URL. + This may be required if the host of the advertised chart URLs in the + index differ from the defined URL. + Enabling this should be done with caution, as it can potentially result + in credentials getting stolen in a MITM-attack. + type: boolean + provider: + default: generic + description: |- + Provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. + This field is optional, and only taken into account if the .spec.type field is set to 'oci'. + When not specified, defaults to 'generic'. + enum: + - generic + - aws + - azure + - gcp + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing authentication credentials + for the HelmRepository. + For HTTP/S basic auth the secret must contain 'username' and 'password' + fields. + Support for TLS auth using the 'certFile' and 'keyFile', and/or 'caFile' + keys is deprecated. Please use `.spec.certSecretRef` instead. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend the reconciliation of this + HelmRepository. + type: boolean + timeout: + description: |- + Timeout is used for the index fetch operation for an HTTPS helm repository, + and for remote OCI Repository operations like pulling for an OCI helm + chart by the associated HelmChart. + Its default value is 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + type: + description: |- + Type of the HelmRepository. + When this field is set to "oci", the URL field value must be prefixed with "oci://". + enum: + - default + - oci + type: string + url: + description: |- + URL of the Helm repository, a valid URL contains at least a protocol and + host. + pattern: ^(http|https|oci)://.*$ + type: string + required: + - url + type: object + status: + default: + observedGeneration: -1 + description: HelmRepositoryStatus records the observed state of the HelmRepository. + properties: + artifact: + description: Artifact represents the last successful HelmRepository + reconciliation. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the HelmRepository. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: |- + ObservedGeneration is the last observed generation of the HelmRepository + object. + format: int64 + type: integer + url: + description: |- + URL is the dynamic fetch link for the latest Artifact. + It is provided on a "best effort" basis, and using the precise + HelmRepositoryStatus.Artifact data is recommended. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: ocirepositories.source.toolkit.fluxcd.io +spec: + group: source.toolkit.fluxcd.io + names: + kind: OCIRepository + listKind: OCIRepositoryList + plural: ocirepositories + shortNames: + - ocirepo + singular: ocirepository + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.url + name: URL + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: OCIRepository is the Schema for the ocirepositories API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: OCIRepositorySpec defines the desired state of OCIRepository + properties: + certSecretRef: + description: |- + CertSecretRef can be given the name of a Secret containing + either or both of + + - a PEM-encoded client certificate (`tls.crt`) and private + key (`tls.key`); + - a PEM-encoded CA certificate (`ca.crt`) + + and whichever are supplied, will be used for connecting to the + registry. The client cert and key are useful if you are + authenticating with a certificate; the CA cert is useful if + you are using a self-signed server certificate. The Secret must + be of type `Opaque` or `kubernetes.io/tls`. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + ignore: + description: |- + Ignore overrides the set of excluded patterns in the .sourceignore format + (which is the same as .gitignore). If not provided, a default will be used, + consult the documentation for your version to find out what those are. + type: string + insecure: + description: Insecure allows connecting to a non-TLS HTTP container + registry. + type: boolean + interval: + description: |- + Interval at which the OCIRepository URL is checked for updates. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + layerSelector: + description: |- + LayerSelector specifies which layer should be extracted from the OCI artifact. + When not specified, the first layer found in the artifact is selected. + properties: + mediaType: + description: |- + MediaType specifies the OCI media type of the layer + which should be extracted from the OCI Artifact. The + first layer matching this type is selected. + type: string + operation: + description: |- + Operation specifies how the selected layer should be processed. + By default, the layer compressed content is extracted to storage. + When the operation is set to 'copy', the layer compressed content + is persisted to storage as it is. + enum: + - extract + - copy + type: string + type: object + provider: + default: generic + description: |- + The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. + When not specified, defaults to 'generic'. + enum: + - generic + - aws + - azure + - gcp + type: string + proxySecretRef: + description: |- + ProxySecretRef specifies the Secret containing the proxy configuration + to use while communicating with the container registry. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + ref: + description: |- + The OCI reference to pull and monitor for changes, + defaults to the latest tag. + properties: + digest: + description: |- + Digest is the image digest to pull, takes precedence over SemVer. + The value should be in the format 'sha256:'. + type: string + semver: + description: |- + SemVer is the range of tags to pull selecting the latest within + the range, takes precedence over Tag. + type: string + semverFilter: + description: SemverFilter is a regex pattern to filter the tags + within the SemVer range. + type: string + tag: + description: Tag is the image tag to pull, defaults to latest. + type: string + type: object + secretRef: + description: |- + SecretRef contains the secret name containing the registry login + credentials to resolve image metadata. + The secret must be of type kubernetes.io/dockerconfigjson. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate + the image pull if the service account has attached pull secrets. For more information: + https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account + type: string + suspend: + description: This flag tells the controller to suspend the reconciliation + of this source. + type: boolean + timeout: + default: 60s + description: The timeout for remote OCI Repository operations like + pulling, defaults to 60s. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + url: + description: |- + URL is a reference to an OCI artifact repository hosted + on a remote container registry. + pattern: ^oci://.*$ + type: string + verify: + description: |- + Verify contains the secret name containing the trusted public keys + used to verify the signature and specifies which provider to use to check + whether OCI image is authentic. + properties: + matchOIDCIdentity: + description: |- + MatchOIDCIdentity specifies the identity matching criteria to use + while verifying an OCI artifact which was signed using Cosign keyless + signing. The artifact's identity is deemed to be verified if any of the + specified matchers match against the identity. + items: + description: |- + OIDCIdentityMatch specifies options for verifying the certificate identity, + i.e. the issuer and the subject of the certificate. + properties: + issuer: + description: |- + Issuer specifies the regex pattern to match against to verify + the OIDC issuer in the Fulcio certificate. The pattern must be a + valid Go regular expression. + type: string + subject: + description: |- + Subject specifies the regex pattern to match against to verify + the identity subject in the Fulcio certificate. The pattern must + be a valid Go regular expression. + type: string + required: + - issuer + - subject + type: object + type: array + provider: + default: cosign + description: Provider specifies the technology used to sign the + OCI Artifact. + enum: + - cosign + - notation + type: string + secretRef: + description: |- + SecretRef specifies the Kubernetes Secret containing the + trusted public keys. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + required: + - interval + - url + type: object + status: + default: + observedGeneration: -1 + description: OCIRepositoryStatus defines the observed state of OCIRepository + properties: + artifact: + description: Artifact represents the output of the last successful + OCI Repository sync. + properties: + digest: + description: Digest is the digest of the file in the form of ':'. + pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ + type: string + lastUpdateTime: + description: |- + LastUpdateTime is the timestamp corresponding to the last update of the + Artifact. + format: date-time + type: string + metadata: + additionalProperties: + type: string + description: Metadata holds upstream information such as OCI annotations. + type: object + path: + description: |- + Path is the relative file path of the Artifact. It can be used to locate + the file in the root of the Artifact storage on the local file system of + the controller managing the Source. + type: string + revision: + description: |- + Revision is a human-readable identifier traceable in the origin source + system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. + type: string + size: + description: Size is the number of bytes in the file. + format: int64 + type: integer + url: + description: |- + URL is the HTTP address of the Artifact as exposed by the controller + managing the Source. It can be used to retrieve the Artifact for + consumption, e.g. by another controller applying the Artifact contents. + type: string + required: + - digest + - lastUpdateTime + - path + - revision + - url + type: object + conditions: + description: Conditions holds the conditions for the OCIRepository. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + observedIgnore: + description: |- + ObservedIgnore is the observed exclusion patterns used for constructing + the source artifact. + type: string + observedLayerSelector: + description: |- + ObservedLayerSelector is the observed layer selector used for constructing + the source artifact. + properties: + mediaType: + description: |- + MediaType specifies the OCI media type of the layer + which should be extracted from the OCI Artifact. The + first layer matching this type is selected. + type: string + operation: + description: |- + Operation specifies how the selected layer should be processed. + By default, the layer compressed content is extracted to storage. + When the operation is set to 'copy', the layer compressed content + is persisted to storage as it is. + enum: + - extract + - copy + type: string + type: object + url: + description: URL is the download link for the artifact output of the + last OCI Repository sync. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: source-controller + namespace: flux-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + control-plane: controller + name: source-controller + namespace: flux-system +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: http + selector: + app: source-controller + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + control-plane: controller + name: source-controller + namespace: flux-system +spec: + replicas: 1 + selector: + matchLabels: + app: source-controller + strategy: + type: Recreate + template: + metadata: + annotations: + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + labels: + app: source-controller + app.kubernetes.io/component: source-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + spec: + containers: + - args: + - --events-addr=http://notification-controller.$(RUNTIME_NAMESPACE).svc.cluster.local./ + - --watch-all-namespaces=true + - --log-level=info + - --log-encoding=json + - --enable-leader-election + - --storage-path=/data + - --storage-adv-addr=source-controller.$(RUNTIME_NAMESPACE).svc.cluster.local. + env: + - name: RUNTIME_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: TUF_ROOT + value: /tmp/.sigstore + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + containerName: manager + resource: limits.memory + image: ghcr.io/fluxcd/source-controller:v1.8.2 + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: healthz + name: manager + ports: + - containerPort: 9090 + name: http + protocol: TCP + - containerPort: 8080 + name: http-prom + protocol: TCP + - containerPort: 9440 + name: healthz + protocol: TCP + readinessProbe: + httpGet: + path: / + port: http + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 50m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /data + name: data + - mountPath: /tmp + name: tmp + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + securityContext: + fsGroup: 1337 + serviceAccountName: source-controller + terminationGracePeriodSeconds: 10 + volumes: + - emptyDir: {} + name: data + - emptyDir: {} + name: tmp +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + app.kubernetes.io/component: kustomize-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: kustomizations.kustomize.toolkit.fluxcd.io +spec: + group: kustomize.toolkit.fluxcd.io + names: + kind: Kustomization + listKind: KustomizationList + plural: kustomizations + shortNames: + - ks + singular: kustomization + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: Kustomization is the Schema for the kustomizations API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: |- + KustomizationSpec defines the configuration to calculate the desired state + from a Source using Kustomize. + properties: + commonMetadata: + description: |- + CommonMetadata specifies the common labels and annotations that are + applied to all resources. Any existing label or annotation will be + overridden if its key matches a common one. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to be added to the object's metadata. + type: object + labels: + additionalProperties: + type: string + description: Labels to be added to the object's metadata. + type: object + type: object + components: + description: Components specifies relative paths to kustomize Components. + items: + type: string + type: array + decryption: + description: Decrypt Kubernetes secrets before applying them on the + cluster. + properties: + provider: + description: Provider is the name of the decryption engine. + enum: + - sops + type: string + secretRef: + description: |- + The secret name containing the private OpenPGP keys used for decryption. + A static credential for a cloud provider defined inside the Secret + takes priority to secret-less authentication with the ServiceAccountName + field. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the service account used to + authenticate with KMS services from cloud providers. If a + static credential for a given cloud provider is defined + inside the Secret referenced by SecretRef, that static + credential takes priority. + type: string + required: + - provider + type: object + deletionPolicy: + description: |- + DeletionPolicy can be used to control garbage collection when this + Kustomization is deleted. Valid values are ('MirrorPrune', 'Delete', + 'WaitForTermination', 'Orphan'). 'MirrorPrune' mirrors the Prune field + (orphan if false, delete if true). Defaults to 'MirrorPrune'. + enum: + - MirrorPrune + - Delete + - WaitForTermination + - Orphan + type: string + dependsOn: + description: |- + DependsOn may contain a DependencyReference slice + with references to Kustomization resources that must be ready before this + Kustomization can be reconciled. + items: + description: DependencyReference defines a Kustomization dependency + on another Kustomization resource. + properties: + name: + description: Name of the referent. + type: string + namespace: + description: |- + Namespace of the referent, defaults to the namespace of the Kustomization + resource object that contains the reference. + type: string + readyExpr: + description: |- + ReadyExpr is a CEL expression that can be used to assess the readiness + of a dependency. When specified, the built-in readiness check + is replaced by the logic defined in the CEL expression. + To make the CEL expression additive to the built-in readiness check, + the feature gate `AdditiveCELDependencyCheck` must be set to `true`. + type: string + required: + - name + type: object + type: array + force: + default: false + description: |- + Force instructs the controller to recreate resources + when patching fails due to an immutable field change. + type: boolean + healthCheckExprs: + description: |- + HealthCheckExprs is a list of healthcheck expressions for evaluating the + health of custom resources using Common Expression Language (CEL). + The expressions are evaluated only when Wait or HealthChecks are specified. + items: + description: CustomHealthCheck defines the health check for custom + resources. + properties: + apiVersion: + description: APIVersion of the custom resource under evaluation. + type: string + current: + description: |- + Current is the CEL expression that determines if the status + of the custom resource has reached the desired state. + type: string + failed: + description: |- + Failed is the CEL expression that determines if the status + of the custom resource has failed to reach the desired state. + type: string + inProgress: + description: |- + InProgress is the CEL expression that determines if the status + of the custom resource has not yet reached the desired state. + type: string + kind: + description: Kind of the custom resource under evaluation. + type: string + required: + - apiVersion + - current + - kind + type: object + type: array + healthChecks: + description: A list of resources to be included in the health assessment. + items: + description: |- + NamespacedObjectKindReference contains enough information to locate the typed referenced Kubernetes resource object + in any namespace. + properties: + apiVersion: + description: API version of the referent, if not specified the + Kubernetes preferred version will be used. + type: string + kind: + description: Kind of the referent. + type: string + name: + description: Name of the referent. + type: string + namespace: + description: Namespace of the referent, when not specified it + acts as LocalObjectReference. + type: string + required: + - kind + - name + type: object + type: array + ignoreMissingComponents: + description: |- + IgnoreMissingComponents instructs the controller to ignore Components paths + not found in source by removing them from the generated kustomization.yaml + before running kustomize build. + type: boolean + images: + description: |- + Images is a list of (image name, new name, new tag or digest) + for changing image names, tags or digests. This can also be achieved with a + patch, but this operator is simpler to specify. + items: + description: Image contains an image name, a new name, a new tag + or digest, which will replace the original name and tag. + properties: + digest: + description: |- + Digest is the value used to replace the original image tag. + If digest is present NewTag value is ignored. + type: string + name: + description: Name is a tag-less image name. + type: string + newName: + description: NewName is the value used to replace the original + name. + type: string + newTag: + description: NewTag is the value used to replace the original + tag. + type: string + required: + - name + type: object + type: array + interval: + description: |- + The interval at which to reconcile the Kustomization. + This interval is approximate and may be subject to jitter to ensure + efficient use of resources. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + kubeConfig: + description: |- + The KubeConfig for reconciling the Kustomization on a remote cluster. + When used in combination with KustomizationSpec.ServiceAccountName, + forces the controller to act on behalf of that Service Account at the + target cluster. + If the --default-service-account flag is set, its value will be used as + a controller level fallback for when KustomizationSpec.ServiceAccountName + is empty. + properties: + configMapRef: + description: |- + ConfigMapRef holds an optional name of a ConfigMap that contains + the following keys: + + - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or + `generic`. Required. + - `cluster`: the fully qualified resource name of the Kubernetes + cluster in the cloud provider API. Not used by the `generic` + provider. Required when one of `address` or `ca.crt` is not set. + - `address`: the address of the Kubernetes API server. Required + for `generic`. For the other providers, if not specified, the + first address in the cluster resource will be used, and if + specified, it must match one of the addresses in the cluster + resource. + If audiences is not set, will be used as the audience for the + `generic` provider. + - `ca.crt`: the optional PEM-encoded CA certificate for the + Kubernetes API server. If not set, the controller will use the + CA certificate from the cluster resource. + - `audiences`: the optional audiences as a list of + line-break-separated strings for the Kubernetes ServiceAccount + token. Defaults to the `address` for the `generic` provider, or + to specific values for the other providers depending on the + provider. + - `serviceAccountName`: the optional name of the Kubernetes + ServiceAccount in the same namespace that should be used + for authentication. If not specified, the controller + ServiceAccount will be used. + + Mutually exclusive with SecretRef. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + secretRef: + description: |- + SecretRef holds an optional name of a secret that contains a key with + the kubeconfig file as the value. If no key is set, the key will default + to 'value'. Mutually exclusive with ConfigMapRef. + It is recommended that the kubeconfig is self-contained, and the secret + is regularly updated if credentials such as a cloud-access-token expire. + Cloud specific `cmd-path` auth helpers will not function without adding + binaries and credentials to the Pod that is responsible for reconciling + Kubernetes resources. Supported only for the generic provider. + properties: + key: + description: Key in the Secret, when not specified an implementation-specific + default key is used. + type: string + name: + description: Name of the Secret. + type: string + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef + must be specified + rule: has(self.configMapRef) || has(self.secretRef) + - message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef + must be specified + rule: '!has(self.configMapRef) || !has(self.secretRef)' + namePrefix: + description: NamePrefix will prefix the names of all managed resources. + maxLength: 200 + minLength: 1 + type: string + nameSuffix: + description: NameSuffix will suffix the names of all managed resources. + maxLength: 200 + minLength: 1 + type: string + patches: + description: |- + Strategic merge and JSON patches, defined as inline YAML objects, + capable of targeting objects based on kind, label and annotation selectors. + items: + description: |- + Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should + be applied to. + properties: + patch: + description: |- + Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with + an array of operation objects. + type: string + target: + description: Target points to the resources that the patch document + should be applied to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + type: object + type: array + path: + description: |- + Path to the directory containing the kustomization.yaml file, or the + set of plain YAMLs a kustomization.yaml should be generated for. + Defaults to 'None', which translates to the root path of the SourceRef. + type: string + postBuild: + description: |- + PostBuild describes which actions to perform on the YAML manifest + generated by building the kustomize overlay. + properties: + substitute: + additionalProperties: + type: string + description: |- + Substitute holds a map of key/value pairs. + The variables defined in your YAML manifests that match any of the keys + defined in the map will be substituted with the set value. + Includes support for bash string replacement functions + e.g. ${var:=default}, ${var:position} and ${var/substring/replacement}. + type: object + substituteFrom: + description: |- + SubstituteFrom holds references to ConfigMaps and Secrets containing + the variables and their values to be substituted in the YAML manifests. + The ConfigMap and the Secret data keys represent the var names, and they + must match the vars declared in the manifests for the substitution to + happen. + items: + description: |- + SubstituteReference contains a reference to a resource containing + the variables name and value. + properties: + kind: + description: Kind of the values referent, valid values are + ('Secret', 'ConfigMap'). + enum: + - Secret + - ConfigMap + type: string + name: + description: |- + Name of the values referent. Should reside in the same namespace as the + referring resource. + maxLength: 253 + minLength: 1 + type: string + optional: + default: false + description: |- + Optional indicates whether the referenced resource must exist, or whether to + tolerate its absence. If true and the referenced resource is absent, proceed + as if the resource was present but empty, without any variables defined. + type: boolean + required: + - kind + - name + type: object + type: array + type: object + prune: + description: Prune enables garbage collection. + type: boolean + retryInterval: + description: |- + The interval at which to retry a previously failed reconciliation. + When not specified, the controller uses the KustomizationSpec.Interval + value to retry failures. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + serviceAccountName: + description: |- + The name of the Kubernetes service account to impersonate + when reconciling this Kustomization. + type: string + sourceRef: + description: Reference of the source where the kustomization file + is. + properties: + apiVersion: + description: API version of the referent. + type: string + kind: + description: Kind of the referent. + enum: + - OCIRepository + - GitRepository + - Bucket + - ExternalArtifact + type: string + name: + description: Name of the referent. + type: string + namespace: + description: |- + Namespace of the referent, defaults to the namespace of the Kubernetes + resource object that contains the reference. + type: string + required: + - kind + - name + type: object + suspend: + description: |- + This flag tells the controller to suspend subsequent kustomize executions, + it does not apply to already started executions. Defaults to false. + type: boolean + targetNamespace: + description: |- + TargetNamespace sets or overrides the namespace in the + kustomization.yaml file. + maxLength: 63 + minLength: 1 + type: string + timeout: + description: |- + Timeout for validation, apply and health checking operations. + Defaults to 'Interval' duration. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + wait: + description: |- + Wait instructs the controller to check the health of all the reconciled + resources. When enabled, the HealthChecks are ignored. Defaults to false. + type: boolean + required: + - interval + - prune + - sourceRef + type: object + status: + default: + observedGeneration: -1 + description: KustomizationStatus defines the observed state of a kustomization. + properties: + conditions: + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + history: + description: |- + History contains a set of snapshots of the last reconciliation attempts + tracking the revision, the state and the duration of each attempt. + items: + description: |- + Snapshot represents a point-in-time record of a group of resources reconciliation, + including timing information, status, and a unique digest identifier. + properties: + digest: + description: Digest is the checksum in the format `:` + of the resources in this snapshot. + type: string + firstReconciled: + description: FirstReconciled is the time when this revision + was first reconciled to the cluster. + format: date-time + type: string + lastReconciled: + description: LastReconciled is the time when this revision was + last reconciled to the cluster. + format: date-time + type: string + lastReconciledDuration: + description: LastReconciledDuration is time it took to reconcile + the resources in this revision. + type: string + lastReconciledStatus: + description: LastReconciledStatus is the status of the last + reconciliation. + type: string + metadata: + additionalProperties: + type: string + description: Metadata contains additional information about + the snapshot. + type: object + totalReconciliations: + description: TotalReconciliations is the total number of reconciliations + that have occurred for this snapshot. + format: int64 + type: integer + required: + - digest + - firstReconciled + - lastReconciled + - lastReconciledDuration + - lastReconciledStatus + - totalReconciliations + type: object + type: array + inventory: + description: |- + Inventory contains the list of Kubernetes resource object references that + have been successfully applied. + properties: + entries: + description: Entries of Kubernetes resource object references. + items: + description: ResourceRef contains the information necessary + to locate a resource within a cluster. + properties: + id: + description: |- + ID is the string representation of the Kubernetes resource object's metadata, + in the format '___'. + type: string + v: + description: Version is the API version of the Kubernetes + resource object's kind. + type: string + required: + - id + - v + type: object + type: array + required: + - entries + type: object + lastAppliedOriginRevision: + description: |- + The last successfully applied origin revision. + Equals the origin revision of the applied Artifact from the referenced Source. + Usually present on the Metadata of the applied Artifact and depends on the + Source type, e.g. for OCI it's the value associated with the key + "org.opencontainers.image.revision". + type: string + lastAppliedRevision: + description: |- + The last successfully applied revision. + Equals the Revision of the applied Artifact from the referenced Source. + type: string + lastAttemptedRevision: + description: LastAttemptedRevision is the revision of the last reconciliation + attempt. + type: string + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last reconciled generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: kustomize-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: kustomize-controller + namespace: flux-system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: kustomize-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + control-plane: controller + name: kustomize-controller + namespace: flux-system +spec: + replicas: 1 + selector: + matchLabels: + app: kustomize-controller + template: + metadata: + annotations: + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + labels: + app: kustomize-controller + app.kubernetes.io/component: kustomize-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + spec: + containers: + - args: + - --events-addr=http://notification-controller.$(RUNTIME_NAMESPACE).svc.cluster.local./ + - --watch-all-namespaces=true + - --log-level=info + - --log-encoding=json + - --enable-leader-election + env: + - name: RUNTIME_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + containerName: manager + resource: limits.memory + image: ghcr.io/fluxcd/kustomize-controller:v1.8.3 + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: healthz + name: manager + ports: + - containerPort: 8080 + name: http-prom + protocol: TCP + - containerPort: 9440 + name: healthz + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: healthz + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 100m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /tmp + name: temp + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + securityContext: + fsGroup: 1337 + serviceAccountName: kustomize-controller + terminationGracePeriodSeconds: 60 + volumes: + - emptyDir: {} + name: temp +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + app.kubernetes.io/component: helm-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: helmreleases.helm.toolkit.fluxcd.io +spec: + group: helm.toolkit.fluxcd.io + names: + kind: HelmRelease + listKind: HelmReleaseList + plural: helmreleases + shortNames: + - hr + singular: helmrelease + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v2 + schema: + openAPIV3Schema: + description: HelmRelease is the Schema for the helmreleases API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: HelmReleaseSpec defines the desired state of a Helm release. + properties: + chart: + description: |- + Chart defines the template of the v1.HelmChart that should be created + for this HelmRelease. + properties: + metadata: + description: ObjectMeta holds the template for metadata like labels + and annotations. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations is an unstructured key value map stored with a resource that may be + set by external tools to store and retrieve arbitrary metadata. They are not + queryable and should be preserved when modifying objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + type: object + labels: + additionalProperties: + type: string + description: |- + Map of string keys and values that can be used to organize and categorize + (scope and select) objects. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + type: object + type: object + spec: + description: Spec holds the template for the v1.HelmChartSpec + for this HelmRelease. + properties: + chart: + description: The name or path the Helm chart is available + at in the SourceRef. + maxLength: 2048 + minLength: 1 + type: string + ignoreMissingValuesFiles: + description: IgnoreMissingValuesFiles controls whether to + silently ignore missing values files rather than failing. + type: boolean + interval: + description: |- + Interval at which to check the v1.Source for updates. Defaults to + 'HelmReleaseSpec.Interval'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + reconcileStrategy: + default: ChartVersion + description: |- + Determines what enables the creation of a new artifact. Valid values are + ('ChartVersion', 'Revision'). + See the documentation of the values for an explanation on their behavior. + Defaults to ChartVersion when omitted. + enum: + - ChartVersion + - Revision + type: string + sourceRef: + description: The name and namespace of the v1.Source the chart + is available at. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: Kind of the referent. + enum: + - HelmRepository + - GitRepository + - Bucket + type: string + name: + description: Name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: Namespace of the referent. + maxLength: 63 + minLength: 1 + type: string + required: + - kind + - name + type: object + valuesFiles: + description: |- + Alternative list of values files to use as the chart values (values.yaml + is not included by default), expected to be a relative path in the SourceRef. + Values files are merged in the order of this list with the last file overriding + the first. Ignored when omitted. + items: + type: string + type: array + verify: + description: |- + Verify contains the secret name containing the trusted public keys + used to verify the signature and specifies which provider to use to check + whether OCI image is authentic. + This field is only supported for OCI sources. + Chart dependencies, which are not bundled in the umbrella chart artifact, + are not verified. + properties: + provider: + default: cosign + description: Provider specifies the technology used to + sign the OCI Helm chart. + enum: + - cosign + - notation + type: string + secretRef: + description: |- + SecretRef specifies the Kubernetes Secret containing the + trusted public keys. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + required: + - provider + type: object + version: + default: '*' + description: |- + Version semver expression, ignored for charts from v1.GitRepository and + v1beta2.Bucket sources. Defaults to latest when omitted. + type: string + required: + - chart + - sourceRef + type: object + required: + - spec + type: object + chartRef: + description: |- + ChartRef holds a reference to a source controller resource containing the + Helm chart artifact. + properties: + apiVersion: + description: APIVersion of the referent. + type: string + kind: + description: Kind of the referent. + enum: + - OCIRepository + - HelmChart + - ExternalArtifact + type: string + name: + description: Name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace of the referent, defaults to the namespace of the Kubernetes + resource object that contains the reference. + maxLength: 63 + minLength: 1 + type: string + required: + - kind + - name + type: object + commonMetadata: + description: |- + CommonMetadata specifies the common labels and annotations that are + applied to all resources. Any existing label or annotation will be + overridden if its key matches a common one. + properties: + annotations: + additionalProperties: + type: string + description: Annotations to be added to the object's metadata. + type: object + labels: + additionalProperties: + type: string + description: Labels to be added to the object's metadata. + type: object + type: object + dependsOn: + description: |- + DependsOn may contain a DependencyReference slice with + references to HelmRelease resources that must be ready before this HelmRelease + can be reconciled. + items: + description: DependencyReference defines a HelmRelease dependency + on another HelmRelease resource. + properties: + name: + description: Name of the referent. + type: string + namespace: + description: |- + Namespace of the referent, defaults to the namespace of the HelmRelease + resource object that contains the reference. + type: string + readyExpr: + description: |- + ReadyExpr is a CEL expression that can be used to assess the readiness + of a dependency. When specified, the built-in readiness check + is replaced by the logic defined in the CEL expression. + To make the CEL expression additive to the built-in readiness check, + the feature gate `AdditiveCELDependencyCheck` must be set to `true`. + type: string + required: + - name + type: object + type: array + driftDetection: + description: |- + DriftDetection holds the configuration for detecting and handling + differences between the manifest in the Helm storage and the resources + currently existing in the cluster. + properties: + ignore: + description: |- + Ignore contains a list of rules for specifying which changes to ignore + during diffing. + items: + description: |- + IgnoreRule defines a rule to selectively disregard specific changes during + the drift detection process. + properties: + paths: + description: |- + Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from + consideration in a Kubernetes object. + items: + type: string + type: array + target: + description: |- + Target is a selector for specifying Kubernetes objects to which this + rule applies. + If Target is not set, the Paths will be ignored for all Kubernetes + objects within the manifest of the Helm release. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - paths + type: object + type: array + mode: + description: |- + Mode defines how differences should be handled between the Helm manifest + and the manifest currently applied to the cluster. + If not explicitly set, it defaults to DiffModeDisabled. + enum: + - enabled + - warn + - disabled + type: string + type: object + healthCheckExprs: + description: |- + HealthCheckExprs is a list of healthcheck expressions for evaluating the + health of custom resources using Common Expression Language (CEL). + The expressions are evaluated only when the specific Helm action + taking place has wait enabled, i.e. DisableWait is false, and the + 'poller' WaitStrategy is used. + items: + description: CustomHealthCheck defines the health check for custom + resources. + properties: + apiVersion: + description: APIVersion of the custom resource under evaluation. + type: string + current: + description: |- + Current is the CEL expression that determines if the status + of the custom resource has reached the desired state. + type: string + failed: + description: |- + Failed is the CEL expression that determines if the status + of the custom resource has failed to reach the desired state. + type: string + inProgress: + description: |- + InProgress is the CEL expression that determines if the status + of the custom resource has not yet reached the desired state. + type: string + kind: + description: Kind of the custom resource under evaluation. + type: string + required: + - apiVersion + - current + - kind + type: object + type: array + install: + description: Install holds the configuration for Helm install actions + for this HelmRelease. + properties: + crds: + description: |- + CRDs upgrade CRDs from the Helm Chart's crds directory according + to the CRD upgrade policy provided here. Valid values are `Skip`, + `Create` or `CreateReplace`. Default is `Create` and if omitted + CRDs are installed but not updated. + + Skip: do neither install nor replace (update) any CRDs. + + Create: new CRDs are created, existing CRDs are neither updated nor deleted. + + CreateReplace: new CRDs are created, existing CRDs are updated (replaced) + but not deleted. + + By default, CRDs are applied (installed) during Helm install action. + With this option users can opt in to CRD replace existing CRDs on Helm + install actions, which is not (yet) natively supported by Helm. + https://helm.sh/docs/chart_best_practices/custom_resource_definitions. + enum: + - Skip + - Create + - CreateReplace + type: string + createNamespace: + description: |- + CreateNamespace tells the Helm install action to create the + HelmReleaseSpec.TargetNamespace if it does not exist yet. + On uninstall, the namespace will not be garbage collected. + type: boolean + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm install action. + type: boolean + disableOpenAPIValidation: + description: |- + DisableOpenAPIValidation prevents the Helm install action from validating + rendered templates against the Kubernetes OpenAPI Schema. + type: boolean + disableSchemaValidation: + description: |- + DisableSchemaValidation prevents the Helm install action from validating + the values against the JSON Schema. + type: boolean + disableTakeOwnership: + description: |- + DisableTakeOwnership disables taking ownership of existing resources + during the Helm install action. Defaults to false. + type: boolean + disableWait: + description: |- + DisableWait disables the waiting for resources to be ready after a Helm + install has been performed. + type: boolean + disableWaitForJobs: + description: |- + DisableWaitForJobs disables waiting for jobs to complete after a Helm + install has been performed. + type: boolean + remediation: + description: |- + Remediation holds the remediation configuration for when the Helm install + action for the HelmRelease fails. The default is to not perform any action. + properties: + ignoreTestFailures: + description: |- + IgnoreTestFailures tells the controller to skip remediation when the Helm + tests are run after an install action but fail. Defaults to + 'Test.IgnoreFailures'. + type: boolean + remediateLastFailure: + description: |- + RemediateLastFailure tells the controller to remediate the last failure, when + no retries remain. Defaults to 'false'. + type: boolean + retries: + description: |- + Retries is the number of retries that should be attempted on failures before + bailing. Remediation, using an uninstall, is performed between each attempt. + Defaults to '0', a negative integer equals to unlimited retries. + type: integer + type: object + replace: + description: |- + Replace tells the Helm install action to re-use the 'ReleaseName', but only + if that name is a deleted release which remains in the history. + type: boolean + serverSideApply: + description: |- + ServerSideApply enables server-side apply for resources during install. + Defaults to true (or false when UseHelm3Defaults feature gate is enabled). + type: boolean + skipCRDs: + description: |- + SkipCRDs tells the Helm install action to not install any CRDs. By default, + CRDs are installed if not already present. + + Deprecated use CRD policy (`crds`) attribute with value `Skip` instead. + type: boolean + strategy: + description: |- + Strategy defines the install strategy to use for this HelmRelease. + Defaults to 'RemediateOnFailure', or 'RetryOnFailure' when the + DefaultToRetryOnFailure feature gate is enabled. + properties: + name: + description: Name of the install strategy. + enum: + - RemediateOnFailure + - RetryOnFailure + type: string + retryInterval: + description: |- + RetryInterval is the interval at which to retry a failed install. + Can be used only when Name is set to RetryOnFailure. + Defaults to '5m'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: .retryInterval cannot be set when .name is 'RemediateOnFailure' + rule: '!has(self.retryInterval) || self.name != ''RemediateOnFailure''' + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm install action. Defaults to + 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + interval: + description: Interval at which to reconcile the Helm release. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + kubeConfig: + description: |- + KubeConfig for reconciling the HelmRelease on a remote cluster. + When used in combination with HelmReleaseSpec.ServiceAccountName, + forces the controller to act on behalf of that Service Account at the + target cluster. + If the --default-service-account flag is set, its value will be used as + a controller level fallback for when HelmReleaseSpec.ServiceAccountName + is empty. + properties: + configMapRef: + description: |- + ConfigMapRef holds an optional name of a ConfigMap that contains + the following keys: + + - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or + `generic`. Required. + - `cluster`: the fully qualified resource name of the Kubernetes + cluster in the cloud provider API. Not used by the `generic` + provider. Required when one of `address` or `ca.crt` is not set. + - `address`: the address of the Kubernetes API server. Required + for `generic`. For the other providers, if not specified, the + first address in the cluster resource will be used, and if + specified, it must match one of the addresses in the cluster + resource. + If audiences is not set, will be used as the audience for the + `generic` provider. + - `ca.crt`: the optional PEM-encoded CA certificate for the + Kubernetes API server. If not set, the controller will use the + CA certificate from the cluster resource. + - `audiences`: the optional audiences as a list of + line-break-separated strings for the Kubernetes ServiceAccount + token. Defaults to the `address` for the `generic` provider, or + to specific values for the other providers depending on the + provider. + - `serviceAccountName`: the optional name of the Kubernetes + ServiceAccount in the same namespace that should be used + for authentication. If not specified, the controller + ServiceAccount will be used. + + Mutually exclusive with SecretRef. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + secretRef: + description: |- + SecretRef holds an optional name of a secret that contains a key with + the kubeconfig file as the value. If no key is set, the key will default + to 'value'. Mutually exclusive with ConfigMapRef. + It is recommended that the kubeconfig is self-contained, and the secret + is regularly updated if credentials such as a cloud-access-token expire. + Cloud specific `cmd-path` auth helpers will not function without adding + binaries and credentials to the Pod that is responsible for reconciling + Kubernetes resources. Supported only for the generic provider. + properties: + key: + description: Key in the Secret, when not specified an implementation-specific + default key is used. + type: string + name: + description: Name of the Secret. + type: string + required: + - name + type: object + type: object + x-kubernetes-validations: + - message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef + must be specified + rule: has(self.configMapRef) || has(self.secretRef) + - message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef + must be specified + rule: '!has(self.configMapRef) || !has(self.secretRef)' + maxHistory: + description: |- + MaxHistory is the number of revisions saved by Helm for this HelmRelease. + Use '0' for an unlimited number of revisions; defaults to '5'. + type: integer + persistentClient: + description: |- + PersistentClient tells the controller to use a persistent Kubernetes + client for this release. When enabled, the client will be reused for the + duration of the reconciliation, instead of being created and destroyed + for each (step of a) Helm action. + + This can improve performance, but may cause issues with some Helm charts + that for example do create Custom Resource Definitions during installation + outside Helm's CRD lifecycle hooks, which are then not observed to be + available by e.g. post-install hooks. + + If not set, it defaults to true. + type: boolean + postRenderers: + description: |- + PostRenderers holds an array of Helm PostRenderers, which will be applied in order + of their definition. + items: + description: PostRenderer contains a Helm PostRenderer specification. + properties: + kustomize: + description: Kustomization to apply as PostRenderer. + properties: + images: + description: |- + Images is a list of (image name, new name, new tag or digest) + for changing image names, tags or digests. This can also be achieved with a + patch, but this operator is simpler to specify. + items: + description: Image contains an image name, a new name, + a new tag or digest, which will replace the original + name and tag. + properties: + digest: + description: |- + Digest is the value used to replace the original image tag. + If digest is present NewTag value is ignored. + type: string + name: + description: Name is a tag-less image name. + type: string + newName: + description: NewName is the value used to replace + the original name. + type: string + newTag: + description: NewTag is the value used to replace the + original tag. + type: string + required: + - name + type: object + type: array + patches: + description: |- + Strategic merge and JSON patches, defined as inline YAML objects, + capable of targeting objects based on kind, label and annotation selectors. + items: + description: |- + Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should + be applied to. + properties: + patch: + description: |- + Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with + an array of operation objects. + type: string + target: + description: Target points to the resources that the + patch document should be applied to. + properties: + annotationSelector: + description: |- + AnnotationSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource annotations. + type: string + group: + description: |- + Group is the API group to select resources from. + Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + kind: + description: |- + Kind of the API Group to select resources from. + Together with Group and Version it is capable of unambiguously + identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + labelSelector: + description: |- + LabelSelector is a string that follows the label selection expression + https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api + It matches with the resource labels. + type: string + name: + description: Name to match resources with. + type: string + namespace: + description: Namespace to select resources from. + type: string + version: + description: |- + Version of the API Group to select resources from. + Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. + https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md + type: string + type: object + required: + - patch + type: object + type: array + type: object + type: object + type: array + releaseName: + description: |- + ReleaseName used for the Helm release. Defaults to a composition of + '[TargetNamespace-]Name'. + maxLength: 53 + minLength: 1 + type: string + rollback: + description: Rollback holds the configuration for Helm rollback actions + for this HelmRelease. + properties: + cleanupOnFail: + description: |- + CleanupOnFail allows deletion of new resources created during the Helm + rollback action when it fails. + type: boolean + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm rollback action. + type: boolean + disableWait: + description: |- + DisableWait disables the waiting for resources to be ready after a Helm + rollback has been performed. + type: boolean + disableWaitForJobs: + description: |- + DisableWaitForJobs disables waiting for jobs to complete after a Helm + rollback has been performed. + type: boolean + force: + description: Force forces resource updates through a replacement + strategy. + type: boolean + recreate: + description: |- + Recreate performs pod restarts for any managed workloads. + + Deprecated: This behavior was deprecated in Helm 3: + - Deprecation: https://github.com/helm/helm/pull/6463 + - Removal: https://github.com/helm/helm/pull/31023 + After helm-controller was upgraded to the Helm 4 SDK, + this field is no longer functional and will print a + warning if set to true. It will also be removed in a + future release. + type: boolean + serverSideApply: + description: |- + ServerSideApply enables server-side apply for resources during rollback. + Can be "enabled", "disabled", or "auto". + When "auto", server-side apply usage will be based on the release's previous usage. + Defaults to "auto". + enum: + - enabled + - disabled + - auto + type: string + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm rollback action. Defaults to + 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + serviceAccountName: + description: |- + The name of the Kubernetes service account to impersonate + when reconciling this HelmRelease. + maxLength: 253 + minLength: 1 + type: string + storageNamespace: + description: |- + StorageNamespace used for the Helm storage. + Defaults to the namespace of the HelmRelease. + maxLength: 63 + minLength: 1 + type: string + suspend: + description: |- + Suspend tells the controller to suspend reconciliation for this HelmRelease, + it does not apply to already started reconciliations. Defaults to false. + type: boolean + targetNamespace: + description: |- + TargetNamespace to target when performing operations for the HelmRelease. + Defaults to the namespace of the HelmRelease. + maxLength: 63 + minLength: 1 + type: string + test: + description: Test holds the configuration for Helm test actions for + this HelmRelease. + properties: + enable: + description: |- + Enable enables Helm test actions for this HelmRelease after an Helm install + or upgrade action has been performed. + type: boolean + filters: + description: Filters is a list of tests to run or exclude from + running. + items: + description: Filter holds the configuration for individual Helm + test filters. + properties: + exclude: + description: Exclude specifies whether the named test should + be excluded. + type: boolean + name: + description: Name is the name of the test. + maxLength: 253 + minLength: 1 + type: string + required: + - name + type: object + type: array + ignoreFailures: + description: |- + IgnoreFailures tells the controller to skip remediation when the Helm tests + are run but fail. Can be overwritten for tests run after install or upgrade + actions in 'Install.IgnoreTestFailures' and 'Upgrade.IgnoreTestFailures'. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation during + the performance of a Helm test action. Defaults to 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like Jobs + for hooks) during the performance of a Helm action. Defaults to '5m0s'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + uninstall: + description: Uninstall holds the configuration for Helm uninstall + actions for this HelmRelease. + properties: + deletionPropagation: + default: background + description: |- + DeletionPropagation specifies the deletion propagation policy when + a Helm uninstall is performed. + enum: + - background + - foreground + - orphan + type: string + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm rollback action. + type: boolean + disableWait: + description: |- + DisableWait disables waiting for all the resources to be deleted after + a Helm uninstall is performed. + type: boolean + keepHistory: + description: |- + KeepHistory tells Helm to remove all associated resources and mark the + release as deleted, but retain the release history. + type: boolean + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm uninstall action. Defaults + to 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + upgrade: + description: Upgrade holds the configuration for Helm upgrade actions + for this HelmRelease. + properties: + cleanupOnFail: + description: |- + CleanupOnFail allows deletion of new resources created during the Helm + upgrade action when it fails. + type: boolean + crds: + description: |- + CRDs upgrade CRDs from the Helm Chart's crds directory according + to the CRD upgrade policy provided here. Valid values are `Skip`, + `Create` or `CreateReplace`. Default is `Skip` and if omitted + CRDs are neither installed nor upgraded. + + Skip: do neither install nor replace (update) any CRDs. + + Create: new CRDs are created, existing CRDs are neither updated nor deleted. + + CreateReplace: new CRDs are created, existing CRDs are updated (replaced) + but not deleted. + + By default, CRDs are not applied during Helm upgrade action. With this + option users can opt-in to CRD upgrade, which is not (yet) natively supported by Helm. + https://helm.sh/docs/chart_best_practices/custom_resource_definitions. + enum: + - Skip + - Create + - CreateReplace + type: string + disableHooks: + description: DisableHooks prevents hooks from running during the + Helm upgrade action. + type: boolean + disableOpenAPIValidation: + description: |- + DisableOpenAPIValidation prevents the Helm upgrade action from validating + rendered templates against the Kubernetes OpenAPI Schema. + type: boolean + disableSchemaValidation: + description: |- + DisableSchemaValidation prevents the Helm upgrade action from validating + the values against the JSON Schema. + type: boolean + disableTakeOwnership: + description: |- + DisableTakeOwnership disables taking ownership of existing resources + during the Helm upgrade action. Defaults to false. + type: boolean + disableWait: + description: |- + DisableWait disables the waiting for resources to be ready after a Helm + upgrade has been performed. + type: boolean + disableWaitForJobs: + description: |- + DisableWaitForJobs disables waiting for jobs to complete after a Helm + upgrade has been performed. + type: boolean + force: + description: Force forces resource updates through a replacement + strategy. + type: boolean + preserveValues: + description: |- + PreserveValues will make Helm reuse the last release's values and merge in + overrides from 'Values'. Setting this flag makes the HelmRelease + non-declarative. + type: boolean + remediation: + description: |- + Remediation holds the remediation configuration for when the Helm upgrade + action for the HelmRelease fails. The default is to not perform any action. + properties: + ignoreTestFailures: + description: |- + IgnoreTestFailures tells the controller to skip remediation when the Helm + tests are run after an upgrade action but fail. + Defaults to 'Test.IgnoreFailures'. + type: boolean + remediateLastFailure: + description: |- + RemediateLastFailure tells the controller to remediate the last failure, when + no retries remain. Defaults to 'false' unless 'Retries' is greater than 0. + type: boolean + retries: + description: |- + Retries is the number of retries that should be attempted on failures before + bailing. Remediation, using 'Strategy', is performed between each attempt. + Defaults to '0', a negative integer equals to unlimited retries. + type: integer + strategy: + description: Strategy to use for failure remediation. Defaults + to 'rollback'. + enum: + - rollback + - uninstall + type: string + type: object + serverSideApply: + description: |- + ServerSideApply enables server-side apply for resources during upgrade. + Can be "enabled", "disabled", or "auto". + When "auto", server-side apply usage will be based on the release's previous usage. + Defaults to "auto". + enum: + - enabled + - disabled + - auto + type: string + strategy: + description: |- + Strategy defines the upgrade strategy to use for this HelmRelease. + Defaults to 'RemediateOnFailure', or 'RetryOnFailure' when the + DefaultToRetryOnFailure feature gate is enabled. + properties: + name: + description: Name of the upgrade strategy. + enum: + - RemediateOnFailure + - RetryOnFailure + type: string + retryInterval: + description: |- + RetryInterval is the interval at which to retry a failed upgrade. + Can be used only when Name is set to RetryOnFailure. + Defaults to '5m'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: .retryInterval can only be set when .name is 'RetryOnFailure' + rule: '!has(self.retryInterval) || self.name == ''RetryOnFailure''' + timeout: + description: |- + Timeout is the time to wait for any individual Kubernetes operation (like + Jobs for hooks) during the performance of a Helm upgrade action. Defaults to + 'HelmReleaseSpec.Timeout'. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + type: object + values: + description: Values holds the values for this Helm release. + x-kubernetes-preserve-unknown-fields: true + valuesFrom: + description: |- + ValuesFrom holds references to resources containing Helm values for this HelmRelease, + and information about how they should be merged. + items: + description: |- + ValuesReference contains a reference to a resource containing Helm values, + and optionally the key they can be found at. + properties: + kind: + description: Kind of the values referent, valid values are ('Secret', + 'ConfigMap'). + enum: + - Secret + - ConfigMap + type: string + name: + description: |- + Name of the values referent. Should reside in the same namespace as the + referring resource. + maxLength: 253 + minLength: 1 + type: string + optional: + description: |- + Optional marks this ValuesReference as optional. When set, a not found error + for the values reference is ignored, but any ValuesKey, TargetPath or + transient error will still result in a reconciliation failure. + type: boolean + targetPath: + description: |- + TargetPath is the YAML dot notation path the value should be merged at. When + set, the ValuesKey is expected to be a single flat value. Defaults to 'None', + which results in the values getting merged at the root. + maxLength: 250 + pattern: ^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$ + type: string + valuesKey: + description: |- + ValuesKey is the data key where the values.yaml or a specific value can be + found at. Defaults to 'values.yaml'. + maxLength: 253 + pattern: ^[\-._a-zA-Z0-9]+$ + type: string + required: + - kind + - name + type: object + type: array + waitStrategy: + description: |- + WaitStrategy defines Helm's wait strategy for waiting for applied + resources to become ready. + properties: + name: + description: |- + Name is Helm's wait strategy for waiting for applied resources to + become ready. One of 'poller' or 'legacy'. The 'poller' strategy uses + kstatus to poll resource statuses, while the 'legacy' strategy uses + Helm v3's waiting logic. + Defaults to 'poller', or to 'legacy' when UseHelm3Defaults feature + gate is enabled. + enum: + - poller + - legacy + type: string + required: + - name + type: object + required: + - interval + type: object + x-kubernetes-validations: + - message: either chart or chartRef must be set + rule: (has(self.chart) && !has(self.chartRef)) || (!has(self.chart) + && has(self.chartRef)) + status: + default: + observedGeneration: -1 + description: HelmReleaseStatus defines the observed state of a HelmRelease. + properties: + conditions: + description: Conditions holds the conditions for the HelmRelease. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + failures: + description: |- + Failures is the reconciliation failure count against the latest desired + state. It is reset after a successful reconciliation. + format: int64 + type: integer + helmChart: + description: |- + HelmChart is the namespaced name of the HelmChart resource created by + the controller for the HelmRelease. + type: string + history: + description: |- + History holds the history of Helm releases performed for this HelmRelease + up to the last successfully completed release. + items: + description: |- + Snapshot captures a point-in-time copy of the status information for a Helm release, + as managed by the controller. + properties: + action: + description: Action is the action that resulted in this snapshot + being created. + type: string + apiVersion: + description: |- + APIVersion is the API version of the Snapshot. + When the calculation method of the Digest field is changed, this + field will be used to distinguish between the old and new methods. + type: string + appVersion: + description: AppVersion is the chart app version of the release + object in storage. + type: string + chartName: + description: ChartName is the chart name of the release object + in storage. + type: string + chartVersion: + description: |- + ChartVersion is the chart version of the release object in + storage. + type: string + configDigest: + description: |- + ConfigDigest is the checksum of the config (better known as + "values") of the release object in storage. + It has the format of `:`. + type: string + deleted: + description: Deleted is when the release was deleted. + format: date-time + type: string + digest: + description: |- + Digest is the checksum of the release object in storage. + It has the format of `:`. + type: string + firstDeployed: + description: FirstDeployed is when the release was first deployed. + format: date-time + type: string + lastDeployed: + description: LastDeployed is when the release was last deployed. + format: date-time + type: string + name: + description: Name is the name of the release. + type: string + namespace: + description: Namespace is the namespace the release is deployed + to. + type: string + ociDigest: + description: OCIDigest is the digest of the OCI artifact associated + with the release. + type: string + status: + description: Status is the current state of the release. + type: string + testHooks: + additionalProperties: + description: |- + TestHookStatus holds the status information for a test hook as observed + to be run by the controller. + properties: + lastCompleted: + description: LastCompleted is the time the test hook last + completed. + format: date-time + type: string + lastStarted: + description: LastStarted is the time the test hook was + last started. + format: date-time + type: string + phase: + description: Phase the test hook was observed to be in. + type: string + type: object + description: |- + TestHooks is the list of test hooks for the release as observed to be + run by the controller. + type: object + version: + description: Version is the version of the release object in + storage. + type: integer + required: + - chartName + - chartVersion + - configDigest + - digest + - firstDeployed + - lastDeployed + - name + - namespace + - status + - version + type: object + type: array + installFailures: + description: |- + InstallFailures is the install failure count against the latest desired + state. It is reset after a successful reconciliation. + format: int64 + type: integer + inventory: + description: |- + Inventory contains the list of Kubernetes resource object references + that have been applied for this release. + properties: + entries: + description: Entries of Kubernetes resource object references. + items: + description: ResourceRef contains the information necessary + to locate a resource within a cluster. + properties: + id: + description: |- + ID is the string representation of the Kubernetes resource object's metadata, + in the format '___'. + type: string + v: + description: Version is the API version of the Kubernetes + resource object's kind. + type: string + required: + - id + - v + type: object + type: array + required: + - entries + type: object + lastAttemptedConfigDigest: + description: |- + LastAttemptedConfigDigest is the digest for the config (better known as + "values") of the last reconciliation attempt. + type: string + lastAttemptedGeneration: + description: |- + LastAttemptedGeneration is the last generation the controller attempted + to reconcile. + format: int64 + type: integer + lastAttemptedReleaseAction: + description: |- + LastAttemptedReleaseAction is the last release action performed for this + HelmRelease. It is used to determine the active retry or remediation + strategy. + enum: + - install + - upgrade + type: string + lastAttemptedReleaseActionDuration: + description: |- + LastAttemptedReleaseActionDuration is the duration of the last + release action performed for this HelmRelease. + type: string + lastAttemptedRevision: + description: |- + LastAttemptedRevision is the Source revision of the last reconciliation + attempt. For OCIRepository sources, the 12 first characters of the digest are + appended to the chart version e.g. "1.2.3+1234567890ab". + type: string + lastAttemptedRevisionDigest: + description: |- + LastAttemptedRevisionDigest is the digest of the last reconciliation attempt. + This is only set for OCIRepository sources. + type: string + lastAttemptedValuesChecksum: + description: |- + LastAttemptedValuesChecksum is the SHA1 checksum for the values of the last + reconciliation attempt. + + Deprecated: Use LastAttemptedConfigDigest instead. + type: string + lastHandledForceAt: + description: |- + LastHandledForceAt holds the value of the most recent + force request value, so a change of the annotation value + can be detected. + type: string + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + lastHandledResetAt: + description: |- + LastHandledResetAt holds the value of the most recent reset request + value, so a change of the annotation value can be detected. + type: string + lastReleaseRevision: + description: |- + LastReleaseRevision is the revision of the last successful Helm release. + + Deprecated: Use History instead. + type: integer + observedCommonMetadataDigest: + description: |- + ObservedCommonMetadataDigest is the digest for the common metadata of + the last successful reconciliation attempt. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + observedPostRenderersDigest: + description: |- + ObservedPostRenderersDigest is the digest for the post-renderers of + the last successful reconciliation attempt. + type: string + storageNamespace: + description: |- + StorageNamespace is the namespace of the Helm release storage for the + current release. + maxLength: 63 + minLength: 1 + type: string + upgradeFailures: + description: |- + UpgradeFailures is the upgrade failure count against the latest desired + state. It is reset after a successful reconciliation. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: helm-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: helm-controller + namespace: flux-system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: helm-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + control-plane: controller + name: helm-controller + namespace: flux-system +spec: + replicas: 1 + selector: + matchLabels: + app: helm-controller + template: + metadata: + annotations: + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + labels: + app: helm-controller + app.kubernetes.io/component: helm-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + spec: + containers: + - args: + - --events-addr=http://notification-controller.$(RUNTIME_NAMESPACE).svc.cluster.local./ + - --watch-all-namespaces=true + - --log-level=info + - --log-encoding=json + - --enable-leader-election + env: + - name: RUNTIME_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + containerName: manager + resource: limits.memory + image: ghcr.io/fluxcd/helm-controller:v1.5.3 + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: healthz + name: manager + ports: + - containerPort: 8080 + name: http-prom + protocol: TCP + - containerPort: 9440 + name: healthz + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: healthz + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 100m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /tmp + name: temp + nodeSelector: + kubernetes.io/os: linux + priorityClassName: system-cluster-critical + securityContext: + fsGroup: 1337 + serviceAccountName: helm-controller + terminationGracePeriodSeconds: 600 + volumes: + - emptyDir: {} + name: temp +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: alerts.notification.toolkit.fluxcd.io +spec: + group: notification.toolkit.fluxcd.io + names: + kind: Alert + listKind: AlertList + plural: alerts + singular: alert + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta2 Alert is deprecated, upgrade to v1beta3 + name: v1beta2 + schema: + openAPIV3Schema: + description: Alert is the Schema for the alerts API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AlertSpec defines an alerting rule for events involving a + list of objects. + properties: + eventMetadata: + additionalProperties: + type: string + description: |- + EventMetadata is an optional field for adding metadata to events dispatched by the + controller. This can be used for enhancing the context of the event. If a field + would override one already present on the original event as generated by the emitter, + then the override doesn't happen, i.e. the original value is preserved, and an info + log is printed. + type: object + eventSeverity: + default: info + description: |- + EventSeverity specifies how to filter events based on severity. + If set to 'info' no events will be filtered. + enum: + - info + - error + type: string + eventSources: + description: |- + EventSources specifies how to filter events based + on the involved object kind, name and namespace. + items: + description: |- + CrossNamespaceObjectReference contains enough information to let you locate the + typed referenced object at cluster level + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: Kind of the referent + enum: + - Bucket + - GitRepository + - Kustomization + - HelmRelease + - HelmChart + - HelmRepository + - ImageRepository + - ImagePolicy + - ImageUpdateAutomation + - OCIRepository + - ArtifactGenerator + - ExternalArtifact + type: string + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + MatchLabels requires the name to be set to `*`. + type: object + name: + description: |- + Name of the referent + If multiple resources are targeted `*` may be set. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: Namespace of the referent + maxLength: 253 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + exclusionList: + description: |- + ExclusionList specifies a list of Golang regular expressions + to be used for excluding messages. + items: + type: string + type: array + inclusionList: + description: |- + InclusionList specifies a list of Golang regular expressions + to be used for including messages. + items: + type: string + type: array + providerRef: + description: ProviderRef specifies which Provider this Alert should + use. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + summary: + description: Summary holds a short description of the impact and affected + cluster. + maxLength: 255 + type: string + suspend: + description: |- + Suspend tells the controller to suspend subsequent + events handling for this Alert. + type: boolean + required: + - eventSources + - providerRef + type: object + status: + default: + observedGeneration: -1 + description: AlertStatus defines the observed state of the Alert. + properties: + conditions: + description: Conditions holds the conditions for the Alert. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta3 + schema: + openAPIV3Schema: + description: Alert is the Schema for the alerts API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: AlertSpec defines an alerting rule for events involving a + list of objects. + properties: + eventMetadata: + additionalProperties: + type: string + description: |- + EventMetadata is an optional field for adding metadata to events dispatched by the + controller. This can be used for enhancing the context of the event. If a field + would override one already present on the original event as generated by the emitter, + then the override doesn't happen, i.e. the original value is preserved, and an info + log is printed. + type: object + eventSeverity: + default: info + description: |- + EventSeverity specifies how to filter events based on severity. + If set to 'info' no events will be filtered. + enum: + - info + - error + type: string + eventSources: + description: |- + EventSources specifies how to filter events based + on the involved object kind, name and namespace. + items: + description: |- + CrossNamespaceObjectReference contains enough information to let you locate the + typed referenced object at cluster level + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: Kind of the referent + enum: + - Bucket + - GitRepository + - Kustomization + - HelmRelease + - HelmChart + - HelmRepository + - ImageRepository + - ImagePolicy + - ImageUpdateAutomation + - OCIRepository + - ArtifactGenerator + - ExternalArtifact + type: string + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + MatchLabels requires the name to be set to `*`. + type: object + name: + description: |- + Name of the referent + If multiple resources are targeted `*` may be set. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: Namespace of the referent + maxLength: 253 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + exclusionList: + description: |- + ExclusionList specifies a list of Golang regular expressions + to be used for excluding messages. + items: + type: string + type: array + inclusionList: + description: |- + InclusionList specifies a list of Golang regular expressions + to be used for including messages. + items: + type: string + type: array + providerRef: + description: ProviderRef specifies which Provider this Alert should + use. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + summary: + description: |- + Summary holds a short description of the impact and affected cluster. + Deprecated: Use EventMetadata instead. + maxLength: 255 + type: string + suspend: + description: |- + Suspend tells the controller to suspend subsequent + events handling for this Alert. + type: boolean + required: + - eventSources + - providerRef + type: object + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: providers.notification.toolkit.fluxcd.io +spec: + group: notification.toolkit.fluxcd.io + names: + kind: Provider + listKind: ProviderList + plural: providers + singular: provider + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta2 Provider is deprecated, upgrade to v1beta3 + name: v1beta2 + schema: + openAPIV3Schema: + description: Provider is the Schema for the providers API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ProviderSpec defines the desired state of the Provider. + properties: + address: + description: |- + Address specifies the endpoint, in a generic sense, to where alerts are sent. + What kind of endpoint depends on the specific Provider type being used. + For the generic Provider, for example, this is an HTTP/S address. + For other Provider types this could be a project ID or a namespace. + maxLength: 2048 + type: string + certSecretRef: + description: |- + CertSecretRef specifies the Secret containing + a PEM-encoded CA certificate (in the `ca.crt` key). + + Note: Support for the `caFile` key has + been deprecated. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + channel: + description: Channel specifies the destination channel where events + should be posted. + maxLength: 2048 + type: string + interval: + description: Interval at which to reconcile the Provider with its + Secret references. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + proxy: + description: Proxy the HTTP/S address of the proxy server. + maxLength: 2048 + pattern: ^(http|https)://.*$ + type: string + secretRef: + description: |- + SecretRef specifies the Secret containing the authentication + credentials for this Provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend subsequent + events handling for this Provider. + type: boolean + timeout: + description: Timeout for sending alerts to the Provider. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + type: + description: Type specifies which Provider implementation to use. + enum: + - slack + - discord + - msteams + - rocket + - generic + - generic-hmac + - github + - gitlab + - gitea + - bitbucketserver + - bitbucket + - azuredevops + - googlechat + - googlepubsub + - webex + - sentry + - azureeventhub + - telegram + - lark + - matrix + - opsgenie + - alertmanager + - grafana + - githubdispatch + - pagerduty + - datadog + type: string + username: + description: Username specifies the name under which events are posted. + maxLength: 2048 + type: string + required: + - type + type: object + status: + default: + observedGeneration: -1 + description: ProviderStatus defines the observed state of the Provider. + properties: + conditions: + description: Conditions holds the conditions for the Provider. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last reconciled generation. + format: int64 + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta3 + schema: + openAPIV3Schema: + description: Provider is the Schema for the providers API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ProviderSpec defines the desired state of the Provider. + properties: + address: + description: |- + Address specifies the endpoint, in a generic sense, to where alerts are sent. + What kind of endpoint depends on the specific Provider type being used. + For the generic Provider, for example, this is an HTTP/S address. + For other Provider types this could be a project ID or a namespace. + maxLength: 2048 + type: string + certSecretRef: + description: |- + CertSecretRef specifies the Secret containing TLS certificates + for secure communication. + + Supported configurations: + - CA-only: Server authentication (provide ca.crt only) + - mTLS: Mutual authentication (provide ca.crt + tls.crt + tls.key) + - Client-only: Client authentication with system CA (provide tls.crt + tls.key only) + + Legacy keys "caFile", "certFile", "keyFile" are supported but deprecated. Use "ca.crt", "tls.crt", "tls.key" instead. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + channel: + description: Channel specifies the destination channel where events + should be posted. + maxLength: 2048 + type: string + commitStatusExpr: + description: |- + CommitStatusExpr is a CEL expression that evaluates to a string value + that can be used to generate a custom commit status message for use + with eligible Provider types (github, gitlab, gitea, bitbucketserver, + bitbucket, azuredevops). Supported variables are: event, provider, + and alert. + type: string + interval: + description: |- + Interval at which to reconcile the Provider with its Secret references. + Deprecated and not used in v1beta3. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + proxy: + description: |- + Proxy the HTTP/S address of the proxy server. + Deprecated: Use ProxySecretRef instead. Will be removed in v1. + maxLength: 2048 + pattern: ^(http|https)://.*$ + type: string + proxySecretRef: + description: |- + ProxySecretRef specifies the Secret containing the proxy configuration + for this Provider. The Secret should contain an 'address' key with the + HTTP/S address of the proxy server. Optional 'username' and 'password' + keys can be provided for proxy authentication. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + secretRef: + description: |- + SecretRef specifies the Secret containing the authentication + credentials for this Provider. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + serviceAccountName: + description: |- + ServiceAccountName is the name of the Kubernetes ServiceAccount used to + authenticate with cloud provider services through workload identity. + This enables multi-tenant authentication without storing static credentials. + + Supported provider types: azureeventhub, azuredevops, googlepubsub + + When specified, the controller will: + 1. Create an OIDC token for the specified ServiceAccount + 2. Exchange it for cloud provider credentials via STS + 3. Use the obtained credentials for API authentication + + When unspecified, controller-level authentication is used (single-tenant). + + An error is thrown if static credentials are also defined in SecretRef. + This field requires the ObjectLevelWorkloadIdentity feature gate to be enabled. + type: string + suspend: + description: |- + Suspend tells the controller to suspend subsequent + events handling for this Provider. + type: boolean + timeout: + description: Timeout for sending alerts to the Provider. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ + type: string + type: + description: Type specifies which Provider implementation to use. + enum: + - slack + - discord + - msteams + - rocket + - generic + - generic-hmac + - github + - gitlab + - gitea + - giteapullrequestcomment + - bitbucketserver + - bitbucket + - azuredevops + - googlechat + - googlepubsub + - webex + - sentry + - azureeventhub + - telegram + - lark + - matrix + - opsgenie + - alertmanager + - grafana + - githubdispatch + - githubpullrequestcomment + - gitlabmergerequestcomment + - pagerduty + - datadog + - nats + - zulip + - otel + type: string + username: + description: Username specifies the name under which events are posted. + maxLength: 2048 + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: spec.commitStatusExpr is only supported for the 'github', 'gitlab', + 'gitea', 'bitbucketserver', 'bitbucket', 'azuredevops' provider types + rule: self.type == 'github' || self.type == 'gitlab' || self.type == + 'gitea' || self.type == 'bitbucketserver' || self.type == 'bitbucket' + || self.type == 'azuredevops' || !has(self.commitStatusExpr) + type: object + served: true + storage: true + subresources: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: receivers.notification.toolkit.fluxcd.io +spec: + group: notification.toolkit.fluxcd.io + names: + kind: Receiver + listKind: ReceiverList + plural: receivers + singular: receiver + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: Receiver is the Schema for the receivers API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ReceiverSpec defines the desired state of the Receiver. + properties: + events: + description: |- + Events specifies the list of event types to handle, + e.g. 'push' for GitHub or 'Push Hook' for GitLab. + items: + type: string + type: array + interval: + default: 10m + description: Interval at which to reconcile the Receiver with its + Secret references. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + resourceFilter: + description: |- + ResourceFilter is a CEL expression expected to return a boolean that is + evaluated for each resource referenced in the Resources field when a + webhook is received. If the expression returns false then the controller + will not request a reconciliation for the resource. + When the expression is specified the controller will parse it and mark + the object as terminally failed if the expression is invalid or does not + return a boolean. + type: string + resources: + description: A list of resources to be notified about changes. + items: + description: |- + CrossNamespaceObjectReference contains enough information to let you locate the + typed referenced object at cluster level + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: Kind of the referent + enum: + - Bucket + - GitRepository + - Kustomization + - HelmRelease + - HelmChart + - HelmRepository + - ImageRepository + - ImagePolicy + - ImageUpdateAutomation + - OCIRepository + - ArtifactGenerator + - ExternalArtifact + type: string + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + MatchLabels requires the name to be set to `*`. + type: object + name: + description: |- + Name of the referent + If multiple resources are targeted `*` may be set. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: Namespace of the referent + maxLength: 253 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + secretRef: + description: |- + SecretRef specifies the Secret containing the token used + to validate the payload authenticity. The Secret must contain a 'token' + key. For GCR receivers, the Secret must also contain an 'email' key + with the IAM service account email configured on the Pub/Sub push + subscription, and may optionally contain an 'audience' key with the + expected OIDC token audience. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend subsequent + events handling for this receiver. + type: boolean + type: + description: |- + Type of webhook sender, used to determine + the validation procedure and payload deserialization. + enum: + - generic + - generic-hmac + - github + - gitlab + - bitbucket + - harbor + - dockerhub + - quay + - gcr + - nexus + - acr + - cdevents + type: string + required: + - resources + - secretRef + - type + type: object + status: + default: + observedGeneration: -1 + description: ReceiverStatus defines the observed state of the Receiver. + properties: + conditions: + description: Conditions holds the conditions for the Receiver. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation of + the Receiver object. + format: int64 + type: integer + webhookPath: + description: |- + WebhookPath is the generated incoming webhook address in the format + of '/hook/sha256sum(token+name+namespace)'. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].message + name: Status + type: string + deprecated: true + deprecationWarning: v1beta2 Receiver is deprecated, upgrade to v1 + name: v1beta2 + schema: + openAPIV3Schema: + description: Receiver is the Schema for the receivers API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: ReceiverSpec defines the desired state of the Receiver. + properties: + events: + description: |- + Events specifies the list of event types to handle, + e.g. 'push' for GitHub or 'Push Hook' for GitLab. + items: + type: string + type: array + interval: + description: Interval at which to reconcile the Receiver with its + Secret references. + pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ + type: string + resources: + description: A list of resources to be notified about changes. + items: + description: |- + CrossNamespaceObjectReference contains enough information to let you locate the + typed referenced object at cluster level + properties: + apiVersion: + description: API version of the referent + type: string + kind: + description: Kind of the referent + enum: + - Bucket + - GitRepository + - Kustomization + - HelmRelease + - HelmChart + - HelmRepository + - ImageRepository + - ImagePolicy + - ImageUpdateAutomation + - OCIRepository + - ArtifactGenerator + - ExternalArtifact + type: string + matchLabels: + additionalProperties: + type: string + description: |- + MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + MatchLabels requires the name to be set to `*`. + type: object + name: + description: |- + Name of the referent + If multiple resources are targeted `*` may be set. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: Namespace of the referent + maxLength: 253 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + secretRef: + description: |- + SecretRef specifies the Secret containing the token used + to validate the payload authenticity. + properties: + name: + description: Name of the referent. + type: string + required: + - name + type: object + suspend: + description: |- + Suspend tells the controller to suspend subsequent + events handling for this receiver. + type: boolean + type: + description: |- + Type of webhook sender, used to determine + the validation procedure and payload deserialization. + enum: + - generic + - generic-hmac + - github + - gitlab + - bitbucket + - harbor + - dockerhub + - quay + - gcr + - nexus + - acr + type: string + required: + - resources + - secretRef + - type + type: object + status: + default: + observedGeneration: -1 + description: ReceiverStatus defines the observed state of the Receiver. + properties: + conditions: + description: Conditions holds the conditions for the Receiver. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + lastHandledReconcileAt: + description: |- + LastHandledReconcileAt holds the value of the most recent + reconcile request value, so a change of the annotation value + can be detected. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation of + the Receiver object. + format: int64 + type: integer + url: + description: |- + URL is the generated incoming webhook address in the format + of '/hook/sha256sum(token+name+namespace)'. + Deprecated: Replaced by WebhookPath. + type: string + webhookPath: + description: |- + WebhookPath is the generated incoming webhook address in the format + of '/hook/sha256sum(token+name+namespace)'. + type: string + type: object + type: object + served: true + storage: false + subresources: + status: {} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + name: notification-controller + namespace: flux-system +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + control-plane: controller + name: notification-controller + namespace: flux-system +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: http + selector: + app: notification-controller + type: ClusterIP +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + control-plane: controller + name: webhook-receiver + namespace: flux-system +spec: + ports: + - name: http + port: 80 + protocol: TCP + targetPort: http-webhook + selector: + app: notification-controller + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + control-plane: controller + name: notification-controller + namespace: flux-system +spec: + replicas: 1 + selector: + matchLabels: + app: notification-controller + template: + metadata: + annotations: + prometheus.io/port: "8080" + prometheus.io/scrape: "true" + labels: + app: notification-controller + app.kubernetes.io/component: notification-controller + app.kubernetes.io/instance: flux-system + app.kubernetes.io/part-of: flux + app.kubernetes.io/version: v2.8.5 + spec: + containers: + - args: + - --watch-all-namespaces=true + - --log-level=info + - --log-encoding=json + - --enable-leader-election + env: + - name: RUNTIME_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + containerName: manager + resource: limits.memory + image: ghcr.io/fluxcd/notification-controller:v1.8.3 + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: healthz + name: manager + ports: + - containerPort: 9090 + name: http + protocol: TCP + - containerPort: 9292 + name: http-webhook + protocol: TCP + - containerPort: 8080 + name: http-prom + protocol: TCP + - containerPort: 9440 + name: healthz + protocol: TCP + readinessProbe: + httpGet: + path: /readyz + port: healthz + resources: + limits: + cpu: 1000m + memory: 1Gi + requests: + cpu: 100m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /tmp + name: temp + nodeSelector: + kubernetes.io/os: linux + securityContext: + fsGroup: 1337 + serviceAccountName: notification-controller + terminationGracePeriodSeconds: 10 + volumes: + - emptyDir: {} + name: temp diff --git a/platform/fluxcd/git-repository.yaml b/platform/fluxcd/git-repository.yaml new file mode 100644 index 00000000..4257c3ab --- /dev/null +++ b/platform/fluxcd/git-repository.yaml @@ -0,0 +1,12 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: GitRepository +metadata: + name: github-source + namespace: flux-system +spec: + interval: 1m + url: https://github.com/EventTriangle/fluxcd + ref: + branch: main + # secretRef: + # name: flux-system \ No newline at end of file diff --git a/platform/helm-install-cert-manager/cert-manager-commands.ps1 b/platform/helm-install-cert-manager/cert-manager-commands.ps1 deleted file mode 100644 index 7f5b2f60..00000000 --- a/platform/helm-install-cert-manager/cert-manager-commands.ps1 +++ /dev/null @@ -1,5 +0,0 @@ -helm repo add jetstack https://charts.jetstack.io -helm repo update - -kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.12.0/cert-manager.crds.yaml -helm install cert-manager jetstack/cert-manager --namespace event-triangle \ No newline at end of file diff --git a/platform/helm-install-nginx-ingress/install-nginx-ingress-example.ps1 b/platform/helm-install-nginx-ingress/install-nginx-ingress-example.ps1 deleted file mode 100644 index 79adac64..00000000 --- a/platform/helm-install-nginx-ingress/install-nginx-ingress-example.ps1 +++ /dev/null @@ -1,6 +0,0 @@ -helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx -helm repo update -helm upgrade my-ingress --install ingress-nginx --repo https://kubernetes.github.io/ingress-nginx ` - --namespace ingress --set controller.service.externalTrafficPolicy=Local --create-namespace - -kubectl --namespace ingress get services my-ingress-ingress-nginx-controller \ No newline at end of file diff --git a/platform/helm-install-rabbit-mq/deploy-rabbitmq-example.ps1 b/platform/helm-install-rabbit-mq/deploy-rabbitmq-example.ps1 deleted file mode 100644 index 71e00967..00000000 --- a/platform/helm-install-rabbit-mq/deploy-rabbitmq-example.ps1 +++ /dev/null @@ -1,3 +0,0 @@ -kubectl apply -f "https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml" - -kubectl apply -f rabbit.yaml diff --git a/platform/helm-install-rabbit-mq/deploy-rabbitmq-helm.ps1 b/platform/helm-install-rabbit-mq/deploy-rabbitmq-helm.ps1 deleted file mode 100644 index 15338ba2..00000000 --- a/platform/helm-install-rabbit-mq/deploy-rabbitmq-helm.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -param( - [Parameter(Position = 0, Mandatory = $true)] - [string] $HelmReleaseName, - [Parameter(Position = 1, Mandatory = $true)] - [string] $Namespace, - [Parameter(Position = 2, Mandatory = $true)] - [string] $RabbitMqUsername, - [Parameter(Position = 3, Mandatory = $true)] - [string] $RabbitMqPassword -) - -$listReleases = $( helm list -n $Namespace ) -$releaseExists = $listReleases -match $HelmReleaseName - -if ($releaseExists) -{ - Write-Output "Release $HelmReleaseName already exists in namespace $Namespace. Skipping..." - return -} - -Write-Output "Release $HelmReleaseName does not exist in namespace $Namespace. Installing..." - -helm repo add bitnami https://charts.bitnami.com/bitnami -helm repo update -helm upgrade --install $HelmReleaseName bitnami/rabbitmq ` - --namespace $Namespace ` - --set auth.username=$RabbitMqUsername ` - --set auth.password=$RabbitMqPassword ` - --set service.type=LoadBalancer - -# example call: -# .\deploy-rabbitmq-helm.ps1 -HelmReleaseName "event-rabbitmq" -Namespace "event-triangle" -RabbitMqUsername "guest" -RabbitMqPassword "guest" \ No newline at end of file diff --git a/platform/helm-install-rabbit-mq/rabbit.yaml b/platform/helm-install-rabbit-mq/rabbit.yaml deleted file mode 100644 index e56144f1..00000000 --- a/platform/helm-install-rabbit-mq/rabbit.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: rabbitmq.com/v1beta1 -kind: RabbitmqCluster -metadata: - name: event-rabbitmq - namespace: event-triangle -spec: - replicas: 1 diff --git a/platform/helm-install-redis/Commands.ps1 b/platform/helm-install-redis/Commands.ps1 deleted file mode 100644 index c7f1f4d9..00000000 --- a/platform/helm-install-redis/Commands.ps1 +++ /dev/null @@ -1,20 +0,0 @@ -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/platform/namespace/Create-Namespace.ps1 b/platform/namespace/Create-Namespace.ps1 new file mode 100644 index 00000000..f30b09c3 --- /dev/null +++ b/platform/namespace/Create-Namespace.ps1 @@ -0,0 +1 @@ +kubectl create namespace event-triangle-dev --dry-run=client -o yaml | kubectl apply -f - diff --git a/platform/namespace/namespace.yaml b/platform/namespace/namespace.yaml deleted file mode 100644 index 60a94e6a..00000000 --- a/platform/namespace/namespace.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: event-triangle \ No newline at end of file diff --git a/platform/helm-install-nginx-ingress/deploy-ingress-helm.ps1 b/platform/nginx-ingress/Install-Nginx-Ingress.ps1 similarity index 82% rename from platform/helm-install-nginx-ingress/deploy-ingress-helm.ps1 rename to platform/nginx-ingress/Install-Nginx-Ingress.ps1 index 9ecfbe0e..2e4c03ae 100644 --- a/platform/helm-install-nginx-ingress/deploy-ingress-helm.ps1 +++ b/platform/nginx-ingress/Install-Nginx-Ingress.ps1 @@ -18,11 +18,11 @@ Write-Output "Release $HelmReleaseName does not exist in namespace $Namespace. I helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update -helm upgrade $HelmReleaseName --install ingress-nginx ` +helm upgrade --install $HelmReleaseName ingress-nginx ` --repo https://kubernetes.github.io/ingress-nginx ` --namespace $Namespace ` --set controller.service.externalTrafficPolicy=Local ` --create-namespace # example call: -# .\deploy-ingress-helm.ps1 -HelmReleaseName "event-ingress" -Namespace "event-triangle" \ No newline at end of file +# .\nginx-ingress\Install-Nginx-Ingress.ps1 -HelmReleaseName "nginx-ingress-dev" -Namespace "ing-dev" diff --git a/platform/pgsql-deployment/pgsql-service.yaml b/platform/pgsql-deployment/pgsql-service.yaml deleted file mode 100644 index c5c4d5bb..00000000 --- a/platform/pgsql-deployment/pgsql-service.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - name: postgres-service - namespace: event-triangle - labels: - app: postgresdb -spec: - type: ClusterIP - ports: - - port: 5432 - selector: - app: postgresdb diff --git a/platform/postgres/Deploy-Postgres.ps1 b/platform/postgres/Deploy-Postgres.ps1 new file mode 100644 index 00000000..4d22df2f --- /dev/null +++ b/platform/postgres/Deploy-Postgres.ps1 @@ -0,0 +1,28 @@ +param( + [Parameter(Position = 0, Mandatory = $true)] + [string] $HelmReleaseName, + [Parameter(Position = 1, Mandatory = $true)] + [string] $Namespace +) + +# Set error handling and preferences +$ErrorActionPreference = "Stop" + +Write-Host "Changing directory to PSScriptRoot ..." + +Set-Location $PSScriptRoot + +$listReleases = $( helm list -n $Namespace ) +$releaseExists = $listReleases -match $HelmReleaseName + +if ($releaseExists) +{ + Write-Output "Release $HelmReleaseName already exists in namespace $Namespace. Skipping..." + return +} + +Write-Output "Release $HelmReleaseName does not exist in namespace $Namespace. Installing..." + +helm upgrade --install pgsql-dev .\pgsql-helm\ --values .\pgsql-helm\values.yaml --namespace pgsql-dev --create-namespace + +# .\Deploy-Postgres.ps1 -HelmReleaseName "pgsql-dev" -Namespace "pgsql-dev" diff --git a/platform/postgres/pgsql-helm/.helmignore b/platform/postgres/pgsql-helm/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/platform/postgres/pgsql-helm/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/platform/postgres/pgsql-helm/Chart.yaml b/platform/postgres/pgsql-helm/Chart.yaml new file mode 100644 index 00000000..021b8913 --- /dev/null +++ b/platform/postgres/pgsql-helm/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: pgsql-helm +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/platform/pgsql-deployment/pgsql-deployment.yaml b/platform/postgres/pgsql-helm/templates/deployment.yaml similarity index 68% rename from platform/pgsql-deployment/pgsql-deployment.yaml rename to platform/postgres/pgsql-helm/templates/deployment.yaml index 1688ac5b..535b2812 100644 --- a/platform/pgsql-deployment/pgsql-deployment.yaml +++ b/platform/postgres/pgsql-helm/templates/deployment.yaml @@ -1,21 +1,20 @@ ---- apiVersion: apps/v1 kind: Deployment metadata: - name: postgresdb - namespace: event-triangle + name: {{ .Release.Name }}-deployment + namespace: {{ .Values.namespace }} spec: replicas: 1 selector: matchLabels: - app: postgresdb + app: {{ .Release.Name }} template: metadata: labels: - app: postgresdb + app: {{ .Release.Name }} spec: containers: - - name: postgresdb + - name: {{ .Release.Name }} image: postgres:latest ports: - containerPort: 5432 @@ -23,17 +22,17 @@ spec: - name: POSTGRES_USER valueFrom: secretKeyRef: - name: connection-creds + name: {{ .Release.Name }}-secrets key: POSTGRES_USER - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: - name: connection-creds + name: {{ .Release.Name }}-secrets key: POSTGRES_PASSWORD - name: POSTGRES_DB valueFrom: secretKeyRef: - name: connection-creds + name: {{ .Release.Name }}-secrets key: POSTGRES_DB volumeMounts: - mountPath: /var/lib/postgres/data @@ -41,4 +40,4 @@ spec: volumes: - name: db-data persistentVolumeClaim: - claimName: db-persistent-volume-claim + claimName: {{ .Release.Name }}-pvc diff --git a/platform/pgsql-deployment/pgsql-pv-claim.yaml b/platform/postgres/pgsql-helm/templates/pv-claim.yaml similarity index 70% rename from platform/pgsql-deployment/pgsql-pv-claim.yaml rename to platform/postgres/pgsql-helm/templates/pv-claim.yaml index dbcea5fb..dee2e583 100644 --- a/platform/pgsql-deployment/pgsql-pv-claim.yaml +++ b/platform/postgres/pgsql-helm/templates/pv-claim.yaml @@ -1,9 +1,8 @@ ---- apiVersion: v1 kind: PersistentVolumeClaim metadata: - name: db-persistent-volume-claim - namespace: event-triangle + name: {{ .Release.Name }}-pvc + namespace: {{ .Values.namespace }} spec: storageClassName: manual accessModes: diff --git a/platform/pgsql-deployment/pgsql-pv.yaml b/platform/postgres/pgsql-helm/templates/pv.yaml similarity index 67% rename from platform/pgsql-deployment/pgsql-pv.yaml rename to platform/postgres/pgsql-helm/templates/pv.yaml index 02b57c8e..4893e268 100644 --- a/platform/pgsql-deployment/pgsql-pv.yaml +++ b/platform/postgres/pgsql-helm/templates/pv.yaml @@ -1,12 +1,11 @@ ---- apiVersion: v1 kind: PersistentVolume metadata: - name: postgresdb-persistent-volume - namespace: event-triangle + name: {{ .Release.Name }}-pv + namespace: {{ .Values.namespace }} labels: type: local - app: postgresdb + app: {{ .Release.Name }} spec: storageClassName: manual capacity: diff --git a/platform/postgres/pgsql-helm/templates/secrets.yaml b/platform/postgres/pgsql-helm/templates/secrets.yaml new file mode 100644 index 00000000..182969d0 --- /dev/null +++ b/platform/postgres/pgsql-helm/templates/secrets.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }}-secrets + namespace: {{ .Values.namespace }} +type: Opaque +stringData: + POSTGRES_USER: {{ .Values.username }} + POSTGRES_PASSWORD: {{ .Values.password }} + POSTGRES_DB: postgres diff --git a/platform/postgres/pgsql-helm/templates/service.yaml b/platform/postgres/pgsql-helm/templates/service.yaml new file mode 100644 index 00000000..6deab55c --- /dev/null +++ b/platform/postgres/pgsql-helm/templates/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-service + namespace: {{ .Values.namespace }} + labels: + app: {{ .Release.Name }}-service +spec: + type: ClusterIP + ports: + - port: 5432 + selector: + app: {{ .Release.Name }} diff --git a/platform/postgres/pgsql-helm/values.yaml b/platform/postgres/pgsql-helm/values.yaml new file mode 100644 index 00000000..84c6e06e --- /dev/null +++ b/platform/postgres/pgsql-helm/values.yaml @@ -0,0 +1,5 @@ +namespace: "pgsql-dev" + +username: "postgres" + +password: "s8SefXkZZlqd" diff --git a/platform/helm-install-grafana-prometheus/Example.ps1 b/platform/prometheus-grafana/Example.ps1 similarity index 100% rename from platform/helm-install-grafana-prometheus/Example.ps1 rename to platform/prometheus-grafana/Example.ps1 diff --git a/platform/helm-install-grafana-prometheus/monitoring-http-nginx-ingress.yaml b/platform/prometheus-grafana/monitoring-http-nginx-ingress.yaml similarity index 100% rename from platform/helm-install-grafana-prometheus/monitoring-http-nginx-ingress.yaml rename to platform/prometheus-grafana/monitoring-http-nginx-ingress.yaml diff --git a/platform/rabbitmq/Install-RabbitMq.ps1 b/platform/rabbitmq/Install-RabbitMq.ps1 new file mode 100644 index 00000000..98233dc2 --- /dev/null +++ b/platform/rabbitmq/Install-RabbitMq.ps1 @@ -0,0 +1,100 @@ +param( + [Parameter(Mandatory = $true)] + [string] $RabbitMqNamespace, + + [Parameter(Mandatory = $true)] + [string] $RabbitMqClusterName +) + +$ErrorActionPreference = "Stop" + +# ---------------------------------------------------- +# 1. CHECK IF CLUSTER EXISTS +# ---------------------------------------------------- +Write-Host "Checking if RabbitMQ cluster exists..." + +$existing = kubectl get rabbitmqcluster $RabbitMqClusterName -n $RabbitMqNamespace --ignore-not-found + +if ($existing) { + Write-Host "RabbitMQ cluster already exists. Skipping installation." + exit 0 +} + +# ---------------------------------------------------- +# 2. INSTALL OPERATOR +# ---------------------------------------------------- +Write-Host "Installing RabbitMQ Cluster Operator..." + +kubectl apply -f "https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml" + +# ---------------------------------------------------- +# 3. WAIT FOR CRD +# ---------------------------------------------------- +Write-Host "Waiting for CRDs..." + +kubectl wait --for=condition=Established crd/rabbitmqclusters.rabbitmq.com --timeout=120s + +# ---------------------------------------------------- +# 4. WAIT FOR OPERATOR +# ---------------------------------------------------- +Write-Host "Waiting for operator rollout..." + +kubectl rollout status deployment/rabbitmq-cluster-operator -n rabbitmq-system --timeout=180s + +# ---------------------------------------------------- +# 5. CREATE NAMESPACE (SAFE / IDEMPOTENT) +# ---------------------------------------------------- +Write-Host "Ensuring namespace exists..." + +kubectl create namespace $RabbitMqNamespace --dry-run=client -o yaml | kubectl apply -f - + +# ---------------------------------------------------- +# 6. APPLY RABBITMQ CLUSTER +# ---------------------------------------------------- +Write-Host "Creating RabbitMQ cluster..." + +$yaml = @" +apiVersion: rabbitmq.com/v1beta1 +kind: RabbitmqCluster +metadata: + name: $RabbitMqClusterName + namespace: $RabbitMqNamespace +spec: + replicas: 1 +"@ + +$yaml | kubectl apply -f - + +# ---------------------------------------------------- +# 7. WAIT FOR CLUSTER READINESS (IMPORTANT PART) +# ---------------------------------------------------- +Write-Host "Waiting for RabbitMQ cluster to become Ready..." + +do { + $json = kubectl get rabbitmqcluster $RabbitMqClusterName -n $RabbitMqNamespace -o json | ConvertFrom-Json + + $conditions = $json.status.conditions + + $allReplicasReady = ($conditions | Where-Object { $_.type -eq "AllReplicasReady" }).status + $reconcileSuccess = ($conditions | Where-Object { $_.type -eq "ReconcileSuccess" }).status + + Write-Host "AllReplicasReady=$allReplicasReady ReconcileSuccess=$reconcileSuccess" + + $ready = ($allReplicasReady -eq "True" -and $reconcileSuccess -eq "True") + + if (-not $ready) { + Start-Sleep 5 + } + +} while (-not $ready) + +Write-Host "RabbitMQ cluster is READY" + +# ---------------------------------------------------- +# 8. OPTIONAL: VERIFY PODS +# ---------------------------------------------------- +Write-Host "Verifying pods..." + +kubectl get pods -n $RabbitMqNamespace + +# .\rabbitmq\Install-RabbitMq.ps1 -RabbitMqNamespace "rabbitmq-dev" -RabbitMqClusterName "rabbitmq-cluster" diff --git a/platform/rabbitmq/Uninstall-RabbitMq.ps1 b/platform/rabbitmq/Uninstall-RabbitMq.ps1 new file mode 100644 index 00000000..c449a3ad --- /dev/null +++ b/platform/rabbitmq/Uninstall-RabbitMq.ps1 @@ -0,0 +1,72 @@ +param( + [Parameter(Mandatory = $true)] + [string] $RabbitMqNamespace, + + [Parameter(Mandatory = $true)] + [string] $RabbitMqClusterName +) + +$ErrorActionPreference = "Stop" + +Write-Host "Checking if RabbitMQ cluster exists..." + +$exists = kubectl get rabbitmqcluster $RabbitMqClusterName -n $RabbitMqNamespace --ignore-not-found + +if (-not $exists) { + Write-Host "Cluster does not exist. Skipping deletion." + exit 0 +} + +# ---------------------------------------------------- +# 1. DELETE RABBITMQ CLUSTER (CR) +# ---------------------------------------------------- +Write-Host "Deleting RabbitMQ cluster CR..." + +kubectl delete rabbitmqcluster $RabbitMqClusterName -n $RabbitMqNamespace --wait=true + +# ---------------------------------------------------- +# 2. WAIT UNTIL PODS ARE GONE +# ---------------------------------------------------- +Write-Host "Waiting for RabbitMQ pods to terminate..." + +while (kubectl get pods -n $RabbitMqNamespace -l app.kubernetes.io/name=rabbitmq --no-headers 2>$null) { + Write-Host "Pods still terminating..." + Start-Sleep 5 +} + +# ---------------------------------------------------- +# 3. DELETE PVCs (VERY IMPORTANT) +# ---------------------------------------------------- +Write-Host "Deleting PVCs..." + +kubectl delete pvc -n $RabbitMqNamespace --all --wait=true + +# ---------------------------------------------------- +# 4. DELETE OPERATOR +# ---------------------------------------------------- +Write-Host "Deleting RabbitMQ Cluster Operator..." + +kubectl delete -f "https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml" --ignore-not-found + +# ---------------------------------------------------- +# 5. FORCE CLEANUP NAMESPACE (SAFE ONLY AFTER ABOVE) +# ---------------------------------------------------- +Write-Host "Final namespace cleanup..." + +do { + + kubectl delete namespace $RabbitMqNamespace --grace-period=0 --force + + Start-Sleep 5; + + $namespaces = kubectl get namespace + + $exists = $namespace -match $RabbitMqNamespace + + Write-Host "Namespace $RabbitMqNamespace exists: $exists" + +} while ($exists) + +Write-Host "Cleanup completed." + +# .\rabbitmq\Uninstall-RabbitMq.ps1 -RabbitMqNamespace "rabbitmq-dev" -RabbitMqClusterName "rabbitmq-cluster" diff --git a/platform/redis/Install-Redis.ps1 b/platform/redis/Install-Redis.ps1 new file mode 100644 index 00000000..9b6b6042 --- /dev/null +++ b/platform/redis/Install-Redis.ps1 @@ -0,0 +1,31 @@ +param( + [Parameter(Mandatory = $true)] + [string] $Namespace, + [Parameter(Mandatory = $true)] + [string] $HelmRelease, + [Parameter(Mandatory = $true)] + [string] $Password +) + +$listReleases = $( helm list -n $Namespace ) +$releaseExists = $listReleases -match $HelmRelease + +if ($releaseExists) +{ + Write-Output "Release $HelmRelease already exists in namespace $Namespace. Skipping..." + exit 0 +} + +Write-Host "Release $HelmRelease does not exist. Installing it ..." + +helm repo add bitnami https://charts.bitnami.com/bitnami + +helm repo update + +helm upgrade --install $HelmRelease bitnami/redis ` +--namespace $Namespace ` +--set auth.enabled=true ` +--set auth.password="$Password" ` +--create-namespace + +# .\redis\Install-Redis.ps1 -Namespace "redis-dev" -HelmRelease "redis-server-dev" -Password "qwerty12345" diff --git a/scripts/Build-Docker.ps1 b/scripts/Build-Docker.ps1 index b68baad8..464c4cd6 100644 --- a/scripts/Build-Docker.ps1 +++ b/scripts/Build-Docker.ps1 @@ -17,6 +17,9 @@ param ( [Parameter(Mandatory = $true)] [string]$GitVersion, + [Parameter(Mandatory = $true)] + [string]$CommitSha, + [Parameter(Mandatory = $true)] [string]$WorkingDirectory ) @@ -25,16 +28,22 @@ Write-Output "Changing directory to $WorkingDirectory" Set-Location $WorkingDirectory # Define image tags -$GIT_VERSION_IMAGE = "$DockerRegistryUrl/$ImageRepository`:$gitVersion" +$GIT_VERSION_IMAGE = "$DockerRegistryUrl/$ImageRepository`:$GitVersion" $LATEST_VERSION_IMAGE = "$DockerRegistryUrl/$ImageRepository`:latest" -$ACR_GIT_VERSION_IMAGE = "$AcrRegistryUrl/$ImageRepository`:$gitVersion" +$SHA_TAG = "$DockerRegistryUrl/$ImageRepository`:$GitVersion-$CommitSha" + +$ACR_GIT_VERSION_IMAGE = "$AcrRegistryUrl/$ImageRepository`:$GitVersion" $ACR_LATEST_VERSION_IMAGE = "$AcrRegistryUrl/$ImageRepository`:latest" +$ACR_SHA_TAG = "$AcrRegistryUrl/$ImageRepository`:$GitVersion-$CommitSha" # Output image tags Write-Output "DOCKERHUB_GIT_VERSION_IMAGE: $GIT_VERSION_IMAGE" Write-Output "DOCKERHUB_GIT_LATEST_VERSION_IMAGE: $LATEST_VERSION_IMAGE" +Write-Output "DOCKERHUB_SHA_VERSION_IMAGE: $SHA_TAG" + Write-Output "ACR_GIT_VERSION_IMAGE: $ACR_GIT_VERSION_IMAGE" Write-Output "ACR_LATEST_VERSION_IMAGE: $ACR_LATEST_VERSION_IMAGE" +Write-Output "ACR_SHA_IMAGE: $ACR_SHA_TAG" # Build the Docker image docker build --build-arg FRONT_API_URL="$DockerBuildParameterUrl" ` @@ -46,6 +55,8 @@ docker build --build-arg FRONT_API_URL="$DockerBuildParameterUrl" ` docker tag "$GIT_VERSION_IMAGE" "$LATEST_VERSION_IMAGE" docker tag "$GIT_VERSION_IMAGE" "$ACR_LATEST_VERSION_IMAGE" docker tag "$GIT_VERSION_IMAGE" "$ACR_GIT_VERSION_IMAGE" +docker tag "$GIT_VERSION_IMAGE" "$SHA_TAG" +docker tag "$GIT_VERSION_IMAGE" "$ACR_SHA_TAG" # List images docker image ls diff --git a/scripts/Deploy-Helm-Chart.ps1 b/scripts/Deploy-Helm-Chart.ps1 deleted file mode 100644 index b35d9ff8..00000000 --- a/scripts/Deploy-Helm-Chart.ps1 +++ /dev/null @@ -1,40 +0,0 @@ -param ( - [string]$HelmChartsFolder = "E:\RiderProjects\02_DOTNET_PROJECTS\EventTriangleAPI\helm", - [string]$ChartName = "auth-service-chart", - [string]$Version, - [string]$Namespace = "event-triangle", - [bool]$UseAcr = $true, - [string]$AcrRegistryUrl = "azuredevopsacrd01.azurecr.io" -) - -# Check if version is empty -if ([string]::IsNullOrEmpty($Version)) { - Write-Output "Version is empty, setting up to latest" - $Version = "latest" -} - -$ChartMap = @{ } -$ChartMap["auth-service-chart"] = "auth-service" -$ChartMap["consumer-service-chart"] = "consumer-service" -$ChartMap["sender-service-chart"] = "sender-service" - -$Image = $ChartMap[$ChartName] - -Write-Output "Version: $Version" -Write-Output "Deploying Helm chart..." - -# Determine image repository -if ($UseAcr) { - $ImageRepository = "$AcrRegistryUrl/$Image" -} else { - $ImageRepository = "kaminome/$Image" -} - -Write-Output "Image repository: $ImageRepository" - -# Execute Helm upgrade/install command -helm upgrade --install $ChartName "$HelmChartsFolder/$ChartName" ` - --values "$HelmChartsFolder/$ChartName/values.yaml" ` - --set image.tag="$Version" ` - --set image.repository="$ImageRepository" ` - --namespace "$Namespace" diff --git a/scripts/Test-Encoding.ps1 b/scripts/Test-Encoding.ps1 new file mode 100644 index 00000000..88cd497d --- /dev/null +++ b/scripts/Test-Encoding.ps1 @@ -0,0 +1,191 @@ +# SPDX-FileCopyrightText: 2020-2026 VerifyEncoding contributors +# +# SPDX-License-Identifier: MIT + +<# +.SYNOPSIS + This function will verify that there's no UTF-8 BOM or CRLF line endings in the files inside of the project. +#> + +param ( + [string] $SourceRoot, + [switch] $Autofix, + [string[]] $ExcludeExtensions = @( + '.dotsettings' + ), + [string[]] $ExcludePatterns = @() +) + +function Test-Encoding +{ + param ( + # Path to the repository root. All text files under the root will be checked for UTF-8 BOM and CRLF. + # + # By default (if nothing's passed), the script will try auto-detecting the nearest Git root. + [string] $SourceRoot, + + # Makes the script to perform file modifications to bring them to the standard. + [switch] $Autofix, + + # List of file extensions (with leading dots) to ignore. Case-insensitive. + [string[]] $ExcludeExtensions = @( + '.dotsettings' + ), + + # List of glob patterns to ignore. Matched against both the leaf file name and the full relative path. + # For example, '*.Designer.cs' will exclude all files whose name ends in '.Designer.cs'. + [string[]] $ExcludePatterns = @() + ) + + Set-StrictMode -Version Latest + $ErrorActionPreference = 'Stop' + + if (!$SourceRoot) + { + $SourceRoot = git rev-parse --show-toplevel + + if (!$?) + { + throw "Cannot call `"git rev-parse`": exit code $LASTEXITCODE." + } + } + + # For PowerShell to properly process the UTF-8 output from git ls-tree we need to set up the output encoding: + [Console]::OutputEncoding = [Text.Encoding]::UTF8 + + try + { + Push-Location $SourceRoot + + # Step 1: Get all file paths from git + $gitFiles = git -c core.quotepath=off ls-tree -r HEAD --name-only + + # Step 2: Filter out deleted files + $existingFiles = $gitFiles | Where-Object { Test-Path -LiteralPath $_ } + + # Step 3: Filter out directories (keep only files) + $allFiles = @($existingFiles | Where-Object { -not (Get-Item -Force -LiteralPath $_).PSIsContainer }) + + if (!$?) + { + throw "Cannot call `"git ls-tree`": exit code $LASTEXITCODE." + } + + Write-Output "Total files in the repository: $($allFiles.Length)" + + $counter = [pscustomobject]@{ Value = 0 } + + $groupSize = 50 + + $chunks = @($allFiles | Group-Object -Property { [math]::Floor($counter.Value++ / $groupSize) }) + + Write-Output "Split into $( $chunks.Count ) chunks." + + # https://stackoverflow.com/questions/6119956/how-to-determine-if-git-handles-a-file-as-binary-or-as-text#comment15281840_6134127 + $nullHash = '4b825dc642cb6eb9a060e54bf8d69288fbee4904' + + $textFiles = @($chunks | ForEach-Object { + $chunk = $_.Group + $filePaths = git -c core.quotepath=off diff --numstat $nullHash HEAD -- @chunk + if (!$?) + { + throw "Cannot call `"git diff`": exit code $LASTEXITCODE." + } + $filePaths | + Where-Object { -not $_.StartsWith('-') } | + ForEach-Object { [Regex]::Unescape($_.Split("`t", 3)[2]) } + }) + + Write-Output "Text files in the repository: $( $textFiles.Length )" + + $bom = @(0xEF, 0xBB, 0xBF) + $bomErrors = @() + $lineEndingErrors = @() + + foreach ($file in $textFiles) + { + if ($ExcludeExtensions -contains [IO.Path]::GetExtension($file).ToLowerInvariant()) + { + continue + } + + $leafName = [IO.Path]::GetFileName($file) + if ($ExcludePatterns | Where-Object { $leafName -like $_ -or $file -like $_ }) + { + continue + } + + $fullPath = Resolve-Path -LiteralPath $file + + $bytes = [IO.File]::ReadAllBytes($fullPath) | Select-Object -First $bom.Length + + # filter empty files + if (!$bytes) + { + continue + } + + $bytesEqualsBom = @(Compare-Object $bytes $bom -SyncWindow 0).Length -eq 0 + + if ($bytesEqualsBom -and $Autofix) + { + $fullContent = [IO.File]::ReadAllBytes($fullPath) + + if ($fullContent.Count -le $bom.Length) + { + Write-Output "Removed UTF-8 BOM from file $file" + [IO.File]::WriteAllBytes($fullPath, @()) + continue + } + + $newContent = $fullContent | Select-Object -Skip $bom.Length + [IO.File]::WriteAllBytes($fullPath, $newContent) + Write-Output "Removed UTF-8 BOM from file $file" + } + elseif ($bytesEqualsBom) + { + $bomErrors += @($file) + } + + $text = [IO.File]::ReadAllText($fullPath) + + $crlf = "`r`n" + $lf = "`n" + $cr = "`r" + + $hasWrongLineEndings = $text.Contains($crlf) -or $text.Contains($cr) + + if ($hasWrongLineEndings -and $Autofix) + { + $newText = $text -replace $crlf, $lf -replace $cr, $lf + [IO.File]::WriteAllText($fullPath, $newText) + Write-Output "Fixed the line endings for file $file" + } + elseif ($hasWrongLineEndings) + { + $lineEndingErrors += @($file) + } + } + + if ($bomErrors.Length) + { + throw "The following $( $bomErrors.Length ) files have UTF-8 BOM:`n" + ($bomErrors -join "`n") + } + if ($lineEndingErrors.Length) + { + throw "The following $( $lineEndingErrors.Length ) files have CRLF instead of LF:`n" + ($lineEndingErrors -join "`n") + } + } + finally + { + Pop-Location + } +} + +# Convenience launch mode when not invoked as part of a module: +if (!$MyInvocation.PSCommandPath -or !$MyInvocation.PSCommandPath.EndsWith('.psm1')) { + Write-Output "Direct script launcher mode.$(if ($MyInvocation.PSCommandPath) { + ' Launched from "' + $MyInvocation.PSCommandPath + '".' + })" + Test-Encoding -SourceRoot:$SourceRoot -Autofix:$Autofix -ExcludeExtensions:$ExcludeExtensions -ExcludePatterns:$ExcludePatterns +} diff --git a/scripts/verify-encoding.ps1 b/scripts/verify-encoding.ps1 deleted file mode 100644 index 41691507..00000000 --- a/scripts/verify-encoding.ps1 +++ /dev/null @@ -1,111 +0,0 @@ -# SPDX-FileCopyrightText: 2020-2025 Friedrich von Never -# -# SPDX-License-Identifier: MIT - -<# -.SYNOPSIS - encoding-verifier v2.0.1. - - This script will verify that there's no UTF-8 BOM or CRLF line endings in the files inside of the project. - - https://github.com/ForNeVeR/encoding-verifier -#> -param ( -# Path to the repository root. All text files under the root will be checked for UTF-8 BOM and CRLF. -# -# By default (if nothing's passed), the script will try auto-detecting the nearest Git root. - [string] $SourceRoot, - -# Makes the script to perform file modifications to bring them to the standard. - [switch] $Autofix, - -# List of file extensions (with leading dots) to ignore. Case-insensitive. - [string[]] $ExcludeExtensions = @( - '.dotsettings' -) -) - -Set-StrictMode -Version Latest -$ErrorActionPreference = 'Stop' - -if (!$SourceRoot) { - $SourceRoot = git rev-parse --show-toplevel - if (!$?) { - throw "Cannot call `"git rev-parse`": exit code $LASTEXITCODE." - } -} - -# For PowerShell to properly process the UTF-8 output from git ls-tree we need to set up the output encoding: -[Console]::OutputEncoding = [Text.Encoding]::UTF8 - -try { - Push-Location $SourceRoot - [array] $allFiles = git -c core.quotepath=off ls-tree -r HEAD --name-only - if (!$?) { - throw "Cannot call `"git ls-tree`": exit code $LASTEXITCODE." - } - Write-Output "Total files in the repository: $($allFiles.Length)" - - $counter = [pscustomobject] @{ Value = 0 } - $groupSize = 50 - [array] $chunks = $allFiles | Group-Object -Property { [math]::Floor($counter.Value++ / $groupSize) } - Write-Output "Split into $($chunks.Count) chunks." - - # https://stackoverflow.com/questions/6119956/how-to-determine-if-git-handles-a-file-as-binary-or-as-text#comment15281840_6134127 - $nullHash = '4b825dc642cb6eb9a060e54bf8d69288fbee4904' - $textFiles = $chunks | ForEach-Object { - $chunk = $_.Group - $filePaths = git -c core.quotepath=off diff --numstat $nullHash HEAD -- @chunk - if (!$?) { - throw "Cannot call `"git diff`": exit code $LASTEXITCODE." - } - $filePaths | - Where-Object { -not $_.StartsWith('-') } | - ForEach-Object { [Regex]::Unescape($_.Split("`t", 3)[2]) } - } - - Write-Output "Text files in the repository: $($textFiles.Length)" - - $bom = @(0xEF, 0xBB, 0xBF) - $bomErrors = @() - $lineEndingErrors = @() - - foreach ($file in $textFiles) { - if ($ExcludeExtensions -contains [IO.Path]::GetExtension($file).ToLowerInvariant()) { - continue - } - - $fullPath = Resolve-Path -LiteralPath $file - $bytes = [IO.File]::ReadAllBytes($fullPath) | Select-Object -First $bom.Length - if (!$bytes) { continue } # filter empty files - - $bytesEqualsBom = @(Compare-Object $bytes $bom -SyncWindow 0).Length -eq 0 - if ($bytesEqualsBom -and $Autofix) { - $fullContent = [IO.File]::ReadAllBytes($fullPath) - $newContent = $fullContent | Select-Object -Skip $bom.Length - [IO.File]::WriteAllBytes($fullPath, $newContent) - Write-Output "Removed UTF-8 BOM from file $file" - } elseif ($bytesEqualsBom) { - $bomErrors += @($file) - } - - $text = [IO.File]::ReadAllText($fullPath) - $hasWrongLineEndings = $text.Contains("`r`n") - if ($hasWrongLineEndings -and $Autofix) { - $newText = $text -replace "`r`n", "`n" - [IO.File]::WriteAllText($fullPath, $newText) - Write-Output "Fixed the line endings for file $file" - } elseif ($hasWrongLineEndings) { - $lineEndingErrors += @($file) - } - } - - if ($bomErrors.Length) { - throw "The following $($bomErrors.Length) files have UTF-8 BOM:`n" + ($bomErrors -join "`n") - } - if ($lineEndingErrors.Length) { - throw "The following $($lineEndingErrors.Length) files have CRLF instead of LF:`n" + ($lineEndingErrors -join "`n") - } -} finally { - Pop-Location -} diff --git a/src/authorization/EventTriangleAPI.Authorization.Presentation/appsettings.Kubernetes.json b/src/authorization/EventTriangleAPI.Authorization.Presentation/appsettings.Kubernetes.json new file mode 100644 index 00000000..df581d77 --- /dev/null +++ b/src/authorization/EventTriangleAPI.Authorization.Presentation/appsettings.Kubernetes.json @@ -0,0 +1,72 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Grpc": "Debug" + } + }, + "AllowedHosts": "*", + "AllowedOrigins": [ + "http://localhost:4200", + "http://localhost:7000" + ], + "DatabaseConnectionString": "Server=db;User Id=postgres;Password=postgres;Database=AuthorizationDb;", + "DevFrontendUrl": "http://localhost:4200", + "RedisUrl": "", + "RedisPassword": "", + "AzureAd": { + "Authority": "https://login.microsoftonline.com/b40a105f-0643-4922-8e60-10fc1abf9c4b/v2.0/", + "Instance": "https://login.microsoftonline.com", + "TenantId": "b40a105f-0643-4922-8e60-10fc1abf9c4b", + "ClientId": "25128d03-9817-4e11-bddf-dc5f6df4042a", + "Scopes": "api://25128d03-9817-4e11-bddf-dc5f6df4042a/EventTriangleLocalAuth.All openid offline_access", + "CallbackPath": "/authorization-redirect", + "RedirectUri": "http://localhost:3000", + "AzureAdTokenUrl": "https://login.microsoftonline.com/b40a105f-0643-4922-8e60-10fc1abf9c4b/oauth2/v2.0/token", + "ClientSecret": "" + }, + "GrpcChannelAddresses": "http://event-triangle-sender-service:81", + "ReverseProxy": { + "Routes": { + "route1": { + "ClusterId": "cluster1", + "Match": { + "Path": "/sender/{**catch-all}" + }, + "Transforms": [ + { + "PathRemovePrefix": "/sender" + } + ] + }, + "route2": { + "ClusterId": "cluster2", + "Match": { + "Path": "/consumer/{**catch-all}" + }, + "Transforms": [ + { + "PathRemovePrefix": "/consumer" + } + ] + } + }, + "Clusters": { + "cluster1": { + "Destinations": { + "destination1": { + "Address": "http://event-triangle-sender-service" + } + } + }, + "cluster2": { + "Destinations": { + "destination1": { + "Address": "http://event-triangle-consumer-service" + } + } + } + } + } +} diff --git a/src/consumer/EventTriangleAPI.Consumer.Presentation/appsettings.Kubernetes.json b/src/consumer/EventTriangleAPI.Consumer.Presentation/appsettings.Kubernetes.json new file mode 100644 index 00000000..a29337a3 --- /dev/null +++ b/src/consumer/EventTriangleAPI.Consumer.Presentation/appsettings.Kubernetes.json @@ -0,0 +1,21 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "DatabaseConnectionString": "Server=db;User Id=postgres;Password=postgres;Database=ConsumerDb;", + "AzureAd": { + "Instance": "https://login.microsoftonline.com/", + "TenantId": "b40a105f-0643-4922-8e60-10fc1abf9c4b", + "ClientId": "25128d03-9817-4e11-bddf-dc5f6df4042a", + "Scopes": "EventTriangleLocalAuth.All" + }, + "RabbitMqHost": "rabbit", + "RabbitMqUsername": "guest", + "RabbitMqPassword": "guest", + "ShouldCreateSeeds": true, + "ShouldCreateSeedsForAdmin": true +} diff --git a/src/sender/EventTriangleAPI.Sender.Presentation/appsettings.Kubernetes.json b/src/sender/EventTriangleAPI.Sender.Presentation/appsettings.Kubernetes.json new file mode 100644 index 00000000..4a4bd647 --- /dev/null +++ b/src/sender/EventTriangleAPI.Sender.Presentation/appsettings.Kubernetes.json @@ -0,0 +1,20 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Grpc": "Debug" + } + }, + "AllowedHosts": "*", + "DatabaseConnectionString": "Server=db;User Id=postgres;Password=postgres;Database=SenderDb;", + "AzureAd": { + "Instance": "https://login.microsoftonline.com/", + "TenantId": "b40a105f-0643-4922-8e60-10fc1abf9c4b", + "ClientId": "25128d03-9817-4e11-bddf-dc5f6df4042a", + "Scopes": "EventTriangleLocalAuth.All" + }, + "RabbitMqHost": "rabbit", + "RabbitMqUsername": "guest", + "RabbitMqPassword": "guest" +} diff --git a/terraform-azdo-libraries/README.md b/terraform-azdo-libraries/README.md new file mode 100644 index 00000000..1a7dbaf4 --- /dev/null +++ b/terraform-azdo-libraries/README.md @@ -0,0 +1,19 @@ +- Export libraries API call: `curl -u :{PAT} "https://dev.azure.com/{organization}/{project}/_apis/distributedtask/variablegroups?api-version=7.0"` +- Get project ID from: https://dev.azure.com/EventTriangle/_apis/projects?api-version=5.0-preview.3 +- Generate Azure DevOps PAT with FULL permissions +- Copy AZDO PAT to azdo-pat-token.txt +- Fill the JSON default values terraform.auto.tfvars.json: + ```json + { + "cloudflare_api_key": "", + "azure_rm_client_secret": "", + "entra_id_auth_secret": "", + "postgres_password": "", + "sas_token": "", + "redis_password": "" + } + + ``` +- Login to Azure CLI in browser as user (yes it matters): az login --use-device-code +- terraform plan -out main.tfplan -lock=false +- terraform apply -lock=false "main.tfplan" diff --git a/terraform-azdo-libraries/aks-settings.tf b/terraform-azdo-libraries/aks-settings.tf new file mode 100644 index 00000000..c614eed4 --- /dev/null +++ b/terraform-azdo-libraries/aks-settings.tf @@ -0,0 +1,21 @@ +resource "azuredevops_variable_group" "aks_settings" { + project_id = var.project_id + name = "AKS_Settings" + description = "AKS_Settings" + allow_access = true + + variable { + name = "library-aks-cluster-name" + value = "my-aks-cluster-$(library-prefix)" + } + + variable { + name = "library-aks-resource-group" + value = "rg-aks-$(library-prefix)" + } + + variable { + name = "library-aks-namespace" + value = "event-triangle-dev" + } +} diff --git a/terraform-azdo-libraries/cloudflare-api-key.tf b/terraform-azdo-libraries/cloudflare-api-key.tf new file mode 100644 index 00000000..b8217818 --- /dev/null +++ b/terraform-azdo-libraries/cloudflare-api-key.tf @@ -0,0 +1,17 @@ +resource "azuredevops_variable_group" "cloudflare_api_key" { + project_id = var.project_id + name = "Cloudflare_API_Key" + description = "Cloudflare API Key" + allow_access = true + + variable { + name = "cloudflare-api-key" + is_secret = true + secret_value = var.cloudflare_api_key + } + + variable { + name = "cloudflare-zone-name" + value = "razumovsky.me" + } +} diff --git a/terraform-azdo-libraries/entra-id-auth-secret.tf b/terraform-azdo-libraries/entra-id-auth-secret.tf new file mode 100644 index 00000000..f8eea0bb --- /dev/null +++ b/terraform-azdo-libraries/entra-id-auth-secret.tf @@ -0,0 +1,12 @@ +resource "azuredevops_variable_group" "entra_id_auth_secret" { + project_id = var.project_id + name = "Entra_ID_Auth_Secret" + description = "Entra_ID_Auth_Secret" + allow_access = true + + variable { + name = "library-entra-id-auth-secret" + is_secret = true + secret_value = var.entra_id_auth_secret + } +} diff --git a/terraform-azdo-libraries/postgres-library.tf b/terraform-azdo-libraries/postgres-library.tf new file mode 100644 index 00000000..e5f27293 --- /dev/null +++ b/terraform-azdo-libraries/postgres-library.tf @@ -0,0 +1,22 @@ +resource "azuredevops_variable_group" "postgres_settings" { + project_id = var.project_id + name = "Postgres_Settings" + description = "Postgres_Settings" + allow_access = true + + variable { + name = "POSTGRES_DB" + value = "postgres" + } + + variable { + name = "POSTGRES_PASSWORD" + is_secret = true + secret_value = var.postgres_password + } + + variable { + name = "POSTGRES_USER" + value = "postgres" + } +} diff --git a/terraform-azdo-libraries/prefix-library.tf b/terraform-azdo-libraries/prefix-library.tf new file mode 100644 index 00000000..d6731dbe --- /dev/null +++ b/terraform-azdo-libraries/prefix-library.tf @@ -0,0 +1,11 @@ +resource "azuredevops_variable_group" "prefix_library" { + project_id = var.project_id + name = "Prefix_Library" + description = "Prefix_Library" + allow_access = true + + variable { + name = "library-prefix" + value = "d01" + } +} diff --git a/terraform-azdo-libraries/provider.tf b/terraform-azdo-libraries/provider.tf new file mode 100644 index 00000000..0e79fa34 --- /dev/null +++ b/terraform-azdo-libraries/provider.tf @@ -0,0 +1,4 @@ +provider "azuredevops" { + org_service_url = "https://dev.azure.com/EventTriangle" + client_secret = file("${path.module}/azdo-pat-token.txt") +} diff --git a/terraform-azdo-libraries/redis-library.tf b/terraform-azdo-libraries/redis-library.tf new file mode 100644 index 00000000..66337c31 --- /dev/null +++ b/terraform-azdo-libraries/redis-library.tf @@ -0,0 +1,17 @@ +resource "azuredevops_variable_group" "redis_secrets" { + project_id = var.project_id + name = "Redis_Credentials" + description = "Redis_Credentials" + allow_access = true + + variable { + name = "library-redis-password" + is_secret = true + secret_value = var.redis_password + } + + variable { + name = "library-redis-url" + value = "" + } +} diff --git a/terraform-azdo-libraries/terraform-azure-credentials.tf b/terraform-azdo-libraries/terraform-azure-credentials.tf new file mode 100644 index 00000000..d0b57ea1 --- /dev/null +++ b/terraform-azdo-libraries/terraform-azure-credentials.tf @@ -0,0 +1,27 @@ +resource "azuredevops_variable_group" "terraform_azure_credentials" { + project_id = var.project_id + name = "Terraform_Azure_Credentials" + description = "Terraform Azure Credentials" + allow_access = true + + variable { + name = "library-client-id" + value = "ab0a5dc1-ee52-4574-96e0-469f237928a6" + } + + variable { + name = "library-client-secret" + is_secret = true + secret_value = var.azure_rm_client_secret + } + + variable { + name = "library-subscription-id" + value = "1b08b9a2-ac6d-4b86-8a2f-8fef552c8371" + } + + variable { + name = "library-tenant-id" + value = "b40a105f-0643-4922-8e60-10fc1abf9c4b" + } +} diff --git a/terraform-azdo-libraries/terraform-backend-library.tf b/terraform-azdo-libraries/terraform-backend-library.tf new file mode 100644 index 00000000..ac0cfd4f --- /dev/null +++ b/terraform-azdo-libraries/terraform-backend-library.tf @@ -0,0 +1,27 @@ +resource "azuredevops_variable_group" "terraform_backend_settings" { + project_id = var.project_id + name = "Terraform_Backend_StateFile_Settings" + description = "Terraform Backend StateFile Settings" + allow_access = true + + variable { + name = "library-sas-token" + is_secret = true + secret_value = var.sas_token + } + + variable { + name = "library-state-file" + value = "aks.event.triangle.$(library-prefix).tfstate" + } + + variable { + name = "library-storage-account" + value = "tfstatestorage011" + } + + variable { + name = "library-storage-container" + value = "tfstatecontainer01" + } +} diff --git a/terraform-azdo-libraries/tfvars-transform-library.tf b/terraform-azdo-libraries/tfvars-transform-library.tf new file mode 100644 index 00000000..6354f8d7 --- /dev/null +++ b/terraform-azdo-libraries/tfvars-transform-library.tf @@ -0,0 +1,22 @@ +resource "azuredevops_variable_group" "tfvars_transform" { + project_id = var.project_id + name = "Terraform_Auto_Tfvars_Json_Transform" + description = "Terraform_Auto_Tfvars_Json_Transform" + allow_access = true + + variable { + name = "client_secret" + is_secret = true + secret_value = var.azure_rm_client_secret + } + + variable { + name = "should_deploy_log_analytics" + value = "false" + } + + variable { + name = "should_deploy_prometheus" + value = "false" + } +} diff --git a/terraform-azdo-libraries/variables.tf b/terraform-azdo-libraries/variables.tf new file mode 100644 index 00000000..de295f0e --- /dev/null +++ b/terraform-azdo-libraries/variables.tf @@ -0,0 +1,27 @@ +variable "cloudflare_api_key" { + sensitive = true +} + +variable "azure_rm_client_secret" { + sensitive = true +} + +variable "entra_id_auth_secret" { + sensitive = true +} + +variable "postgres_password" { + sensitive = true +} + +variable "sas_token" { + sensitive = true +} + +variable "redis_password" { + sensitive = true +} + +variable "project_id" { + default = "29327428-805a-440b-9d16-fcf0ac20edb2" +} diff --git a/terraform-azdo-libraries/versions.tf b/terraform-azdo-libraries/versions.tf new file mode 100644 index 00000000..b7e205df --- /dev/null +++ b/terraform-azdo-libraries/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_providers { + azuredevops = { + source = "microsoft/azuredevops" + version = ">=1.1.1" + } + } + + backend "azurerm" {} +} diff --git a/terraform/output.tf b/terraform/output.tf index b71f337e..c45f6e97 100644 --- a/terraform/output.tf +++ b/terraform/output.tf @@ -11,7 +11,7 @@ output "subscription" { } output "cluster_connect_command" { - value = "az aks get-credentials --resource-group ${azurerm_resource_group.public.name} --name ${module.aks.name} --subscription ${var.subscription_id}" + value = "az aks get-credentials --resource-group ${azurerm_resource_group.public.name} --name ${module.aks.name} --subscription ${var.subscription_id} --overwrite-existing" } output "grafana_endpoint" { diff --git a/terraform/terraform.auto.tfvars.json b/terraform/terraform.auto.tfvars.json index c820c251..5244b42d 100644 --- a/terraform/terraform.auto.tfvars.json +++ b/terraform/terraform.auto.tfvars.json @@ -8,8 +8,8 @@ "default_node_pool_type": "VirtualMachineScaleSets", "system_node_count": 3, "log_analytics_sku": "PerGB2018", - "should_deploy_log_analytics": true, - "should_deploy_prometheus": true, + "should_deploy_log_analytics": false, + "should_deploy_prometheus": false, "acr_name": "acrsharedd01", "subscription_id": "1b08b9a2-ac6d-4b86-8a2f-8fef552c8371", "tenant_id": "b40a105f-0643-4922-8e60-10fc1abf9c4b",