From 92f28049ef92292fbd8f70ae3e734dcd4e17c3dc Mon Sep 17 00:00:00 2001 From: shivaprasadmb Date: Thu, 30 Apr 2026 10:57:50 +0530 Subject: [PATCH 1/3] helm-release: Chart 0.5.8 with Postgres HA, Oracle SI, and kube-rbac-proxy update - Bump chart to v0.5.8 / appVersion v0.5.5 - Update kube-rbac-proxy to quay.io/brancz/kube-rbac-proxy:v0.22.0 - Update CRD schema with PostgresHAConfig nested struct - Update README with HA provisioning details Made-with: Cursor --- .github/workflows/build-dev.yaml | 2 - .github/workflows/helm-lint.yaml | 2 +- deploy/helm/Chart.yaml | 12 ++- deploy/helm/README.md | 82 ++++++++++++++++- ...edefinition-databases.ndb.nutanix.com.yaml | 90 +++++++++++++++++++ ...yment-ndb-operator-controller-manager.yaml | 2 +- 6 files changed, 181 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-dev.yaml b/.github/workflows/build-dev.yaml index 24a538a7..5cfcff3f 100644 --- a/.github/workflows/build-dev.yaml +++ b/.github/workflows/build-dev.yaml @@ -7,8 +7,6 @@ on: paths-ignore: - 'deploy/helm/**' pull_request: - paths-ignore: - - 'deploy/helm/**' jobs: build-binary: diff --git a/.github/workflows/helm-lint.yaml b/.github/workflows/helm-lint.yaml index 0666854b..ce05fea2 100644 --- a/.github/workflows/helm-lint.yaml +++ b/.github/workflows/helm-lint.yaml @@ -1,7 +1,7 @@ name: Linting Charts on: - push: + pull_request: paths: - 'deploy/helm/**' diff --git a/deploy/helm/Chart.yaml b/deploy/helm/Chart.yaml index 0acb9782..037d4500 100644 --- a/deploy/helm/Chart.yaml +++ b/deploy/helm/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: ndb-operator description: A Helm chart for Nutanix Database Kubernetes Operator type: application -version: 0.5.7 -appVersion: v0.5.4 +version: 0.5.8 +appVersion: v0.5.5 maintainers: - name: mazin-s email: mazin.shaaeldin@nutanix.com @@ -22,10 +22,14 @@ maintainers: icon: https://www.nutanix.com/content/dam/nutanix/global/icons/products/svg/Nutanix-Era-40.svg annotations: artifacthub.io/changes: | + - kind: added + description: "Chart 0.5.8: Add support for Postgres HA and Oracle SI." - kind: changed - description: "Chart 0.5.7: controller image v0.5.4." + description: "Chart 0.5.8: controller image v0.5.5." + - kind: security + description: "kube-rbac-proxy v0.22.0 (quay.io/brancz/kube-rbac-proxy)." - kind: changed - description: "Release details: https://github.com/nutanix-cloud-native/ndb-operator/releases/tag/v0.5.4" + description: "Release details: https://github.com/nutanix-cloud-native/ndb-operator/releases/tag/v0.5.5" artifacthub.io/containsSecurityUpdates: "true" artifacthub.io/license: Apache-2.0 artifacthub.io/maintainers: | diff --git a/deploy/helm/README.md b/deploy/helm/README.md index 61699dd3..08ca2918 100644 --- a/deploy/helm/README.md +++ b/deploy/helm/README.md @@ -6,7 +6,8 @@ NDB operator supports these functionalities: 1. Provisioning and deprovisioning a single instance postgres, mssql, sql server, and mongodb database with or without time machine. 2. Cloning support for the above database engines -3. Creation of a service for the applications to consume the database within Kubernetes. +3. Provisioning and deprovisioning Postgres High Availability (HA) instances. +4. Creation of a service for the applications to consume the database within Kubernetes. --- @@ -436,6 +437,85 @@ Create the Database resource: kubectl apply -f ``` +#### Creating Postgres HA instance resource +```yaml +apiVersion: ndb.nutanix.com/v1alpha1 +kind: Database +metadata: + name: Postgres-HA-K8s-resource + namespace: default +spec: + ndbRef: ndbserver + databaseInstance: + name: "PGHA_instance_DB" + description: "Postgres HA instance" + # defaultsConfigMapRef: pgha-defaults # injects timezone, profiles, timeMachine from ConfigMap + type: postgres + credentialSecret: pgha-db-secret + size: 200 + clusterName: "" # This is often the Primary PE cluster + # ClusterID: "UUID of the PE cluster" + databaseNames: + - PGHA_instance + timeMachine: + name: "PGHA_TM" + description: "TM for Postgres HA" + haConfig: + patroniClusterName: "pgha-patroni" # any desired name + clusterName: "PGHA_cluster" # any desired name + enableSynchronousMode: true # default is false, This is for data replication across DB nodes + # provisionVirtualIP: true # default is false, keep this true if having stretched VLAN and need to provision VirtualIP + # writePort: 5000 # defaults to 5000 if omitted + # readPort: 5001 # defaults to 5001 if omitted + nodes: + - vmName: "PGHA_haproxy1" # any desired name + nodeType: "haproxy" + clusterName: "" + # clusterId: "UUID of the PE cluster" + - vmName: "PGHA_haproxy2" # any desired name + nodeType: "haproxy" + clusterName: "" + # clusterId: "UUID of the PE cluster" + - vmName: "PGHA_DB-1" # any desired name + nodeType: "database" + role: "Primary" + clusterName: "" + # clusterId: "UUID of the PE cluster" + - vmName: "PGHA_DB-2" # any desired name + nodeType: "database" + role: "Secondary" + clusterName: "" + # clusterId: "UUID of the PE cluster" + - vmName: "PGHA_DB-3" # any desired name + nodeType: "database" + role: "Secondary" + clusterName: "" + # clusterId: "UUID of the PE cluster" +``` + +### Example Defaults configmap for HA instance +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: pgha-defaults + namespace: default +data: + timezone: "UTC" + # postgres-prefixed keys take priority over unprefixed keys for postgres databases + postgres.profiles.software.name: "POSTGRES_15.6_HA_ENABLED_ROCKY_LINUX_8_OOB" + postgres.profiles.compute.name: "DEFAULT_HA_COMPUTE" + postgres.profiles.network.name: "PGHA_VLAN" + postgres.profiles.dbParam.name: "DEFAULT_POSTGRES_HA_PARAMS" + postgres.timeMachine.sla: "DEFAULT_OOB_BRONZE_SLA" + postgres.timeMachine.dailySnapshotTime: "10:00:00" + postgres.timeMachine.snapshotsPerDay: "1" + postgres.timeMachine.logCatchUpFrequency: "120" + postgres.timeMachine.weeklySnapshotDay: "WEDNESDAY" + postgres.timeMachine.monthlySnapshotDay: "8" + postgres.timeMachine.quarterlySnapshotMonth: "Jan" +``` + ### Additional Arguments for Databases Below are the various optional addtionalArguments you can specify along with examples of their corresponding values. Arguments that have defaults will be indicated. diff --git a/deploy/helm/crds/customresourcedefinition-databases.ndb.nutanix.com.yaml b/deploy/helm/crds/customresourcedefinition-databases.ndb.nutanix.com.yaml index ddd9b9b5..d2555959 100644 --- a/deploy/helm/crds/customresourcedefinition-databases.ndb.nutanix.com.yaml +++ b/deploy/helm/crds/customresourcedefinition-databases.ndb.nutanix.com.yaml @@ -190,6 +190,89 @@ spec: description: description: Description of the database instance type: string + haConfig: + description: |- + HA configuration for Postgres HA instances (multi-cluster topology). + When set, provisions a clustered Postgres instance with HAProxy and Patroni. + properties: + clusterName: + description: Display name for the NDB HA cluster + type: string + enableSynchronousMode: + description: Enable synchronous replication mode + type: boolean + nodes: + description: Node placement and role definitions for all VMs + in the HA cluster + items: + description: InstanceHANode describes the placement and + role of a single VM in an HA cluster. + properties: + clusterId: + description: |- + Id of the PE cluster this node should be placed on. + Either clusterId or clusterName must be provided. + type: string + clusterName: + description: |- + Name of the PE cluster this node should be placed on. + Either clusterId or clusterName must be provided. + type: string + failoverMode: + description: Failover mode for database nodes (default + "Automatic") + type: string + nodeType: + description: 'Type of this node: "haproxy" or "database"' + enum: + - haproxy + - database + type: string + role: + description: 'Role of this node (database nodes only): + "Primary" or "Secondary"' + type: string + vmName: + description: Name of the VM to be created + type: string + required: + - nodeType + - vmName + type: object + type: array + postgres: + description: |- + Postgres contains Patroni and HAProxy settings specific to Postgres HA. + Required when the database type is "postgres". + properties: + patroniClusterName: + description: Name used by Patroni for DCS cluster coordination + type: string + provisionVirtualIP: + description: |- + ProvisionVirtualIP controls whether NDB provisions a Virtual IP for the HAProxy layer. + Set to true only when all HAProxy VMs are on the same Nutanix cluster (non-stretched VLAN). + Defaults to false; use false when HAProxy nodes span multiple PE clusters. + type: boolean + readPort: + default: 5001 + description: HAProxy read (replica) port. Defaults to + 5001. + format: int32 + type: integer + writePort: + default: 5000 + description: HAProxy write (primary) port. Defaults to + 5000. + format: int32 + type: integer + required: + - patroniClusterName + type: object + required: + - clusterName + - nodes + type: object name: description: Name of the database instance type: string @@ -298,6 +381,13 @@ spec: properties: creationOperationId: type: string + dbServerDeletionOperationIds: + description: |- + DBServerDeletionOperationIds holds the NDB operation ID returned by the DPC (DBServerCluster) deletion. + Populated when HA deletion starts; polled until the operation completes before the finalizer is removed. + items: + type: string + type: array dbServerId: type: string deregistrationOperationId: diff --git a/deploy/helm/templates/deployment-ndb-operator-controller-manager.yaml b/deploy/helm/templates/deployment-ndb-operator-controller-manager.yaml index 32089276..67502d91 100644 --- a/deploy/helm/templates/deployment-ndb-operator-controller-manager.yaml +++ b/deploy/helm/templates/deployment-ndb-operator-controller-manager.yaml @@ -59,7 +59,7 @@ spec: - --upstream=http://127.0.0.1:8080/ - --logtostderr=true - --v=0 - image: quay.io/brancz/kube-rbac-proxy:v0.21.2 + image: quay.io/brancz/kube-rbac-proxy:v0.22.0 name: kube-rbac-proxy ports: - containerPort: 8443 From 332a5e89e89a0ad94ae6b25f0c695f4c68245b99 Mon Sep 17 00:00:00 2001 From: shivaprasadmb Date: Fri, 1 May 2026 09:47:43 +0530 Subject: [PATCH 2/3] add oracle readme info --- README.md | 68 +++++++++++++++++++++++- deploy/helm/README.md | 117 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 181 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 242fe921..6a884a5a 100644 --- a/README.md +++ b/README.md @@ -371,7 +371,73 @@ spec: expireInDays: 3 ``` -#### Creating Postgres HA instance resource + +### Creating Oracle SI resource +``` +apiVersion: ndb.nutanix.com/v1alpha1 +kind: Database +metadata: + name: + namespace: "" +spec: + ndbRef: + isClone: false + databaseInstance: + name: + databaseNames: [""] + credentialSecret: + type: oracle + size: 50 + timezone: "UTC" + clusterId: "" # or use clusterName field to specify name + profiles: + software: + name: "" + compute: + name: "" + network: + name: "" + dbParam: + name: "" + timeMachine: + sla: "NAME of SLA" + dailySnapshotTime: "12:00:00" + snapshotsPerDay: 1 + logCatchUpFrequency: 60 + weeklySnapshotDay: "MONDAY" + monthlySnapshotDay: 15 + quarterlySnapshotMonth: "Jan" +``` + +### Creating Oracle SI Clone +``` +apiVersion: ndb.nutanix.com/v1alpha1 +kind: Database +metadata: + name: + namespace: "" +spec: + ndbRef: + isClone: true + clone: + name: < orabel db clone name> + sourceDatabaseName: "" # specify actual database name shown in NDB UI, not K8s resource name + timezone: "UTC" + clusterId: "" # or use clusterName field + credentialSecret: + type: oracle + profiles: + software: + name: "" + compute: + name: "" + network: + name: "" + dbParam: + name: "" +``` + +### Creating Postgres HA instance resource ``` apiVersion: ndb.nutanix.com/v1alpha1 kind: Database diff --git a/deploy/helm/README.md b/deploy/helm/README.md index 08ca2918..a03cce61 100644 --- a/deploy/helm/README.md +++ b/deploy/helm/README.md @@ -431,11 +431,71 @@ spec: ``` -Create the Database resource: +### Creating Oracle SI resource +``` +apiVersion: ndb.nutanix.com/v1alpha1 +kind: Database +metadata: + name: + namespace: "" +spec: + ndbRef: + isClone: false + databaseInstance: + name: + databaseNames: [""] + credentialSecret: + type: oracle + size: 50 + timezone: "UTC" + clusterId: "" # or use clusterName field to specify name + profiles: + software: + name: "" + compute: + name: "" + network: + name: "" + dbParam: + name: "" + timeMachine: + sla: "NAME of SLA" + dailySnapshotTime: "12:00:00" + snapshotsPerDay: 1 + logCatchUpFrequency: 60 + weeklySnapshotDay: "MONDAY" + monthlySnapshotDay: 15 + quarterlySnapshotMonth: "Jan" +``` -```sh -kubectl apply -f +### Creating Oracle SI Clone ``` +apiVersion: ndb.nutanix.com/v1alpha1 +kind: Database +metadata: + name: + namespace: "" +spec: + ndbRef: + isClone: true + clone: + name: < orabel db clone name> + sourceDatabaseName: "" # specify actual database name shown in NDB UI, not K8s resource name + timezone: "UTC" + clusterId: "" # or use clusterName field + credentialSecret: + type: oracle + profiles: + software: + name: "" + compute: + name: "" + network: + name: "" + dbParam: + name: "" +``` + #### Creating Postgres HA instance resource ```yaml @@ -515,6 +575,11 @@ data: postgres.timeMachine.monthlySnapshotDay: "8" postgres.timeMachine.quarterlySnapshotMonth: "Jan" ``` +### Create the Database resource: + +```sh +kubectl apply -f +``` ### Additional Arguments for Databases @@ -549,6 +614,31 @@ additionalArguments: windows_domain_profile_id: # NO Default. Must specify vm_db_server_user. vm_db_server_user: # NO Default. Must specify windows_domain_profile_id. vm_win_license_key: # NO Default. + +# Oracle +additionalArguments: + # Core parameters (all have defaults) + listener_port: "1521" # Default: "1521" + oracle_sid: "ORCL" # Default: database name (max 8 chars, alphanumeric, starts with letter) + global_database_name: "ORCL.example.com" # Default: database name + db_unique_name: "ORCL" # Default: database name + sys_password: "Password123" # Default: from database secret + system_password: "Password123" # Default: sys_password + db_character_set: "AL32UTF8" # Default: "AL32UTF8" + national_character_set: "AL16UTF16" # Default: "AL16UTF16" + database_fra_size: "100" # Default: database size (Fast Recovery Area) + enable_cdb: "false" # Default: "false" (Container Database for multitenant) + enable_tde: "false" # Default: "false" (Transparent Data Encryption) + enable_ha: "false" # Default: "false" (High Availability/RAC) + auto_tune_staging_drive: "true" # Default: "true" + working_dir: "/tmp" # Default: "/tmp" + # Advanced parameters (optional) + pga_aggregate_target: "2G" # NO Default. Oracle PGA memory + sga_target: "4G" # NO Default. Oracle SGA memory + tde_encryption_passphrase: "Passphrase123" # NO Default. Required if enable_tde="true" + pre_create_script: "echo 'Pre-create'" # Default: "" + post_create_script: "echo 'Post-create'" # Default: "" + # For complete list of 64+ Oracle parameters, see docs/ORACLE-SI-GUIDE.md ``` Cloning Additional Arguments: @@ -590,6 +680,27 @@ MySQL: refreshInDays refreshTime refreshDateTimezone + +Oracle: + # Core clone parameters (have defaults) + new_db_sid # New Oracle SID (max 8 chars) - Default: clone name + oracle_sid # Alternative to new_db_sid - Default: clone name + db_password # SYS password - Default: from secret + listener_port # Listener port - Default: "1521" + enable_ha # Enable HA/RAC - Default: "false" + scan_port # SCAN port for RAC - Default: "1521" + delete_logs_post_recovery # Delete archive logs - Default: "false" + asm_driver # ASM driver type - Default: "None" + vm_name # VM name - Default: clone name + dbserver_description # DB server description - Default: auto-generated + # Lifecycle Management (LCM) parameters + expireInDays # Must specify all 3 expiry params together + expiryDateTimezone + deleteDatabase + refreshInDays # Must specify all 3 refresh params together + refreshTime + refreshDateTimezone + # For complete list of Oracle clone parameters, see docs/ORACLE-SI-GUIDE.md ``` ### Deleting the Database resource From 4fc1e99c48209ba161633bed3739a15eeb97e8aa Mon Sep 17 00:00:00 2001 From: shivaprasadmb Date: Tue, 5 May 2026 09:24:47 +0530 Subject: [PATCH 3/3] generalize SI instance examples --- deploy/helm/README.md | 71 ++----------------------------------------- 1 file changed, 3 insertions(+), 68 deletions(-) diff --git a/deploy/helm/README.md b/deploy/helm/README.md index a03cce61..a6b83072 100644 --- a/deploy/helm/README.md +++ b/deploy/helm/README.md @@ -285,7 +285,7 @@ spec: defaultsConfigMapRef: ndb-database-defaults # Reference the ConfigMap isClone: false databaseInstance: - type: postgres + type: #postgres,oracle,mysql,mssql,mongo name: my-app-db databaseNames: ["appdb"] credentialSecret: db-instance-secret-name @@ -326,7 +326,7 @@ spec: credentialSecret: db-instance-secret-name size: 10 timezone: "UTC" - type: postgres + type: #postgres,oracle,mysql,mssql,mongo # You can specify any (or none) of these types of profiles: compute, software, network, dbParam # If not specified, the corresponding Out-of-Box (OOB) profile will be used wherever applicable @@ -378,7 +378,7 @@ spec: # Clone specific details (that is to be provisioned) clone: # Type of the database to be cloned - type: postgres + type: #postgres,oracle,mysql,mssql,mongo # The clone instance name on NDB name: "Clone-Instance-Name" # The description of the clone instance @@ -431,71 +431,6 @@ spec: ``` -### Creating Oracle SI resource -``` -apiVersion: ndb.nutanix.com/v1alpha1 -kind: Database -metadata: - name: - namespace: "" -spec: - ndbRef: - isClone: false - databaseInstance: - name: - databaseNames: [""] - credentialSecret: - type: oracle - size: 50 - timezone: "UTC" - clusterId: "" # or use clusterName field to specify name - profiles: - software: - name: "" - compute: - name: "" - network: - name: "" - dbParam: - name: "" - timeMachine: - sla: "NAME of SLA" - dailySnapshotTime: "12:00:00" - snapshotsPerDay: 1 - logCatchUpFrequency: 60 - weeklySnapshotDay: "MONDAY" - monthlySnapshotDay: 15 - quarterlySnapshotMonth: "Jan" -``` - -### Creating Oracle SI Clone -``` -apiVersion: ndb.nutanix.com/v1alpha1 -kind: Database -metadata: - name: - namespace: "" -spec: - ndbRef: - isClone: true - clone: - name: < orabel db clone name> - sourceDatabaseName: "" # specify actual database name shown in NDB UI, not K8s resource name - timezone: "UTC" - clusterId: "" # or use clusterName field - credentialSecret: - type: oracle - profiles: - software: - name: "" - compute: - name: "" - network: - name: "" - dbParam: - name: "" -``` - #### Creating Postgres HA instance resource ```yaml