diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index dec8f59f2d..0f4c6131e1 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -61,6 +61,12 @@ jobs:
kubectl create -f https://github.com/kubedb/installer/raw/master/crds/kubedb-crds.yaml
kubectl create -f https://github.com/kubernetes-csi/external-snapshotter/raw/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
kubectl create -f https://github.com/kubestash/installer/raw/master/crds/kubestash-crds.yaml
+ # recommendation
+ kubectl create -f https://github.com/kubeops/supervisor/raw/master/crds/supervisor.appscode.com_approvalpolicies.yaml
+ kubectl create -f https://github.com/kubeops/supervisor/raw/master/crds/supervisor.appscode.com_clustermaintenancewindows.yaml
+ kubectl create -f https://github.com/kubeops/supervisor/raw/master/crds/supervisor.appscode.com_maintenancewindows.yaml
+ kubectl create -f https://github.com/kubeops/supervisor/raw/master/crds/supervisor.appscode.com_recommendations.yaml
+ # gateway
kubectl create -f https://github.com/appscode-cloud/catalog/raw/master/crds/catalog.appscode.com_mongodbbindings.yaml
kubectl create -f https://github.com/voyagermesh/installer/raw/master/charts/voyager-gateway/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
kubectl create -f https://github.com/voyagermesh/installer/raw/master/charts/gateway-api/crds/gateway.networking.k8s.io_gatewayclasses.yaml
diff --git a/docs/guides/elasticsearch/cli/cli.md b/docs/guides/elasticsearch/cli/cli.md
index 540a6b911d..223ce51d0f 100644
--- a/docs/guides/elasticsearch/cli/cli.md
+++ b/docs/guides/elasticsearch/cli/cli.md
@@ -5,7 +5,7 @@ menu:
identifier: es-cli-cli
name: Quickstart
parent: es-cli-elasticsearch
- weight: 100
+ weight: 110
menu_name: docs_{{ .version }}
section_menu_id: guides
---
diff --git a/docs/guides/elasticsearch/plugins/_index.md b/docs/guides/elasticsearch/plugins/_index.md
index efa9f0d86b..088eeea570 100755
--- a/docs/guides/elasticsearch/plugins/_index.md
+++ b/docs/guides/elasticsearch/plugins/_index.md
@@ -5,6 +5,6 @@ menu:
identifier: es-plugin-elasticsearch
name: Extensions & Plugins
parent: es-elasticsearch-guides
- weight: 60
+ weight: 90
menu_name: docs_{{ .version }}
---
\ No newline at end of file
diff --git a/docs/guides/elasticsearch/recommendation/_index.md b/docs/guides/elasticsearch/recommendation/_index.md
new file mode 100755
index 0000000000..3ed4e47bf1
--- /dev/null
+++ b/docs/guides/elasticsearch/recommendation/_index.md
@@ -0,0 +1,11 @@
+---
+title: Elasticsearch Recommendation
+menu:
+ docs_{{ .version }}:
+ identifier: es-recommendation-elasticsearch
+ name: Recommendation
+ parent: es-elasticsearch-guides
+ weight: 60
+menu_name: docs_{{ .version }}
+---
+
diff --git a/docs/guides/elasticsearch/recommendation/images/recommendation-generation.png b/docs/guides/elasticsearch/recommendation/images/recommendation-generation.png
new file mode 100644
index 0000000000..dd96452a27
Binary files /dev/null and b/docs/guides/elasticsearch/recommendation/images/recommendation-generation.png differ
diff --git a/docs/guides/elasticsearch/recommendation/overview.md b/docs/guides/elasticsearch/recommendation/overview.md
new file mode 100644
index 0000000000..0b81868d5d
--- /dev/null
+++ b/docs/guides/elasticsearch/recommendation/overview.md
@@ -0,0 +1,42 @@
+---
+title: Elasticsearch Recommendation
+description: Elasticsearch Recommendation Overview
+menu:
+ docs_{{ .version }}:
+ identifier: es-recommendation-overview
+ name: Overview
+ parent: es-recommendation-elasticsearch
+ weight: 10
+menu_name: docs_{{ .version }}
+section_menu_id: guides
+---
+
+> New to KubeDB? Please start [here](/docs/README.md).
+
+# Recommendation for KubeDB managed Elasticsearch and Opensearch
+
+Databases on Kubernetes in production grade infrastructure often need to go through several administrative operations depending on specific resource requirements. Such operations include vertical scaling (cpu, memory) and storage expansion. Autoscaling support for KubeDB managed databases takes care of it. However, databases also need to go through some maintenance operations in order to ensure security, enhance performance, getting bug fixes and new features etc. Such operations mostly require organization's manual intervention. Even if these operations are automated, they need to be done in surveillance. KubeDB simplifies this by generating K8s Native Recommendations.
+
+## Overview
+
+Recommendation is a custom resource definition (CRD) object which is created by KubeDB ops-manager controller and managed by supervisor. So, You need to have KubeDB and Supervisor installed first. You can simply install supervisor along with other KubeDB components using `--set supervisor.enabled=true` flag while installing KubeDB via helm chart.
+
+
+
+
+
+KubeDB provisioner watches user provided database custom resource spec and creates/sync all the necessary DB resources. Once the Database is ready KubeDB Ops-manager watches the DB and creates Recommendation if it requires. KubeDB Supervisor then watches the Recommendation, updates status of the recommendation, creates recommended operation via OpsRequest if deadline reaches or manually triggered and watches the OpsRequest status to update accordingly in Recommendation custom resource.
+
+KubeDB provides Three types of recommendation for Elasticsearch and Opensearch.
+
+1. [Version Update Recommendation](/docs/guides/elasticsearch/recommendation/version-update-recommendation.md)
+2. [TLS Certificate Rotation Recommendation](/docs/guides/elasticsearch/recommendation/rotate-tls-recommendation.md)
+3. [Authentication Secret Rotation Recommendation](/docs/guides/elasticsearch/recommendation/rotate-auth-recommendation.md)
+
+The next page describes these recommendations, how to approve/reject them, their generation mechanism and usability.
+
+## Next Steps
+
+- Learn about Elasticsearch [Version Update Recommendation](/docs/guides/elasticsearch/recommendation/version-update-recommendation.md).
+- Learn about Elasticsearch [TLS Certificate Rotation Recommendation](/docs/guides/elasticsearch/recommendation/rotate-tls-recommendation.md)
+- Learn about Elasticsearch [Authentication Secret Rotation Recommendation](/docs/guides/elasticsearch/recommendation/rotate-auth-recommendation.md)
diff --git a/docs/guides/elasticsearch/recommendation/rotate-auth-recommendation.md b/docs/guides/elasticsearch/recommendation/rotate-auth-recommendation.md
new file mode 100644
index 0000000000..121bc2c992
--- /dev/null
+++ b/docs/guides/elasticsearch/recommendation/rotate-auth-recommendation.md
@@ -0,0 +1,305 @@
+---
+title: Elasticsearch Rotate Auth Recommendation
+menu:
+ docs_{{ .version }}:
+ identifier: es-rotate-auth-recommendation
+ name: Rotate Auth Recommendation
+ parent: es-recommendation-elasticsearch
+ weight: 40
+menu_name: docs_{{ .version }}
+section_menu_id: guides
+---
+
+> New to KubeDB? Please start [here](/docs/README.md).
+
+# Elasticsearch Version Update Recommendation
+
+Rotating authentication secrets in database management is vital to mitigate security risks, such as credential leakage or unauthorized access, and to comply with regulatory requirements. Regular rotation limits the exposure of compromised credentials, reduces the risk of insider threats, and enforces updated security policies like stronger passwords or algorithms. It also ensures operational resilience by testing the rotation process and revoking stale or unused credentials. KubeDB provides `RotateAuth` which reduces manual errors, and strengthens database security with minimal effort. KubeDB Ops-manager generates Recommendation for rotating authentication secrets via this OpsRequest.
+
+`Recommendation` is a Kubernetes `Custom Resource Definitions` (CRD). It provides a declarative recommendation for KubeDB managed databases like [Elasticsearch](https://www.elastic.co/products/elasticsearch) and [OpenSearch](https://opensearch.org/) in a Kubernetes native way. The recommendation will only be created if `.spec.authSecret.rotateAfter` is set. KubeDB generates Elasticsearch/Opensearch Rotate Auth recommendation regarding two particular cases.
+
+1. AuthSecret lifespan is more than one month and, less than one month remaining till expiry
+2. AuthSecret lifespan is less than one month and, less than one third of lifespan remaining till expiry
+
+Let's go through a demo to see `RotateAuth` recommendations being generated. First, get the available Elasticsearch versions provided by KubeDB.
+
+```bash
+$ kubectl get elasticsearchversions | grep xpack
+xpack-6.8.23 6.8.23 ElasticStack ghcr.io/appscode-images/elastic:6.8.23 17h
+xpack-7.13.4 7.13.4 ElasticStack ghcr.io/appscode-images/elastic:7.13.4 17h
+xpack-7.14.2 7.14.2 ElasticStack ghcr.io/appscode-images/elastic:7.14.2 17h
+xpack-7.16.3 7.16.3 ElasticStack ghcr.io/appscode-images/elastic:7.16.3 17h
+xpack-7.17.15 7.17.15 ElasticStack ghcr.io/appscode-images/elastic:7.17.15 17h
+xpack-7.17.23 7.17.23 ElasticStack ghcr.io/appscode-images/elastic:7.17.23 17h
+xpack-7.17.25 7.17.25 ElasticStack ghcr.io/appscode-images/elastic:7.17.25 16h
+xpack-8.11.1 8.11.1 ElasticStack ghcr.io/appscode-images/elastic:8.11.1 17h
+xpack-8.11.4 8.11.4 ElasticStack ghcr.io/appscode-images/elastic:8.11.4 17h
+xpack-8.13.4 8.13.4 ElasticStack ghcr.io/appscode-images/elastic:8.13.4 17h
+xpack-8.14.1 8.14.1 ElasticStack ghcr.io/appscode-images/elastic:8.14.1 17h
+xpack-8.14.3 8.14.3 ElasticStack ghcr.io/appscode-images/elastic:8.14.3 17h
+xpack-8.15.0 8.15.0 ElasticStack ghcr.io/appscode-images/elastic:8.15.0 17h
+xpack-8.15.4 8.15.4 ElasticStack ghcr.io/appscode-images/elastic:8.15.4 16h
+xpack-8.16.0 8.16.0 ElasticStack ghcr.io/appscode-images/elastic:8.16.0 16h
+xpack-8.2.3 8.2.3 ElasticStack ghcr.io/appscode-images/elastic:8.2.3 17h
+xpack-8.5.3 8.5.3 ElasticStack ghcr.io/appscode-images/elastic:8.5.3 17h
+xpack-8.6.2 8.6.2 ElasticStack ghcr.io/appscode-images/elastic:8.6.2 17h
+xpack-8.8.2 8.8.2 ElasticStack ghcr.io/appscode-images/elastic:8.8.2 17h
+```
+
+Let's deploy an Elasticsearch cluster with version `xpack-8.15.0`. We are going to create a cluster topology with 2 master nodes, 3 data nodes and 2 ingest node. We also have to provide an available storageclass for each of the node types.
+
+```yaml
+ apiVersion: kubedb.com/v1
+ kind: Elasticsearch
+ metadata:
+ name: elastic
+ namespace: es
+ spec:
+ version: xpack-8.15.0
+ storageType: Durable
+ deletionPolicy: WipeOut
+ authSecret:
+ rotateAfter: 1h
+ topology:
+ master:
+ replicas: 2
+ storage:
+ storageClassName: "local-path"
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ data:
+ replicas: 2
+ storage:
+ storageClassName: "local-path"
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ ingest:
+ replicas: 1
+ storage:
+ storageClassName: "local-path"
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+```
+
+Wait for a while till elasicsearch cluster gets into `Ready` state. Required time depends on image pulling and node's physical specifications.
+
+```bash
+$ kubectl get es elastic -n es -w
+NAME VERSION STATUS AGE
+elastic xpack-8.15.0 Provisioning 98s
+elastic xpack-8.15.0 Provisioning 5m43s
+elastic xpack-8.15.0 Provisioning 8m7s
+.
+.
+.
+elastic xpack-8.15.0 Ready 10m
+elastic xpack-8.15.0 Ready 10m
+```
+
+Since, `.spec.authSecret.rotateAfter` is set as `1h`, it is expected that the recommendation engine will generate a rotate-auth recommendation at least after 40 minutes (two-third of lifespan) of the authsecret creation. Once generated you will get a similar recommendation as follows.
+
+```bash
+$ kubectl get recommendation -n es | grep rotate-auth
+NAME STATUS OUTDATED AGE
+elastic-x-elasticsearch-x-rotate-auth-2juuee Pending false 10m
+```
+
+The `Recommendation` custom resource will be named as `-x--x--`. Initially, the KubeDB `Supervisor` controller will mark the `Status` of this object to `Pending`. Let's check the complete Recommendation custom resource manifest:
+
+```yaml
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-rotate-auth-2juuee -oyaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: Recommendation
+metadata:
+ creationTimestamp: "2025-02-25T09:12:29Z"
+ generation: 1
+ labels:
+ app.kubernetes.io/instance: elastic
+ app.kubernetes.io/managed-by: kubedb.com
+ app.kubernetes.io/type: rotate-auth
+ name: elastic-x-elasticsearch-x-rotate-auth-2juuee
+ namespace: es
+ resourceVersion: "80116"
+ uid: 12f24cf6-2f02-420f-863d-3523e32a08dd
+spec:
+ backoffLimit: 5
+ deadline: "2025-02-25T09:20:53Z"
+ description: Recommending AuthSecret rotation,elastic-auth AuthSecret needs to be
+ rotated before 2025-02-25 09:30:53 +0000 UTC
+ operation:
+ apiVersion: ops.kubedb.com/v1alpha1
+ kind: ElasticsearchOpsRequest
+ metadata:
+ name: rotate-auth
+ namespace: es
+ spec:
+ databaseRef:
+ name: elastic
+ type: RotateAuth
+ status: {}
+ recommender:
+ name: kubedb-ops-manager
+ rules:
+ failed: has(self.status) && has(self.status.phase) && self.status.phase == 'Failed'
+ inProgress: has(self.status) && has(self.status.phase) && self.status.phase ==
+ 'Progressing'
+ success: has(self.status) && has(self.status.phase) && self.status.phase == 'Successful'
+ target:
+ apiGroup: kubedb.com
+ kind: Elasticsearch
+ name: elastic
+status:
+ approvalStatus: Pending
+ failedAttempt: 0
+ outdated: false
+ parallelism: Namespace
+ phase: Pending
+ reason: WaitingForApproval
+```
+
+In the generated Recommendation you will find a description, targeted db object, recommended operation or Ops-Request manifest, current status of the recommendation etc. Let's just focus on the recommendation description first.
+
+```shell
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-rotate-auth-2juuee -o jsonpath='{.spec.operation}' | yq -y
+apiVersion: ops.kubedb.com/v1alpha1
+kind: ElasticsearchOpsRequest
+metadata:
+ name: rotate-auth
+ namespace: es
+spec:
+ databaseRef:
+ name: elastic
+ type: RotateAuth
+status: {}
+```
+
+Let's check the status part of this recommendation.
+
+```bash
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-rotate-auth-2juuee -o jsonpath='{.status}' | yq -y
+approvalStatus: Pending
+failedAttempt: 0
+outdated: false
+parallelism: Namespace
+phase: Pending
+reason: WaitingForApproval
+```
+
+Now, This recommendation can be approved and operation can be executed immediately by setting `ApprovalStatus` to `Approved` and Setting `approvedWindow` to `Immediate`. You can approve this easily through Appscode UI or edit it manually. Also, You can use kubectl CLI for this -
+
+```bash
+$ kubectl patch Recommendation elastic-x-elasticsearch-x-rotate-auth-2juuee \
+ -n es \
+ --type merge \
+ --subresource='status' \
+ -p '{"status":{"approvalStatus":"Approved","approvedWindow":{"window":"Immediate"}}}'
+recommendation.supervisor.appscode.com/elastic-x-elasticsearch-x-rotate-auth-2juuee patched
+```
+
+Now, check the status part again. You will find a condition have appeared which says `OpsRequest is successfully created`.
+
+```bash
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-rotate-auth-2juuee -o jsonpath='{.status}' | yq -y
+approvalStatus: Approved
+approvedWindow:
+ window: Immediate
+conditions:
+ - lastTransitionTime: '2025-02-25T09:23:29Z'
+ message: OpsRequest is successfully created
+ reason: SuccessfullyCreatedOperation
+ status: 'True'
+ type: SuccessfullyCreatedOperation
+createdOperationRef:
+ name: elastic-1740475409-rotate-auth-auto
+failedAttempt: 0
+outdated: false
+parallelism: Namespace
+phase: InProgress
+reason: StartedExecutingOperation
+```
+
+You will find an `ElasticsearchOpsRequest` custom resource have been created and, it is rotating the authsecret of `elastic` cluster with negligible downtime. Let's wait for it to reach `Successful` status.
+
+```bash
+$ kubectl get elasticsearchopsrequest -n es elastic-1740475409-rotate-auth-auto -w
+NAME TYPE STATUS AGE
+elastic-1740475409-rotate-auth-auto UpdateVersion Progressing 3m12s
+elastic-1740475409-rotate-auth-auto UpdateVersion Progressing 3m34s
+.
+.
+elastic-1740475409-rotate-auth-auto UpdateVersion Successful 11m
+```
+
+Let's recheck the recommendation for one last time. We should find that `.status.phase` has been marked as `Succeeded`.
+
+```bash
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-rotate-auth-2juuee
+NAME STATUS OUTDATED AGE
+elastic-x-elasticsearch-x-rotate-auth-2juuee Succeeded false 78m
+```
+
+You may not want to do trigger recommended operations manually. Rather, trigger them autonomously in a preferred schedule when infrastructure is idle or traffic rate is at the lowest. For this purpose, You can create a `MaintenanceWindow` custom resource where you can set your desired schedule/period for triggering these recommended operations automatically. Here's a sample one:
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: MaintenanceWindow
+metadata:
+ name: elastic-maintenance
+ namespace: es
+spec:
+ timezone: Asia/Dhaka
+ days:
+ Wednesday:
+ - start: 5:40AM
+ end: 7:00PM
+ dates:
+ - start: 2025-01-25T00:00:18Z
+ end: 2025-01-25T23:41:18Z
+```
+
+You can now create a `ApprovalPolicy` custom resource to refer this `MaintenanceWindow` for particular DB type. Following is a sample `ApprovalPolicy` for any `Elasticsearch` custom resource deployed in `es` namespace. This `ApprovalPolicy` custom resource is referring to the `elastic-maintenance` MaintenanceWindow created in the same namespace. You can also create `ClusterMaintenanceWindow` instead which is effective for cluster-wide operations and refer it here. The following ApprovalPolicy will trigger recommended operations when referred maintenance window timeframe is reached.
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: ApprovalPolicy
+metadata:
+ name: es-policy
+ namespace: es
+maintenanceWindowRef:
+ name: elastic-maintenance
+targets:
+ - group: kubedb.com
+ kind: Elasticsearch
+ operations:
+ - group: ops.kubedb.com
+ kind: ElasticsearchOpsRequest
+```
+
+Lastly, If you want to reject a recommendation, you can just set `ApprovalStatus` to `Rejected` in the recommendation status section. Here's how you can do it using kubectl cli.
+
+```bash
+$ kubectl patch Recommendation elastic-x-elasticsearch-x-rotate-auth-2juuee \
+ -n es \
+ --type merge \
+ --subresource='status' \
+ -p '{"status":{"approvalStatus":"Rejected"}}'
+recommendation.supervisor.appscode.com/elastic-x-elasticsearch-x-rotate-auth-2juuee patched
+```
+
+
+## Next Steps
+
+- Learn about [backup & restore](/docs/guides/elasticsearch/backup/stash/overview/index.md) Elasticsearch database using Stash.
+- Learn how to configure [Elasticsearch Topology Cluster](/docs/guides/elasticsearch/clustering/topology-cluster/simple-dedicated-cluster/index.md).
+- Monitor your Elasticsearch database with KubeDB using [`out-of-the-box` Prometheus operator](/docs/guides/elasticsearch/monitoring/using-prometheus-operator.md).
+- Use [private Docker registry](/docs/guides/elasticsearch/private-registry/using-private-registry.md) to deploy Elasticsearch with KubeDB.
+- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md).
diff --git a/docs/guides/elasticsearch/recommendation/rotate-tls-recommendation.md b/docs/guides/elasticsearch/recommendation/rotate-tls-recommendation.md
new file mode 100644
index 0000000000..fbdfbfafcc
--- /dev/null
+++ b/docs/guides/elasticsearch/recommendation/rotate-tls-recommendation.md
@@ -0,0 +1,367 @@
+---
+title: Elasticsearch Rotate TLS Recommendation
+menu:
+ docs_{{ .version }}:
+ identifier: es-rotate-tls-recommendation
+ name: Rotate TLS Recommendation
+ parent: es-recommendation-elasticsearch
+ weight: 30
+menu_name: docs_{{ .version }}
+section_menu_id: guides
+---
+
+> New to KubeDB? Please start [here](/docs/README.md).
+
+# Elasticsearch Rotate TLS Recommendation
+
+TLS certificate rotation in databases is essential for maintaining security, ensuring compliance, and preventing service disruptions. Regular rotation mitigates risks like certificate expiry and key compromise, adapts to evolving cryptographic standards, and maintains trust relationships with Certificate Authorities. It also enhances operational resilience by testing renewal processes and ensures smooth auditing and monitoring. To minimize risks and streamline the process, KubeDB provides ReconfigureTLS OpsRequest support. KubeDB Ops-manager generates Recommendation to rotate TLS certificates via this OpsRequest when their expiry is near.
+
+`Recommendation` is a Kubernetes `Custom Resource Definitions` (CRD). It provides a declarative recommendation for KubeDB managed databases like [Elasticsearch](https://www.elastic.co/products/elasticsearch) and [OpenSearch](https://opensearch.org/) in a Kubernetes native way. KubeDB generates Elasticsearch/Opensearch Rotate TLS recommendation regarding if:
+
+- At least one of its certificate’s lifespan is more than one month and less than one month remaining till expiry
+
+- At least one of its certificates has one-third of its lifespan remaining till expiry.
+
+Let's go through a demo to see `RotateTLS` recommendations being generated. First, get the available Elasticsearch versions provided by KubeDB.
+
+```bash
+$ kubectl get elasticsearchversions | grep xpack
+xpack-6.8.23 6.8.23 ElasticStack ghcr.io/appscode-images/elastic:6.8.23 17h
+xpack-7.13.4 7.13.4 ElasticStack ghcr.io/appscode-images/elastic:7.13.4 17h
+xpack-7.14.2 7.14.2 ElasticStack ghcr.io/appscode-images/elastic:7.14.2 17h
+xpack-7.16.3 7.16.3 ElasticStack ghcr.io/appscode-images/elastic:7.16.3 17h
+xpack-7.17.15 7.17.15 ElasticStack ghcr.io/appscode-images/elastic:7.17.15 17h
+xpack-7.17.23 7.17.23 ElasticStack ghcr.io/appscode-images/elastic:7.17.23 17h
+xpack-7.17.25 7.17.25 ElasticStack ghcr.io/appscode-images/elastic:7.17.25 16h
+xpack-8.11.1 8.11.1 ElasticStack ghcr.io/appscode-images/elastic:8.11.1 17h
+xpack-8.11.4 8.11.4 ElasticStack ghcr.io/appscode-images/elastic:8.11.4 17h
+xpack-8.13.4 8.13.4 ElasticStack ghcr.io/appscode-images/elastic:8.13.4 17h
+xpack-8.14.1 8.14.1 ElasticStack ghcr.io/appscode-images/elastic:8.14.1 17h
+xpack-8.14.3 8.14.3 ElasticStack ghcr.io/appscode-images/elastic:8.14.3 17h
+xpack-8.15.0 8.15.0 ElasticStack ghcr.io/appscode-images/elastic:8.15.0 17h
+xpack-8.15.4 8.15.4 ElasticStack ghcr.io/appscode-images/elastic:8.15.4 16h
+xpack-8.16.0 8.16.0 ElasticStack ghcr.io/appscode-images/elastic:8.16.0 16h
+xpack-8.2.3 8.2.3 ElasticStack ghcr.io/appscode-images/elastic:8.2.3 17h
+xpack-8.5.3 8.5.3 ElasticStack ghcr.io/appscode-images/elastic:8.5.3 17h
+xpack-8.6.2 8.6.2 ElasticStack ghcr.io/appscode-images/elastic:8.6.2 17h
+xpack-8.8.2 8.8.2 ElasticStack ghcr.io/appscode-images/elastic:8.8.2 17h
+```
+
+Let's deploy an Elasticsearch cluster with version `xpack-8.15.0`. We are going to create a cluster topology with 2 master nodes, 3 data nodes and 2 ingest node. We also have to provide an available storageclass for each of the node types. Make sure to have an issuer/clusterIssuer to refer in the manifest. Though KubeDB managed elasticsearch supports TLS in both cert-manager provisioned and Operator provisioned ways, rotate tls only works when certificates are provisioned via cert-manager.
+
+```yaml
+apiVersion: kubedb.com/v1
+kind: Elasticsearch
+metadata:
+ name: elastic
+ namespace: es
+spec:
+ deletionPolicy: WipeOut
+ kernelSettings:
+ disableDefaults: false
+ storageType: Durable
+ enableSSL: true
+ tls:
+ issuerRef:
+ apiGroup: "cert-manager.io"
+ kind: Issuer
+ name: ca-issuer
+ certificates:
+ - alias: client
+ duration: 1h20m
+ - alias: http
+ duration: 2h10m
+ topology:
+ data:
+ podTemplate:
+ spec:
+ containers:
+ - name: elasticsearch
+ resources:
+ limits:
+ cpu: 500m
+ memory: 1536Mi
+ requests:
+ cpu: 500m
+ memory: 1536Mi
+ nodeSelector:
+ kubernetes.io/os: linux
+ podPlacementPolicy:
+ name: default
+ replicas: 3
+ storage:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 5Gi
+ storageClassName: local-path
+ ingest:
+ podTemplate:
+ spec:
+ containers:
+ - name: elasticsearch
+ resources:
+ limits:
+ cpu: 500m
+ memory: 1536Mi
+ requests:
+ cpu: 500m
+ memory: 1536Mi
+ nodeSelector:
+ kubernetes.io/os: linux
+ podPlacementPolicy:
+ name: default
+ replicas: 2
+ storage:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ storageClassName: local-path
+ master:
+ podTemplate:
+ spec:
+ containers:
+ - name: elasticsearch
+ resources:
+ limits:
+ cpu: 500m
+ memory: 1536Mi
+ requests:
+ cpu: 500m
+ memory: 1536Mi
+ nodeSelector:
+ kubernetes.io/os: linux
+ podPlacementPolicy:
+ name: default
+ replicas: 2
+ storage:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 3Gi
+ storageClassName: local-path
+ version: xpack-8.15.0
+```
+
+Wait for a while till elasicsearch cluster gets into `Ready` state. Required time depends on image pulling and node's physical specifications.
+
+```bash
+$ kubectl get es elastic -n es -w
+NAME VERSION STATUS AGE
+elastic xpack-8.15.0 Provisioning 98s
+elastic xpack-8.15.0 Provisioning 5m43s
+elastic xpack-8.15.0 Provisioning 8m7s
+.
+.
+.
+elastic xpack-8.15.0 Ready 10m
+elastic xpack-8.15.0 Ready 10m
+```
+
+Since,duration for client certificate is set as `1h20min`, it is expected that the recommendation engine will generate a rotate-auth recommendation at least after 54 minutes (two-third of lifespan) of the client certificate creation. Once generated you will get a similar recommendation as follows.
+
+```bash
+$ kubectl get recommendation -n es | grep rotate-tls
+NAME STATUS OUTDATED AGE
+elastic-x-elasticsearch-x-rotate-tls-6ujvez Pending false 74s
+```
+
+The `Recommendation` custom resource will be named as `-x--x--`. Initially, the KubeDB `Supervisor` controller will mark the `Status` of this object to `Pending`. Let's check the complete Recommendation custom resource manifest:
+
+```yaml
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-rotate-tls-6ujvez -oyaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: Recommendation
+metadata:
+ creationTimestamp: "2025-02-27T11:50:04Z"
+ generation: 1
+ labels:
+ app.kubernetes.io/instance: elastic
+ app.kubernetes.io/managed-by: kubedb.com
+ app.kubernetes.io/type: rotate-tls
+ name: elastic-x-elasticsearch-x-rotate-tls-6ujvez
+ namespace: es
+ resourceVersion: "309401"
+ uid: d208df6b-5fbf-4122-b7b7-18e73a4e1d6c
+spec:
+ backoffLimit: 5
+ deadline: "2025-02-27T11:59:43Z"
+ description: Recommending TLS certificate rotation,elastic-client-cert Certificate
+ is going to be expire on 2025-02-27 12:04:43 +0000 UTC
+ operation:
+ apiVersion: ops.kubedb.com/v1alpha1
+ kind: ElasticsearchOpsRequest
+ metadata:
+ name: rotate-tls
+ namespace: es
+ spec:
+ databaseRef:
+ name: elastic
+ tls:
+ rotateCertificates: true
+ type: ReconfigureTLS
+ status: {}
+ recommender:
+ name: kubedb-ops-manager
+ rules:
+ failed: has(self.status) && has(self.status.phase) && self.status.phase == 'Failed'
+ inProgress: has(self.status) && has(self.status.phase) && self.status.phase ==
+ 'Progressing'
+ success: has(self.status) && has(self.status.phase) && self.status.phase == 'Successful'
+ target:
+ apiGroup: kubedb.com
+ kind: Elasticsearch
+ name: elastic
+status:
+ approvalStatus: Pending
+ failedAttempt: 0
+ outdated: false
+ parallelism: Namespace
+ phase: Pending
+ reason: WaitingForApproval
+```
+
+In the generated Recommendation you will find a description, targeted db object, recommended operation or Ops-Request manifest, current status of the recommendation etc. Let's just focus on the recommendation description first.
+
+```shell
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-rotate-tls-6ujvez -o jsonpath='{.spec.operation}' | yq -y
+apiVersion: ops.kubedb.com/v1alpha1
+kind: ElasticsearchOpsRequest
+metadata:
+ name: rotate-tls
+ namespace: es
+spec:
+ databaseRef:
+ name: elastic
+ tls:
+ rotateCertificates: true
+ type: ReconfigureTLS
+status: {}
+```
+
+Let's check the status part of this recommendation.
+
+```bash
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-rotate-tls-6ujvez -o jsonpath='{.status}' | yq -y
+approvalStatus: Pending
+failedAttempt: 0
+outdated: false
+parallelism: Namespace
+phase: Pending
+reason: WaitingForApproval
+```
+
+Now, This recommendation can be approved and operation can be executed immediately by setting `ApprovalStatus` to `Approved` and Setting `approvedWindow` to `Immediate`. You can approve this easily through Appscode UI or edit it manually. Also, You can use kubectl CLI for this -
+
+```bash
+$ kubectl patch Recommendation elastic-x-elasticsearch-x-rotate-tls-6ujvez \
+ -n es \
+ --type merge \
+ --subresource='status' \
+ -p '{"status":{"approvalStatus":"Approved","approvedWindow":{"window":"Immediate"}}}'
+recommendation.supervisor.appscode.com/elastic-x-elasticsearch-x-rotate-tls-6ujvez patched
+```
+
+Now, check the status part again. You will find a condition have appeared which says `OpsRequest is successfully created`.
+
+```bash
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-rotate-tls-6ujvez -o jsonpath='{.status}' | yq -y
+approvalStatus: Approved
+approvedWindow:
+ window: Immediate
+conditions:
+ - lastTransitionTime: '2025-02-27T11:54:50Z'
+ message: OpsRequest is successfully created
+ reason: SuccessfullyCreatedOperation
+ status: 'True'
+ type: SuccessfullyCreatedOperation
+createdOperationRef:
+ name: elastic-1740657290-rotate-tls-auto
+failedAttempt: 0
+outdated: false
+parallelism: Namespace
+phase: InProgress
+reason: StartedExecutingOperation
+```
+
+You will find an `ElasticsearchOpsRequest` custom resource have been created and, it is rotating the authsecret of `elastic` cluster with negligible downtime. Let's wait for it to reach `Successful` status.
+
+```bash
+$ kubectl get elasticsearchopsrequest -n es elastic-1740657290-rotate-tls-auto -w
+NAME TYPE STATUS AGE
+elastic-1740657290-rotate-tls-auto ReconfigureTLS Progressing 60s
+elastic-1740657290-rotate-tls-auto ReconfigureTLS Progressing 114s
+.
+.
+elastic-1740657290-rotate-tls-auto ReconfigureTLS Successful 12m
+
+```
+
+Let's recheck the recommendation for one last time. We should find that `.status.phase` has been marked as `Succeeded`.
+
+```bash
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-rotate-tls-6ujvez
+NAME STATUS OUTDATED AGE
+elastic-x-elasticsearch-x-rotate-tls-6ujvez Succeeded false 78m
+```
+
+You may not want to do trigger recommended operations manually. Rather, trigger them autonomously in a preferred schedule when infrastructure is idle or traffic rate is at the lowest. For this purpose, You can create a `MaintenanceWindow` custom resource where you can set your desired schedule/period for triggering these recommended operations automatically. Here's a sample one:
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: MaintenanceWindow
+metadata:
+ name: elastic-maintenance
+ namespace: es
+spec:
+ timezone: Asia/Dhaka
+ days:
+ Wednesday:
+ - start: 5:40AM
+ end: 7:00PM
+ dates:
+ - start: 2025-01-25T00:00:18Z
+ end: 2025-01-25T23:41:18Z
+```
+
+You can now create a `ApprovalPolicy` custom resource to refer this `MaintenanceWindow` for particular DB type. Following is a sample `ApprovalPolicy` for any `Elasticsearch` custom resource deployed in `es` namespace. This `ApprovalPolicy` custom resource is referring to the `elastic-maintenance` MaintenanceWindow created in the same namespace. You can also create `ClusterMaintenanceWindow` instead which is effective for cluster-wide operations and refer it here. The following ApprovalPolicy will trigger recommended operations when referred maintenance window timeframe is reached.
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: ApprovalPolicy
+metadata:
+ name: es-policy
+ namespace: es
+maintenanceWindowRef:
+ name: elastic-maintenance
+targets:
+ - group: kubedb.com
+ kind: Elasticsearch
+ operations:
+ - group: ops.kubedb.com
+ kind: ElasticsearchOpsRequest
+```
+
+Lastly, If you want to reject a recommendation, you can just set `ApprovalStatus` to `Rejected` in the recommendation status section. Here's how you can do it using kubectl cli.
+
+```bash
+$ kubectl patch Recommendation elastic-x-elasticsearch-x-rotate-tls-6ujvez \
+ -n es \
+ --type merge \
+ --subresource='status' \
+ -p '{"status":{"approvalStatus":"Rejected"}}'
+recommendation.supervisor.appscode.com/elastic-x-elasticsearch-x-rotate-tls-6ujvez patched
+```
+
+
+## Next Steps
+
+- Learn about [backup & restore](/docs/guides/elasticsearch/backup/stash/overview/index.md) Elasticsearch database using Stash.
+- Learn how to configure [Elasticsearch Topology Cluster](/docs/guides/elasticsearch/clustering/topology-cluster/simple-dedicated-cluster/index.md).
+- Monitor your Elasticsearch database with KubeDB using [`out-of-the-box` Prometheus operator](/docs/guides/elasticsearch/monitoring/using-prometheus-operator.md).
+- Use [private Docker registry](/docs/guides/elasticsearch/private-registry/using-private-registry.md) to deploy Elasticsearch with KubeDB.
+- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md).
diff --git a/docs/guides/elasticsearch/recommendation/version-update-recommendation.md b/docs/guides/elasticsearch/recommendation/version-update-recommendation.md
new file mode 100644
index 0000000000..c751a498ed
--- /dev/null
+++ b/docs/guides/elasticsearch/recommendation/version-update-recommendation.md
@@ -0,0 +1,327 @@
+---
+title: Elasticsearch Version Update Recommendation
+menu:
+ docs_{{ .version }}:
+ identifier: es-version-update-recommendation
+ name: Version Update Recommendation
+ parent: es-recommendation-elasticsearch
+ weight: 20
+menu_name: docs_{{ .version }}
+section_menu_id: guides
+---
+
+> New to KubeDB? Please start [here](/docs/README.md).
+
+# Elasticsearch Version Update Recommendation
+
+Database versions often need to be updated due to several reasons. Older database versions may have vulnerabilities that hackers can exploit. New versions often include optimizations for query execution, indexing, and storage mechanisms. Modern databases frequently introduce new features, such as better data types, improved indexing methods, or advanced analytics capabilities. Database vendors release patches and updates to address these issues and introduce new features.
+
+`Recommendation` is a Kubernetes `Custom Resource Definitions` (CRD). It provides a declarative recommendation for KubeDB managed databases like [Elasticsearch](https://www.elastic.co/products/elasticsearch) and [OpenSearch](https://opensearch.org/) in a Kubernetes native way. KubeDB generates Elasticsearch/Opensearch Version Update recommendation regarding three particular cases.
+
+1. There's been an update in the current version image
+2. There's a new major/minor version available
+3. There's a version available with patch fix
+
+Let's go through a demo to see version update recommendations being generated. First, get the available Elasticsearch versions provided by KubeDB.
+
+```bash
+$ kubectl get elasticsearchversions | grep xpack
+xpack-6.8.23 6.8.23 ElasticStack ghcr.io/appscode-images/elastic:6.8.23 17h
+xpack-7.13.4 7.13.4 ElasticStack ghcr.io/appscode-images/elastic:7.13.4 17h
+xpack-7.14.2 7.14.2 ElasticStack ghcr.io/appscode-images/elastic:7.14.2 17h
+xpack-7.16.3 7.16.3 ElasticStack ghcr.io/appscode-images/elastic:7.16.3 17h
+xpack-7.17.15 7.17.15 ElasticStack ghcr.io/appscode-images/elastic:7.17.15 17h
+xpack-7.17.23 7.17.23 ElasticStack ghcr.io/appscode-images/elastic:7.17.23 17h
+xpack-7.17.25 7.17.25 ElasticStack ghcr.io/appscode-images/elastic:7.17.25 16h
+xpack-8.11.1 8.11.1 ElasticStack ghcr.io/appscode-images/elastic:8.11.1 17h
+xpack-8.11.4 8.11.4 ElasticStack ghcr.io/appscode-images/elastic:8.11.4 17h
+xpack-8.13.4 8.13.4 ElasticStack ghcr.io/appscode-images/elastic:8.13.4 17h
+xpack-8.14.1 8.14.1 ElasticStack ghcr.io/appscode-images/elastic:8.14.1 17h
+xpack-8.14.3 8.14.3 ElasticStack ghcr.io/appscode-images/elastic:8.14.3 17h
+xpack-8.15.0 8.15.0 ElasticStack ghcr.io/appscode-images/elastic:8.15.0 17h
+xpack-8.15.4 8.15.4 ElasticStack ghcr.io/appscode-images/elastic:8.15.4 16h
+xpack-8.16.0 8.16.0 ElasticStack ghcr.io/appscode-images/elastic:8.16.0 16h
+xpack-8.2.3 8.2.3 ElasticStack ghcr.io/appscode-images/elastic:8.2.3 17h
+xpack-8.5.3 8.5.3 ElasticStack ghcr.io/appscode-images/elastic:8.5.3 17h
+xpack-8.6.2 8.6.2 ElasticStack ghcr.io/appscode-images/elastic:8.6.2 17h
+xpack-8.8.2 8.8.2 ElasticStack ghcr.io/appscode-images/elastic:8.8.2 17h
+```
+
+Let's deploy an Elasticsearch cluster with version `xpack-8.15.0`. We are going to create a cluster topology with 2 master nodes, 3 data nodes and 2 ingest node. We also have to provide an available storageclass for each of the node types.
+
+```yaml
+apiVersion: kubedb.com/v1
+kind: Elasticsearch
+metadata:
+ name: elastic
+ namespace: es
+spec:
+ version: xpack-8.15.0
+ storageType: Durable
+ deletionPolicy: WipeOut
+ topology:
+ master:
+ replicas: 2
+ storage:
+ storageClassName: "local-path"
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ data:
+ replicas: 3
+ storage:
+ storageClassName: "local-path"
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+ ingest:
+ replicas: 2
+ storage:
+ storageClassName: "local-path"
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 1Gi
+```
+
+Wait for a while till elasicsearch cluster gets into `Ready` state. Required time depends on image pulling and node's physical specifications.
+
+```bash
+$ kubectl get es elastic -n es -w
+NAME VERSION STATUS AGE
+elastic xpack-8.15.0 Provisioning 98s
+elastic xpack-8.15.0 Provisioning 5m43s
+elastic xpack-8.15.0 Provisioning 8m7s
+.
+.
+.
+elastic xpack-8.15.0 Ready 10m
+elastic xpack-8.15.0 Ready 10m
+```
+
+Once elastic instance is `Ready`, a `Recommendation` instance will be automatically generated by KubeDB `Ops-Manager` controller. Might take a few minutes to trigger an event for the database creation in the controller.
+
+```bash
+$ kubectl get recommendation -n es
+NAME STATUS OUTDATED AGE
+elastic-x-elasticsearch-x-update-version-2juuee Pending false 10m
+```
+
+The `Recommendation` custom resource will be named as `-x--x--`. Initially, the KubeDB `Supervisor` controller will mark the `Status` of this object to `Pending`. Let's check the complete Recommendation custom resource manifest:
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: Recommendation
+metadata:
+ annotations:
+ kubedb.com/recommendation-for-version: xpack-8.15.0
+ creationTimestamp: "2025-01-29T12:06:43Z"
+ generation: 5
+ labels:
+ app.kubernetes.io/instance: elastic
+ app.kubernetes.io/managed-by: kubedb.com
+ app.kubernetes.io/type: version-update
+ kubedb.com/version-update-recommendation-type: major-minor
+ name: elastic-x-elasticsearch-x-update-version-2juuee
+ namespace: es
+ resourceVersion: "783271"
+ uid: 3026d740-64fd-4ac4-8f33-2bd305ab0e69
+spec:
+ backoffLimit: 5
+ description: Latest Major/Minor version is available. Recommending version Update
+ from xpack-8.15.0 to xpack-8.16.0.
+ operation:
+ apiVersion: ops.kubedb.com/v1alpha1
+ kind: ElasticsearchOpsRequest
+ metadata:
+ name: update-version
+ namespace: es
+ spec:
+ databaseRef:
+ name: elastic
+ type: UpdateVersion
+ updateVersion:
+ targetVersion: xpack-8.16.0
+ status: {}
+ recommender:
+ name: kubedb-ops-manager
+ requireExplicitApproval: true
+ rules:
+ failed: has(self.status) && has(self.status.phase) && self.status.phase == 'Failed'
+ inProgress: has(self.status) && has(self.status.phase) && self.status.phase ==
+ 'Progressing'
+ success: has(self.status) && has(self.status.phase) && self.status.phase == 'Successful'
+ target:
+ apiGroup: kubedb.com
+ kind: Elasticsearch
+ name: elastic
+ vulnerabilityReport:
+ message: 'ImageScanRequest phase is not Current: timed out waiting for the condition'
+ status: Failure
+status:
+ approvalStatus: Pending
+ failedAttempt: 0
+ outdated: false
+ parallelism: Namespace
+ phase: Pending
+ reason: WaitingForApproval
+```
+
+In the generated Recommendation you will find a description, targeted db object, recommended operation or Ops-Request manifest, current status of the recommendation etc. Let's just focus on the recommendation description first.
+
+```shell
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-update-version-2juuee -o jsonpath='{.spec.description}'
+Latest Major/Minor version is available. Recommending version Update from xpack-8.15.0 to xpack-8.16.0.
+```
+
+The recommendation says current version `xpack-8.15.0` should be upgraded to latest upgradable version `xpack-8.16.0`. You can also find the recommended operation which is a `ElasticsearchOpsRequest` of `UpdateVersion` type in this case.
+
+```shell
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-update-version-2juuee -o jsonpath='{.spec.operation}' | yq -y
+apiVersion: ops.kubedb.com/v1alpha1
+kind: ElasticsearchOpsRequest
+metadata:
+ name: update-version
+ namespace: es
+spec:
+ databaseRef:
+ name: elastic
+ type: UpdateVersion
+ updateVersion:
+ targetVersion: xpack-8.16.0
+status: {}
+```
+
+Let's check the status part of this recommendation.
+
+```bash
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-update-version-2juuee -o jsonpath='{.status}' | yq -y
+approvalStatus: Pending
+failedAttempt: 0
+outdated: false
+parallelism: Namespace
+phase: Pending
+reason: WaitingForApproval
+```
+
+Now, This recommendation can be approved and operation can be executed immediately by setting `ApprovalStatus` to `Approved` and Setting `approvedWindow` to `Immediate`. You can approve this easily through Appscode UI or edit it manually. Also, You can use kubectl CLI for this -
+
+```bash
+$ kubectl patch Recommendation elastic-x-elasticsearch-x-update-version-2juuee \
+ -n es \
+ --type merge \
+ --subresource='status' \
+ -p '{"status":{"approvalStatus":"Approved","approvedWindow":{"window":"Immediate"}}}'
+recommendation.supervisor.appscode.com/elastic-x-elasticsearch-x-update-version-2juuee patched
+```
+
+Now, check the status part again. You will find a condition have appeared which says `OpsRequest is successfully created`.
+
+```bash
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-update-version-2juuee -o jsonpath='{.status}' | yq -y
+approvalStatus: Approved
+approvedWindow:
+ window: Immediate
+conditions:
+ - lastTransitionTime: '2025-01-29T13:01:40Z'
+ message: OpsRequest is successfully created
+ reason: SuccessfullyCreatedOperation
+ status: 'True'
+ type: SuccessfullyCreatedOperation
+createdOperationRef:
+ name: elastic-1738155700-update-version-auto
+failedAttempt: 0
+outdated: false
+parallelism: Namespace
+phase: InProgress
+reason: StartedExecutingOperation
+```
+
+You will find an `ElasticsearchOpsRequest` custom resource have been created and, it is updating the `elastic` cluster version to `xpack-8.16.0` with negligible downtime. Let's wait for it to reach `Successful` status.
+
+```bash
+$ kubectl get elasticsearchopsrequest -n es elastic-1738155700-update-version-auto -w
+NAME TYPE STATUS AGE
+elastic-1738155700-update-version-auto UpdateVersion Progressing 3m12s
+elastic-1738155700-update-version-auto UpdateVersion Progressing 3m34s
+.
+.
+elastic-1738155700-update-version-auto UpdateVersion Successful 11m
+```
+
+Let's recheck the recommendation for one last time. We should find that `.status.phase` has been marked as `Succeeded`.
+
+```bash
+$ kubectl get recommendation -n es elastic-x-elasticsearch-x-update-version-2juuee
+NAME STATUS OUTDATED AGE
+elastic-x-elasticsearch-x-update-version-2juuee Succeeded false 78m
+```
+
+Finally, You can check `elastic` cluster version now, which should be upgraded to version `xpack-8.16.0`.
+
+```bash
+$ kubectl get es elastic -n es
+NAME VERSION STATUS AGE
+elastic xpack-8.16.0 Ready 85m
+```
+
+You may not want to do trigger recommended operations manually. Rather, trigger them autonomously in a preferred schedule when infrastructure is idle or traffic rate is at the lowest. For this purpose, You can create a `MaintenanceWindow` custom resource where you can set your desired schedule/period for triggering these recommended operations automatically. Here's a sample one:
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: MaintenanceWindow
+metadata:
+ name: elastic-maintenance
+ namespace: es
+spec:
+ timezone: Asia/Dhaka
+ days:
+ Wednesday:
+ - start: 5:40AM
+ end: 7:00PM
+ dates:
+ - start: 2025-01-25T00:00:18Z
+ end: 2025-01-25T23:41:18Z
+```
+
+You can now create a `ApprovalPolicy` custom resource to refer this `MaintenanceWindow` for particular DB type. Following is a sample `ApprovalPolicy` for any `Elasticsearch` custom resource deployed in `es` namespace. This `ApprovalPolicy` custom resource is referring to the `elastic-maintenance` MaintenanceWindow created in the same namespace. You can also create `ClusterMaintenanceWindow` instead which is effective for cluster-wide operations and refer it here. The following ApprovalPolicy will trigger recommended operations when referred maintenance window timeframe is reached.
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: ApprovalPolicy
+metadata:
+ name: es-policy
+ namespace: es
+maintenanceWindowRef:
+ name: elastic-maintenance
+targets:
+ - group: kubedb.com
+ kind: Elasticsearch
+ operations:
+ - group: ops.kubedb.com
+ kind: ElasticsearchOpsRequest
+```
+
+Lastly, If you want to reject a recommendation, you can just set `ApprovalStatus` to `Rejected` in the recommendation status section. Here's how you can do it using kubectl cli.
+
+```bash
+$ kubectl patch Recommendation elastic-x-elasticsearch-x-update-version-2juuee \
+ -n es \
+ --type merge \
+ --subresource='status' \
+ -p '{"status":{"approvalStatus":"Rejected"}}'
+recommendation.supervisor.appscode.com/elastic-x-elasticsearch-x-update-version-2juuee patched
+```
+
+## Next Steps
+
+- Learn about [backup & restore](/docs/guides/elasticsearch/backup/stash/overview/index.md) Elasticsearch database using Stash.
+- Learn how to configure [Elasticsearch Topology Cluster](/docs/guides/elasticsearch/clustering/topology-cluster/simple-dedicated-cluster/index.md).
+- Monitor your Elasticsearch database with KubeDB using [`out-of-the-box` Prometheus operator](/docs/guides/elasticsearch/monitoring/using-prometheus-operator.md).
+- Use [private Docker registry](/docs/guides/elasticsearch/private-registry/using-private-registry.md) to deploy Elasticsearch with KubeDB.
+- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md).
diff --git a/docs/guides/mongodb/recommendation/_index.md b/docs/guides/mongodb/recommendation/_index.md
new file mode 100755
index 0000000000..e466b323b1
--- /dev/null
+++ b/docs/guides/mongodb/recommendation/_index.md
@@ -0,0 +1,11 @@
+---
+title: MongoDB Recommendation
+menu:
+ docs_{{ .version }}:
+ identifier: mg-recommendation-mongodb
+ name: Recommendation
+ parent: mg-mongodb-guides
+ weight: 60
+menu_name: docs_{{ .version }}
+---
+
diff --git a/docs/guides/mongodb/recommendation/images/recommendation-generation.png b/docs/guides/mongodb/recommendation/images/recommendation-generation.png
new file mode 100644
index 0000000000..dd96452a27
Binary files /dev/null and b/docs/guides/mongodb/recommendation/images/recommendation-generation.png differ
diff --git a/docs/guides/mongodb/recommendation/overview.md b/docs/guides/mongodb/recommendation/overview.md
new file mode 100644
index 0000000000..5a0e8b51e6
--- /dev/null
+++ b/docs/guides/mongodb/recommendation/overview.md
@@ -0,0 +1,42 @@
+---
+title: MongoDB Recommendation
+description: MongoDB Recommendation Overview
+menu:
+ docs_{{ .version }}:
+ identifier: mg-recommendation-overview
+ name: Overview
+ parent: mg-recommendation-mongodb
+ weight: 10
+menu_name: docs_{{ .version }}
+section_menu_id: guides
+---
+
+> New to KubeDB? Please start [here](/docs/README.md).
+
+# Recommendation for KubeDB managed MongoDB
+
+Databases on Kubernetes in production grade infrastructure often need to go through several administrative operations depending on specific resource requirements. Such operations include vertical scaling (cpu, memory) and storage expansion. Autoscaling support for KubeDB managed databases takes care of it. However, databases also need to go through some maintenance operations in order to ensure security, enhance performance, getting bug fixes and new features etc. Such operations mostly require organization's manual intervention. Even if these operations are automated, they need to be done in surveillance. KubeDB simplifies this by generating K8s Native Recommendations.
+
+## Overview
+
+Recommendation is a custom resource definition (CRD) object which is created by KubeDB ops-manager controller and managed by supervisor. So, You need to have KubeDB and Supervisor installed first. You can simply install supervisor along with other KubeDB components using `--set supervisor.enabled=true` flag while installing KubeDB via helm chart.
+
+
+
+
+
+KubeDB provisioner watches user provided database custom resource spec and creates/sync all the necessary DB resources. Once the Database is ready KubeDB Ops-manager watches the DB and creates Recommendation if it requires. KubeDB Supervisor then watches the Recommendation, updates status of the recommendation, creates recommended operation via OpsRequest if deadline reaches or manually triggered and watches the OpsRequest status to update accordingly in Recommendation custom resource.
+
+KubeDB provides Three types of recommendation for MongoDB.
+
+1. [Version Update Recommendation](/docs/guides/mongodb/recommendation/version-update-recommendation.md)
+2. [TLS Certificate Rotation Recommendation](/docs/guides/mongodb/recommendation/rotate-tls-recommendation.md)
+3. [Authentication Secret Rotation Recommendation](/docs/guides/mongodb/recommendation/rotate-auth-recommendation.md)
+
+The next page describes these recommendations, how to approve/reject them, their generation mechanism and usability.
+
+## Next Steps
+
+- Learn about MongoDB [Version Update Recommendation](/docs/guides/mongodb/recommendation/version-update-recommendation.md).
+- Learn about MongoDB [TLS Certificate Rotation Recommendation](/docs/guides/mongodb/recommendation/rotate-tls-recommendation.md)
+- Learn about MongoDB [Authentication Secret Rotation Recommendation](/docs/guides/mongodb/recommendation/rotate-auth-recommendation.md)
diff --git a/docs/guides/mongodb/recommendation/rotate-auth-recommendation.md b/docs/guides/mongodb/recommendation/rotate-auth-recommendation.md
new file mode 100644
index 0000000000..69ba69dea8
--- /dev/null
+++ b/docs/guides/mongodb/recommendation/rotate-auth-recommendation.md
@@ -0,0 +1,327 @@
+---
+title: MongoDB Rotate Auth Recommendation
+menu:
+ docs_{{ .version }}:
+ identifier: mg-rotate-auth-recommendation
+ name: Rotate Auth Recommendation
+ parent: mg-recommendation-mongodb
+ weight: 40
+menu_name: docs_{{ .version }}
+section_menu_id: guides
+---
+
+> New to KubeDB? Please start [here](/docs/README.md).
+
+# MongoDB Version Update Recommendation
+
+Rotating authentication secrets in database management is vital to mitigate security risks, such as credential leakage or unauthorized access, and to comply with regulatory requirements. Regular rotation limits the exposure of compromised credentials, reduces the risk of insider threats, and enforces updated security policies like stronger passwords or algorithms. It also ensures operational resilience by testing the rotation process and revoking stale or unused credentials. KubeDB provides `RotateAuth` which reduces manual errors, and strengthens database security with minimal effort. KubeDB Ops-manager generates Recommendation for rotating authentication secrets via this OpsRequest.
+
+`Recommendation` is a Kubernetes `Custom Resource Definitions` (CRD). It provides a declarative recommendation for KubeDB managed databases like [MongoDB](https://www.mongodb.com/) in a Kubernetes native way. The recommendation will only be created if `.spec.authSecret.rotateAfter` is set. KubeDB generates MongoDB Rotate Auth recommendation regarding two particular cases.
+
+1. AuthSecret lifespan is more than one month and, less than one month remaining till expiry
+2. AuthSecret lifespan is less than one month and, less than one third of lifespan remaining till expiry
+
+Let's go through a demo to see `RotateAuth` recommendations being generated. First, get the available MongoDB versions provided by KubeDB.
+
+```bash
+$ kubectl get mongodbversions
+NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE
+4.2.24 4.2.24 Official ghcr.io/appscode-images/mongo:4.2.24 3h43m
+4.4.26 4.4.26 Official ghcr.io/appscode-images/mongo:4.4.26 3h43m
+5.0.23 5.0.23 Official ghcr.io/appscode-images/mongo:5.0.23 3h43m
+5.0.26 5.0.26 Official ghcr.io/appscode-images/mongo:5.0.26 3h43m
+6.0.12 6.0.12 Official ghcr.io/appscode-images/mongo:6.0.12 3h43m
+7.0.16 7.0.16 Official ghcr.io/appscode-images/mongo:7.0.16 3h43m
+7.0.5 7.0.5 Official ghcr.io/appscode-images/mongo:7.0.5 3h43m
+7.0.8 7.0.8 Official ghcr.io/appscode-images/mongo:7.0.8 3h43m
+8.0.4 8.0.4 Official ghcr.io/appscode-images/mongo:8.0.4 3h43m
+percona-4.2.24 4.2.24 Percona percona/percona-server-mongodb:4.2.24 3h43m
+percona-4.4.26 4.4.26 Percona percona/percona-server-mongodb:4.4.26 3h43m
+percona-5.0.23 5.0.23 Percona percona/percona-server-mongodb:5.0.23 3h43m
+percona-6.0.12 6.0.12 Percona percona/percona-server-mongodb:6.0.12 3h43m
+percona-7.0.4 7.0.4 Percona percona/percona-server-mongodb:7.0.4 3h43m
+```
+
+Let's deploy an MongoDB cluster with version `7.0.8`.
+
+```yaml
+apiVersion: kubedb.com/v1
+kind: MongoDB
+metadata:
+ name: mongo
+ namespace: mg
+spec:
+ deletionPolicy: WipeOut
+ authSecret:
+ rotateAfter: 1h
+ podTemplate:
+ spec:
+ containers:
+ - name: mongodb
+ resources:
+ limits:
+ cpu: 700m
+ memory: 1Gi
+ requests:
+ cpu: 700m
+ memory: 1Gi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ runAsGroup: 0
+ runAsNonRoot: true
+ runAsUser: 999
+ seccompProfile:
+ type: RuntimeDefault
+ - name: replication-mode-detector
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ runAsGroup: 0
+ runAsNonRoot: true
+ runAsUser: 999
+ seccompProfile:
+ type: RuntimeDefault
+ initContainers:
+ - name: copy-config
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ runAsGroup: 0
+ runAsNonRoot: true
+ runAsUser: 999
+ seccompProfile:
+ type: RuntimeDefault
+ nodeSelector:
+ kubernetes.io/os: linux
+ securityContext:
+ fsGroup: 999
+ replicaSet:
+ name: rs0
+ replicas: 2
+ storage:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 4Gi
+ storageClassName: local-path
+ storageType: Durable
+ version: 7.0.8
+```
+
+Wait for a while till mongodb cluster gets into `Ready` state. Required time depends on image pulling and node's physical specifications.
+
+```bash
+$ kubectl get mg mongo -n mg -w
+NAME VERSION STATUS AGE
+mongo 7.0.8 Provisioning 98s
+mongo 7.0.8 Provisioning 5m43s
+mongo 7.0.8 Provisioning 8m7s
+.
+.
+.
+mongo 7.0.8 Ready 10m
+mongo 7.0.8 Ready 10m
+```
+
+Since, `.spec.authSecret.rotateAfter` is set as `1h`, it is expected that the recommendation engine will generate a rotate-auth recommendation at least after 40 minutes (two-third of lifespan) of the authsecret creation. Once generated you will get a similar recommendation as follows.
+
+```bash
+$ kubectl get recommendation -n mg | grep rotate-auth
+NAME STATUS OUTDATED AGE
+mongo-x-mongodb-x-rotate-auth-441xqs Pending false 7m11s
+```
+
+The `Recommendation` custom resource will be named as `-x--x--`. Initially, the KubeDB `Supervisor` controller will mark the `Status` of this object to `Pending`. Let's check the complete Recommendation custom resource manifest:
+
+```yaml
+$ kubectl get recommendation -n mg mongo-x-mongodb-x-rotate-auth-441xqs -oyaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: Recommendation
+metadata:
+ creationTimestamp: "2025-02-25T09:12:29Z"
+ generation: 1
+ labels:
+ app.kubernetes.io/instance: mongo
+ app.kubernetes.io/managed-by: kubedb.com
+ app.kubernetes.io/type: rotate-auth
+ name: mongo-x-mongodb-x-rotate-auth-441xqs
+ namespace: mg
+ resourceVersion: "80116"
+ uid: 12f24cf6-2f02-420f-863d-3523e32a08dd
+spec:
+ backoffLimit: 5
+ deadline: "2025-02-25T09:20:53Z"
+ description: Recommending AuthSecret rotation,mongo-auth AuthSecret needs to be
+ rotated before 2025-02-25 09:30:53 +0000 UTC
+ operation:
+ apiVersion: ops.kubedb.com/v1alpha1
+ kind: MongoDBOpsRequest
+ metadata:
+ name: rotate-auth
+ namespace: mg
+ spec:
+ databaseRef:
+ name: mongo
+ type: RotateAuth
+ status: {}
+ recommender:
+ name: kubedb-ops-manager
+ rules:
+ failed: has(self.status) && has(self.status.phase) && self.status.phase == 'Failed'
+ inProgress: has(self.status) && has(self.status.phase) && self.status.phase ==
+ 'Progressing'
+ success: has(self.status) && has(self.status.phase) && self.status.phase == 'Successful'
+ target:
+ apiGroup: kubedb.com
+ kind: MongoDB
+ name: mongo
+status:
+ approvalStatus: Pending
+ failedAttempt: 0
+ outdated: false
+ parallelism: Namespace
+ phase: Pending
+ reason: WaitingForApproval
+```
+
+In the generated Recommendation you will find a description, targeted db object, recommended operation or Ops-Request manifest, current status of the recommendation etc. Let's just focus on the recommendation description first.
+
+```shell
+$ kubectl get recommendation -n mg mongo-x-mongodb-x-rotate-auth-441xqs -o jsonpath='{.spec.operation}' | yq -y
+apiVersion: ops.kubedb.com/v1alpha1
+kind: MongoDBOpsRequest
+metadata:
+ name: rotate-auth
+ namespace: mg
+spec:
+ databaseRef:
+ name: mongo
+ type: RotateAuth
+status: {}
+```
+
+Let's check the status part of this recommendation.
+
+```bash
+$ kubectl get recommendation -n mg mongo-x-mongodb-x-rotate-auth-441xqs -o jsonpath='{.status}' | yq -y
+approvalStatus: Pending
+failedAttempt: 0
+outdated: false
+parallelism: Namespace
+phase: Pending
+reason: WaitingForApproval
+```
+
+Now, This recommendation can be approved and operation can be executed immediately by setting `ApprovalStatus` to `Approved` and Setting `approvedWindow` to `Immediate`. You can approve this easily through Appscode UI or edit it manually. Also, You can use kubectl CLI for this -
+
+```bash
+$ kubectl patch Recommendation mongo-x-mongodb-x-rotate-auth-441xqs \
+ -n mg \
+ --type merge \
+ --subresource='status' \
+ -p '{"status":{"approvalStatus":"Approved","approvedWindow":{"window":"Immediate"}}}'
+recommendation.supervisor.appscode.com/mongo-x-mongodb-x-rotate-auth-441xqs patched
+```
+
+Now, check the status part again. You will find a condition have appeared which says `OpsRequest is successfully created`.
+
+```bash
+$ kubectl get recommendation -n mg mongo-x-mongodb-x-rotate-auth-441xqs -o jsonpath='{.status}' | yq -y
+approvalStatus: Approved
+approvedWindow:
+ window: Immediate
+conditions:
+ - lastTransitionTime: '2025-02-25T09:23:29Z'
+ message: OpsRequest is successfully created
+ reason: SuccessfullyCreatedOperation
+ status: 'True'
+ type: SuccessfullyCreatedOperation
+createdOperationRef:
+ name: mongo-1740475409-rotate-auth-auto
+failedAttempt: 0
+outdated: false
+parallelism: Namespace
+phase: InProgress
+reason: StartedExecutingOperation
+```
+
+You will find an `MongoDBOpsRequest` custom resource have been created and, it is rotating the authsecret of `mongo` cluster with negligible downtime. Let's wait for it to reach `Successful` status.
+
+```bash
+$ kubectl get mongodbopsrequest -n mg mongo-1740475409-rotate-auth-auto -w
+NAME TYPE STATUS AGE
+mongo-1740475409-rotate-auth-auto RotateAuth Successful 112s
+```
+
+Let's recheck the recommendation for one last time. We should find that `.status.phase` has been marked as `Succeeded`.
+
+```bash
+$ kubectl get recommendation -n mg mongo-x-mongodb-x-rotate-auth-441xqs
+NAME STATUS OUTDATED AGE
+mongo-x-mongodb-x-rotate-auth-441xqs Succeeded false 78m
+```
+
+You may not want to do trigger recommended operations manually. Rather, trigger them autonomously in a preferred schedule when infrastructure is idle or traffic rate is at the lowest. For this purpose, You can create a `MaintenanceWindow` custom resource where you can set your desired schedule/period for triggering these recommended operations automatically. Here's a sample one:
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: MaintenanceWindow
+metadata:
+ name: mongo-maintenance
+ namespace: mg
+spec:
+ timezone: Asia/Dhaka
+ days:
+ Wednesday:
+ - start: 5:40AM
+ end: 7:00PM
+ dates:
+ - start: 2025-01-25T00:00:18Z
+ end: 2025-01-25T23:41:18Z
+```
+
+You can now create a `ApprovalPolicy` custom resource to refer this `MaintenanceWindow` for particular DB type. Following is a sample `ApprovalPolicy` for any `MongoDB` custom resource deployed in `mg` namespace. This `ApprovalPolicy` custom resource is referring to the `mongo-maintenance` MaintenanceWindow created in the same namespace. You can also create `ClusterMaintenanceWindow` instead which is effective for cluster-wide operations and refer it here. The following ApprovalPolicy will trigger recommended operations when referred maintenance window timeframe is reached.
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: ApprovalPolicy
+metadata:
+ name: mg-policy
+ namespace: mg
+maintenanceWindowRef:
+ name: mongo-maintenance
+targets:
+ - group: kubedb.com
+ kind: MongoDB
+ operations:
+ - group: ops.kubedb.com
+ kind: MongoDBOpsRequest
+```
+
+Lastly, If you want to reject a recommendation, you can just set `ApprovalStatus` to `Rejected` in the recommendation status section. Here's how you can do it using kubectl cli.
+
+```bash
+$ kubectl patch Recommendation mongo-x-mongodb-x-rotate-auth-441xqs \
+ -n mg \
+ --type merge \
+ --subresource='status' \
+ -p '{"status":{"approvalStatus":"Rejected"}}'
+recommendation.supervisor.appscode.com/mongo-x-mongodb-x-rotate-auth-441xqs patched
+```
+
+
+## Next Steps
+
+- Learn about [backup & restore](/docs/guides/mongodb/backup/stash/overview/index.md) MongoDB database using Stash.
+- Learn how to configure [MongoDB Cluster](/docs/guides/mongodb/clustering/replicaset.md).
+- Monitor your MongoDB database with KubeDB using [`out-of-the-box` Prometheus operator](/docs/guides/mongodb/monitoring/using-prometheus-operator.md).
+- Use [private Docker registry](/docs/guides/mongodb/private-registry/using-private-registry.md) to deploy MongoDB with KubeDB.
+- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md).
\ No newline at end of file
diff --git a/docs/guides/mongodb/recommendation/rotate-tls-recommendation.md b/docs/guides/mongodb/recommendation/rotate-tls-recommendation.md
new file mode 100644
index 0000000000..a71efd32fa
--- /dev/null
+++ b/docs/guides/mongodb/recommendation/rotate-tls-recommendation.md
@@ -0,0 +1,343 @@
+---
+title: MongoDB Rotate TLS Recommendation
+menu:
+ docs_{{ .version }}:
+ identifier: mg-rotate-tls-recommendation
+ name: Rotate TLS Recommendation
+ parent: mg-recommendation-mongodb
+ weight: 30
+menu_name: docs_{{ .version }}
+section_menu_id: guides
+---
+
+> New to KubeDB? Please start [here](/docs/README.md).
+
+# MongoDB Rotate TLS Recommendation
+
+TLS certificate rotation in databases is essential for maintaining security, ensuring compliance, and preventing service disruptions. Regular rotation mitigates risks like certificate expiry and key compromise, adapts to evolving cryptographic standards, and maintains trust relationships with Certificate Authorities. It also enhances operational resilience by testing renewal processes and ensures smooth auditing and monitoring. To minimize risks and streamline the process, KubeDB provides ReconfigureTLS OpsRequest support. KubeDB Ops-manager generates Recommendation to rotate TLS certificates via this OpsRequest when their expiry is near.
+
+`Recommendation` is a Kubernetes `Custom Resource Definitions` (CRD). It provides a declarative recommendation for KubeDB managed databases like [MongoDB](https://www.mongodb.com/) in a Kubernetes native way. KubeDB generates MongoDB/Opensearch Rotate TLS recommendation regarding if:
+
+- At least one of its certificate’s lifespan is more than one month and less than one month remaining till expiry
+
+- At least one of its certificates has one-third of its lifespan remaining till expiry.
+
+Let's go through a demo to see `RotateTLS` recommendations being generated. First, get the available MongoDB versions provided by KubeDB.
+
+```bash
+$ kubectl get mongodbversions
+NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE
+4.2.24 4.2.24 Official ghcr.io/appscode-images/mongo:4.2.24 3h43m
+4.4.26 4.4.26 Official ghcr.io/appscode-images/mongo:4.4.26 3h43m
+5.0.23 5.0.23 Official ghcr.io/appscode-images/mongo:5.0.23 3h43m
+5.0.26 5.0.26 Official ghcr.io/appscode-images/mongo:5.0.26 3h43m
+6.0.12 6.0.12 Official ghcr.io/appscode-images/mongo:6.0.12 3h43m
+7.0.16 7.0.16 Official ghcr.io/appscode-images/mongo:7.0.16 3h43m
+7.0.5 7.0.5 Official ghcr.io/appscode-images/mongo:7.0.5 3h43m
+7.0.8 7.0.8 Official ghcr.io/appscode-images/mongo:7.0.8 3h43m
+8.0.4 8.0.4 Official ghcr.io/appscode-images/mongo:8.0.4 3h43m
+percona-4.2.24 4.2.24 Percona percona/percona-server-mongodb:4.2.24 3h43m
+percona-4.4.26 4.4.26 Percona percona/percona-server-mongodb:4.4.26 3h43m
+percona-5.0.23 5.0.23 Percona percona/percona-server-mongodb:5.0.23 3h43m
+percona-6.0.12 6.0.12 Percona percona/percona-server-mongodb:6.0.12 3h43m
+percona-7.0.4 7.0.4 Percona percona/percona-server-mongodb:7.0.4 3h43m
+```
+
+Let's deploy an MongoDB cluster with version `7.0.8`.
+
+```yaml
+apiVersion: kubedb.com/v1
+kind: MongoDB
+metadata:
+ name: mongo
+ namespace: mg
+spec:
+ deletionPolicy: WipeOut
+ tls:
+ issuerRef:
+ apiGroup: "cert-manager.io"
+ kind: Issuer
+ name: ca-issuer
+ certificates:
+ - alias: client
+ duration: 1h20m
+ podTemplate:
+ spec:
+ containers:
+ - name: mongodb
+ resources:
+ limits:
+ cpu: 700m
+ memory: 1Gi
+ requests:
+ cpu: 700m
+ memory: 1Gi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ runAsGroup: 0
+ runAsNonRoot: true
+ runAsUser: 999
+ seccompProfile:
+ type: RuntimeDefault
+ - name: replication-mode-detector
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ runAsGroup: 0
+ runAsNonRoot: true
+ runAsUser: 999
+ seccompProfile:
+ type: RuntimeDefault
+ initContainers:
+ - name: copy-config
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ runAsGroup: 0
+ runAsNonRoot: true
+ runAsUser: 999
+ seccompProfile:
+ type: RuntimeDefault
+ nodeSelector:
+ kubernetes.io/os: linux
+ securityContext:
+ fsGroup: 999
+ replicaSet:
+ name: rs0
+ replicas: 2
+ storage:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 4Gi
+ storageClassName: local-path
+ storageType: Durable
+ version: 7.0.8
+```
+
+Wait for a while till mongodb cluster gets into `Ready` state. Required time depends on image pulling and node's physical specifications.
+
+```bash
+$ kubectl get es mongo -n es -w
+NAME VERSION STATUS AGE
+mongo 7.0.8 Provisioning 98s
+mongo 7.0.8 Provisioning 5m43s
+mongo 7.0.8 Provisioning 8m7s
+.
+.
+.
+mongo 7.0.8 Ready 10m
+mongo 7.0.8 Ready 10m
+```
+
+Since,duration for client certificate is set as `1h20min`, it is expected that the recommendation engine will generate a rotate-auth recommendation at least after 54 minutes (two-third of lifespan) of the client certificate creation. Once generated you will get a similar recommendation as follows.
+
+```bash
+$ kubectl get recommendation -n es | grep rotate-tls
+NAME STATUS OUTDATED AGE
+mongo-x-mongodb-x-rotate-tls-6ujvez Pending false 74s
+```
+
+The `Recommendation` custom resource will be named as `-x--x--`. Initially, the KubeDB `Supervisor` controller will mark the `Status` of this object to `Pending`. Let's check the complete Recommendation custom resource manifest:
+
+```yaml
+$ kubectl get recommendation -n es mongo-x-mongodb-x-rotate-tls-6ujvez -oyaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: Recommendation
+metadata:
+ creationTimestamp: "2025-02-27T11:50:04Z"
+ generation: 1
+ labels:
+ app.kubernetes.io/instance: mongo
+ app.kubernetes.io/managed-by: kubedb.com
+ app.kubernetes.io/type: rotate-tls
+ name: mongo-x-mongodb-x-rotate-tls-6ujvez
+ namespace: es
+ resourceVersion: "309401"
+ uid: d208df6b-5fbf-4122-b7b7-18e73a4e1d6c
+spec:
+ backoffLimit: 5
+ deadline: "2025-02-27T11:59:43Z"
+ description: Recommending TLS certificate rotation,mongo-client-cert Certificate
+ is going to be expire on 2025-02-27 12:04:43 +0000 UTC
+ operation:
+ apiVersion: ops.kubedb.com/v1alpha1
+ kind: MongoDBOpsRequest
+ metadata:
+ name: rotate-tls
+ namespace: es
+ spec:
+ databaseRef:
+ name: mongo
+ tls:
+ rotateCertificates: true
+ type: ReconfigureTLS
+ status: {}
+ recommender:
+ name: kubedb-ops-manager
+ rules:
+ failed: has(self.status) && has(self.status.phase) && self.status.phase == 'Failed'
+ inProgress: has(self.status) && has(self.status.phase) && self.status.phase ==
+ 'Progressing'
+ success: has(self.status) && has(self.status.phase) && self.status.phase == 'Successful'
+ target:
+ apiGroup: kubedb.com
+ kind: MongoDB
+ name: mongo
+status:
+ approvalStatus: Pending
+ failedAttempt: 0
+ outdated: false
+ parallelism: Namespace
+ phase: Pending
+ reason: WaitingForApproval
+```
+
+In the generated Recommendation you will find a description, targeted db object, recommended operation or Ops-Request manifest, current status of the recommendation etc. Let's just focus on the recommendation description first.
+
+```shell
+$ kubectl get recommendation -n es mongo-x-mongodb-x-rotate-tls-6ujvez -o jsonpath='{.spec.operation}' | yq -y
+apiVersion: ops.kubedb.com/v1alpha1
+kind: MongoDBOpsRequest
+metadata:
+ name: rotate-tls
+ namespace: es
+spec:
+ databaseRef:
+ name: mongo
+ tls:
+ rotateCertificates: true
+ type: ReconfigureTLS
+status: {}
+```
+
+Let's check the status part of this recommendation.
+
+```bash
+$ kubectl get recommendation -n es mongo-x-mongodb-x-rotate-tls-6ujvez -o jsonpath='{.status}' | yq -y
+approvalStatus: Pending
+failedAttempt: 0
+outdated: false
+parallelism: Namespace
+phase: Pending
+reason: WaitingForApproval
+```
+
+Now, This recommendation can be approved and operation can be executed immediately by setting `ApprovalStatus` to `Approved` and Setting `approvedWindow` to `Immediate`. You can approve this easily through Appscode UI or edit it manually. Also, You can use kubectl CLI for this -
+
+```bash
+$ kubectl patch Recommendation mongo-x-mongodb-x-rotate-tls-6ujvez \
+ -n es \
+ --type merge \
+ --subresource='status' \
+ -p '{"status":{"approvalStatus":"Approved","approvedWindow":{"window":"Immediate"}}}'
+recommendation.supervisor.appscode.com/mongo-x-mongodb-x-rotate-tls-6ujvez patched
+```
+
+Now, check the status part again. You will find a condition have appeared which says `OpsRequest is successfully created`.
+
+```bash
+$ kubectl get recommendation -n es mongo-x-mongodb-x-rotate-tls-6ujvez -o jsonpath='{.status}' | yq -y
+approvalStatus: Approved
+approvedWindow:
+ window: Immediate
+conditions:
+ - lastTransitionTime: '2025-02-27T11:54:50Z'
+ message: OpsRequest is successfully created
+ reason: SuccessfullyCreatedOperation
+ status: 'True'
+ type: SuccessfullyCreatedOperation
+createdOperationRef:
+ name: mongo-1740657290-rotate-tls-auto
+failedAttempt: 0
+outdated: false
+parallelism: Namespace
+phase: InProgress
+reason: StartedExecutingOperation
+```
+
+You will find an `MongoDBOpsRequest` custom resource have been created and, it is rotating the authsecret of `mongo` cluster with negligible downtime. Let's wait for it to reach `Successful` status.
+
+```bash
+$ kubectl get mongodbopsrequest -n es mongo-1740657290-rotate-tls-auto -w
+NAME TYPE STATUS AGE
+mongo-1740657290-rotate-tls-auto ReconfigureTLS Progressing 60s
+mongo-1740657290-rotate-tls-auto ReconfigureTLS Progressing 114s
+.
+.
+mongo-1740657290-rotate-tls-auto ReconfigureTLS Successful 12m
+
+```
+
+Let's recheck the recommendation for one last time. We should find that `.status.phase` has been marked as `Succeeded`.
+
+```bash
+$ kubectl get recommendation -n es mongo-x-mongodb-x-rotate-tls-6ujvez
+NAME STATUS OUTDATED AGE
+mongo-x-mongodb-x-rotate-tls-6ujvez Succeeded false 78m
+```
+
+You may not want to do trigger recommended operations manually. Rather, trigger them autonomously in a preferred schedule when infrastructure is idle or traffic rate is at the lowest. For this purpose, You can create a `MaintenanceWindow` custom resource where you can set your desired schedule/period for triggering these recommended operations automatically. Here's a sample one:
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: MaintenanceWindow
+metadata:
+ name: mongo-maintenance
+ namespace: es
+spec:
+ timezone: Asia/Dhaka
+ days:
+ Wednesday:
+ - start: 5:40AM
+ end: 7:00PM
+ dates:
+ - start: 2025-01-25T00:00:18Z
+ end: 2025-01-25T23:41:18Z
+```
+
+You can now create a `ApprovalPolicy` custom resource to refer this `MaintenanceWindow` for particular DB type. Following is a sample `ApprovalPolicy` for any `MongoDB` custom resource deployed in `es` namespace. This `ApprovalPolicy` custom resource is referring to the `mongo-maintenance` MaintenanceWindow created in the same namespace. You can also create `ClusterMaintenanceWindow` instead which is effective for cluster-wide operations and refer it here. The following ApprovalPolicy will trigger recommended operations when referred maintenance window timeframe is reached.
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: ApprovalPolicy
+metadata:
+ name: mg-policy
+ namespace: es
+maintenanceWindowRef:
+ name: mongo-maintenance
+targets:
+ - group: kubedb.com
+ kind: MongoDB
+ operations:
+ - group: ops.kubedb.com
+ kind: MongoDBOpsRequest
+```
+
+Lastly, If you want to reject a recommendation, you can just set `ApprovalStatus` to `Rejected` in the recommendation status section. Here's how you can do it using kubectl cli.
+
+```bash
+$ kubectl patch Recommendation mongo-x-mongodb-x-rotate-tls-6ujvez \
+ -n es \
+ --type merge \
+ --subresource='status' \
+ -p '{"status":{"approvalStatus":"Rejected"}}'
+recommendation.supervisor.appscode.com/mongo-x-mongodb-x-rotate-tls-6ujvez patched
+```
+
+
+## Next Steps
+
+- Learn about [backup & restore](/docs/guides/mongodb/backup/stash/overview/index.md) MongoDB database using Stash.
+- Learn how to configure [MongoDB Cluster](/docs/guides/mongodb/clustering/replicaset.md).
+- Monitor your MongoDB database with KubeDB using [`out-of-the-box` Prometheus operator](/docs/guides/mongodb/monitoring/using-prometheus-operator.md).
+- Use [private Docker registry](/docs/guides/mongodb/private-registry/using-private-registry.md) to deploy MongoDB with KubeDB.
+- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md).
diff --git a/docs/guides/mongodb/recommendation/version-update-recommendation.md b/docs/guides/mongodb/recommendation/version-update-recommendation.md
new file mode 100644
index 0000000000..bedf773244
--- /dev/null
+++ b/docs/guides/mongodb/recommendation/version-update-recommendation.md
@@ -0,0 +1,356 @@
+---
+title: MongoDB Version Update Recommendation
+menu:
+ docs_{{ .version }}:
+ identifier: mg-version-update-recommendation
+ name: Version Update Recommendation
+ parent: mg-recommendation-mongodb
+ weight: 20
+menu_name: docs_{{ .version }}
+section_menu_id: guides
+---
+
+> New to KubeDB? Please start [here](/docs/README.md).
+
+# MongoDB Version Update Recommendation
+
+Database versions often need to be updated due to several reasons. Older database versions may have vulnerabilities that hackers can exploit. New versions often include optimizations for query execution, indexing, and storage mechanisms. Modern databases frequently introduce new features, such as better data types, improved indexing methods, or advanced analytics capabilities. Database vendors release patches and updates to address these issues and introduce new features.
+
+`Recommendation` is a Kubernetes `Custom Resource Definitions` (CRD). It provides a declarative recommendation for KubeDB managed databases like [MongoDB](https://www.mongodb.com/) in a Kubernetes native way. KubeDB generates MongoDB Version Update recommendation regarding three particular cases.
+
+1. There's been an update in the current version image
+2. There's a new major/minor version available
+3. There's a version available with patch fix
+
+Let's go through a demo to see version update recommendations being generated. First, get the available MongoDB versions provided by KubeDB.
+
+```bash
+$ kubectl get mongodbversions
+NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE
+4.2.24 4.2.24 Official ghcr.io/appscode-images/mongo:4.2.24 3h43m
+4.4.26 4.4.26 Official ghcr.io/appscode-images/mongo:4.4.26 3h43m
+5.0.23 5.0.23 Official ghcr.io/appscode-images/mongo:5.0.23 3h43m
+5.0.26 5.0.26 Official ghcr.io/appscode-images/mongo:5.0.26 3h43m
+6.0.12 6.0.12 Official ghcr.io/appscode-images/mongo:6.0.12 3h43m
+7.0.16 7.0.16 Official ghcr.io/appscode-images/mongo:7.0.16 3h43m
+7.0.5 7.0.5 Official ghcr.io/appscode-images/mongo:7.0.5 3h43m
+7.0.8 7.0.8 Official ghcr.io/appscode-images/mongo:7.0.8 3h43m
+8.0.4 8.0.4 Official ghcr.io/appscode-images/mongo:8.0.4 3h43m
+percona-4.2.24 4.2.24 Percona percona/percona-server-mongodb:4.2.24 3h43m
+percona-4.4.26 4.4.26 Percona percona/percona-server-mongodb:4.4.26 3h43m
+percona-5.0.23 5.0.23 Percona percona/percona-server-mongodb:5.0.23 3h43m
+percona-6.0.12 6.0.12 Percona percona/percona-server-mongodb:6.0.12 3h43m
+percona-7.0.4 7.0.4 Percona percona/percona-server-mongodb:7.0.4 3h43m
+```
+
+Let's deploy an MongoDB cluster with version `7.0.8`.
+
+```yaml
+apiVersion: kubedb.com/v1
+kind: MongoDB
+metadata:
+ name: mongo
+ namespace: mg
+spec:
+ deletionPolicy: WipeOut
+ podTemplate:
+ spec:
+ containers:
+ - name: mongodb
+ resources:
+ limits:
+ cpu: 700m
+ memory: 1Gi
+ requests:
+ cpu: 700m
+ memory: 1Gi
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ runAsGroup: 0
+ runAsNonRoot: true
+ runAsUser: 999
+ seccompProfile:
+ type: RuntimeDefault
+ - name: replication-mode-detector
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ runAsGroup: 0
+ runAsNonRoot: true
+ runAsUser: 999
+ seccompProfile:
+ type: RuntimeDefault
+ initContainers:
+ - name: copy-config
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ runAsGroup: 0
+ runAsNonRoot: true
+ runAsUser: 999
+ seccompProfile:
+ type: RuntimeDefault
+ nodeSelector:
+ kubernetes.io/os: linux
+ securityContext:
+ fsGroup: 999
+ replicaSet:
+ name: rs0
+ replicas: 2
+ storage:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 4Gi
+ storageClassName: local-path
+ storageType: Durable
+ version: 7.0.8
+```
+
+Wait for a while till mongodb cluster gets into `Ready` state. Required time depends on image pulling and node's physical specifications.
+
+```bash
+$ kubectl get mg mongo -n mg -w
+NAME VERSION STATUS AGE
+mongo 7.0.8 Provisioning 98s
+mongo 7.0.8 Provisioning 5m43s
+mongo 7.0.8 Provisioning 8m7s
+.
+.
+.
+mongo 7.0.8 Ready 10m
+mongo 7.0.8 Ready 10m
+```
+
+Once mongo instance is `Ready`, a `Recommendation` instance will be automatically generated by KubeDB `Ops-Manager` controller. Might take a few minutes to trigger an event for the database creation in the controller.
+
+```bash
+$ kubectl get recommendation -n mg
+NAME STATUS OUTDATED AGE
+mongo-x-mongodb-x-update-version-uax2ot Pending false 10m
+```
+
+The `Recommendation` custom resource will be named as `-x--x--`. Initially, the KubeDB `Supervisor` controller will mark the `Status` of this object to `Pending`. Let's check the complete Recommendation custom resource manifest:
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: Recommendation
+metadata:
+ annotations:
+ kubedb.com/recommendation-for-version: 7.0.8
+ creationTimestamp: "2025-02-25T08:32:58Z"
+ generation: 1
+ labels:
+ app.kubernetes.io/instance: mongo
+ app.kubernetes.io/managed-by: kubedb.com
+ app.kubernetes.io/type: version-update
+ kubedb.com/version-update-recommendation-type: major-minor
+ name: mongo-x-mongodb-x-update-version-uax2ot
+ namespace: mg
+ resourceVersion: "76768"
+ uid: 17722dda-992a-4755-a480-a6ef1f7149a7
+spec:
+ backoffLimit: 5
+ description: Latest Major/Minor version is available. Recommending version Update
+ from 7.0.8 to 8.0.4.
+ operation:
+ apiVersion: ops.kubedb.com/v1alpha1
+ kind: MongoDBOpsRequest
+ metadata:
+ name: update-version
+ namespace: mg
+ spec:
+ databaseRef:
+ name: mongo
+ type: UpdateVersion
+ updateVersion:
+ targetVersion: 8.0.4
+ status: {}
+ recommender:
+ name: kubedb-ops-manager
+ requireExplicitApproval: true
+ rules:
+ failed: has(self.status) && has(self.status.phase) && self.status.phase == 'Failed'
+ inProgress: has(self.status) && has(self.status.phase) && self.status.phase ==
+ 'Progressing'
+ success: has(self.status) && has(self.status.phase) && self.status.phase == 'Successful'
+ target:
+ apiGroup: kubedb.com
+ kind: MongoDB
+ name: mongo
+ vulnerabilityReport:
+ message: no matches for kind "ImageScanReport" in version "scanner.appscode.com/v1alpha1"
+ status: Failure
+status:
+ approvalStatus: Pending
+ failedAttempt: 0
+ outdated: false
+ parallelism: Namespace
+ phase: Pending
+ reason: WaitingForApproval
+```
+
+In the generated Recommendation you will find a description, targeted db object, recommended operation or Ops-Request manifest, current status of the recommendation etc. Let's just focus on the recommendation description first.
+
+```shell
+$ kubectl get recommendation -n mg mongo-x-mongodb-x-update-version-uax2ot -o jsonpath='{.spec.description}'
+Latest Major/Minor version is available. Recommending version Update from 7.0.8 to 8.0.4.
+```
+
+The recommendation says current version `7.0.8` should be upgraded to latest upgradable version `8.0.4`. You can also find the recommended operation which is a `MongoDBOpsRequest` of `UpdateVersion` type in this case.
+
+```shell
+$ kubectl get recommendation -n mg mongo-x-mongodb-x-update-version-uax2ot -o jsonpath='{.spec.operation}' | yq -y
+apiVersion: ops.kubedb.com/v1alpha1
+kind: MongoDBOpsRequest
+metadata:
+ name: update-version
+ namespace: mg
+spec:
+ databaseRef:
+ name: mongo
+ type: UpdateVersion
+ updateVersion:
+ targetVersion: 8.0.4
+status: {}
+```
+
+Note: For the above command to work you need to have YQ v3 installed.
+
+Let's check the status part of this recommendation.
+
+```bash
+$ kubectl get recommendation -n mg mongo-x-mongodb-x-update-version-uax2ot -o jsonpath='{.status}' | yq -y
+approvalStatus: Pending
+failedAttempt: 0
+outdated: false
+parallelism: Namespace
+phase: Pending
+reason: WaitingForApproval
+```
+
+Now, This recommendation can be approved and operation can be executed immediately by setting `ApprovalStatus` to `Approved` and Setting `approvedWindow` to `Immediate`. You can approve this easily through Appscode UI or edit it manually. Also, You can use kubectl CLI for this -
+
+```bash
+$ kubectl patch Recommendation mongo-x-mongodb-x-update-version-uax2ot \
+ -n mg \
+ --type merge \
+ --subresource='status' \
+ -p '{"status":{"approvalStatus":"Approved","approvedWindow":{"window":"Immediate"}}}'
+recommendation.supervisor.appscode.com/mongo-x-mongodb-x-update-version-uax2ot patched
+```
+
+Now, check the status part again. You will find a condition have appeared which says `OpsRequest is successfully created`.
+
+```bash
+$ kubectl get recommendation -n mg mongo-x-mongodb-x-update-version-uax2ot -o jsonpath='{.status}' | yq -y
+approvalStatus: Approved
+approvedWindow:
+ window: Immediate
+conditions:
+ - lastTransitionTime: '2025-02-25T09:07:19Z'
+ message: OpsRequest is successfully created
+ reason: SuccessfullyCreatedOperation
+ status: 'True'
+ type: SuccessfullyCreatedOperation
+createdOperationRef:
+ name: mongo-1740474439-update-version-auto
+failedAttempt: 0
+outdated: false
+parallelism: Namespace
+phase: InProgress
+reason: StartedExecutingOperation
+
+```
+
+You will find an `MongoDBOpsRequest` custom resource have been created and, it is updating the `mongo` cluster version to `8.0.4` with negligible downtime. Let's wait for it to reach `Successful` status.
+
+```bash
+$ kubectl get mongodbopsrequest -n mg mongo-1740474439-update-version-auto -w
+NAME TYPE STATUS AGE
+mongo-1740474439-update-version-auto UpdateVersion Progressing 70s
+mongo-1740474439-update-version-auto UpdateVersion Progressing 99s
+.
+.
+mongo-1740474439-update-version-auto UpdateVersion Successful 2m15s
+```
+
+Let's recheck the recommendation for one last time. We should find that `.status.phase` has been marked as `Succeeded`.
+
+```bash
+$ kubectl get recommendation -n mg mongo-x-mongodb-x-update-version-uax2ot
+NAME STATUS OUTDATED AGE
+mongo-x-mongodb-x-update-version-uax2ot Succeeded false 78m
+```
+
+Finally, You can check `mongo` cluster version now, which should be upgraded to version `8.0.4`.
+
+```bash
+$ kubectl get mg mongo -n mg
+NAME VERSION STATUS AGE
+mongo 8.0.4 Ready 40m
+```
+
+You may not want to do trigger recommended operations manually. Rather, trigger them autonomously in a preferred schedule when infrastructure is idle or traffic rate is at the lowest. For this purpose, You can create a `MaintenanceWindow` custom resource where you can set your desired schedule/period for triggering these recommended operations automatically. Here's a sample one:
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: MaintenanceWindow
+metadata:
+ name: mongo-maintenance
+ namespace: mg
+spec:
+ timezone: Asia/Dhaka
+ days:
+ Wednesday:
+ - start: 5:40AM
+ end: 7:00PM
+ dates:
+ - start: 2025-01-25T00:00:18Z
+ end: 2025-01-25T23:41:18Z
+```
+
+You can now create a `ApprovalPolicy` custom resource to refer this `MaintenanceWindow` for particular DB type. Following is a sample `ApprovalPolicy` for any `MongoDB` custom resource deployed in `mg` namespace. This `ApprovalPolicy` custom resource is referring to the `mongo-maintenance` MaintenanceWindow created in the same namespace. You can also create `ClusterMaintenanceWindow` instead which is effective for cluster-wide operations and refer it here. The following ApprovalPolicy will trigger recommended operations when referred maintenance window timeframe is reached.
+
+```yaml
+apiVersion: supervisor.appscode.com/v1alpha1
+kind: ApprovalPolicy
+metadata:
+ name: mg-policy
+ namespace: mg
+maintenanceWindowRef:
+ name: mongo-maintenance
+targets:
+ - group: kubedb.com
+ kind: MongoDB
+ operations:
+ - group: ops.kubedb.com
+ kind: MongoDBOpsRequest
+```
+
+Lastly, If you want to reject a recommendation, you can just set `ApprovalStatus` to `Rejected` in the recommendation status section. Here's how you can do it using kubectl cli.
+
+```bash
+$ kubectl patch Recommendation mongo-x-mongodb-x-update-version-uax2ot \
+ -n mg \
+ --type merge \
+ --subresource='status' \
+ -p '{"status":{"approvalStatus":"Rejected"}}'
+recommendation.supervisor.appscode.com/mongo-x-mongodb-x-update-version-uax2ot patched
+```
+
+## Next Steps
+
+- Learn about [backup & restore](/docs/guides/mongodb/backup/stash/overview/index.md) MongoDB database using Stash.
+- Learn how to configure [MongoDB Cluster](/docs/guides/mongodb/clustering/replicaset.md).
+- Monitor your MongoDB database with KubeDB using [`out-of-the-box` Prometheus operator](/docs/guides/mongodb/monitoring/using-prometheus-operator.md).
+- Use [private Docker registry](/docs/guides/mongodb/private-registry/using-private-registry.md) to deploy MongoDB with KubeDB.
+- Want to hack on KubeDB? Check our [contribution guidelines](/docs/CONTRIBUTING.md).