diff --git a/.gitignore b/.gitignore index 4da6fc20..3cb6b65e 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ styles/ # Allow !styles/config/vocabularies/Percona/** + +# Generated plugin cache +.cache/plugin/git-committers/ diff --git a/docs/details/oci-storage.md b/docs/details/oci-storage.md new file mode 100644 index 00000000..651f7ca7 --- /dev/null +++ b/docs/details/oci-storage.md @@ -0,0 +1,369 @@ +# Oracle Cloud Infrastructure Object Storage + +Percona Backup for MongoDB (PBM) supports [OCI Object Storage](https://docs.oracle.com/en-us/iaas/Content/Object/Concepts/objectstorageoverview.htm) +as a remote backup destination through a dedicated OCI native +driver. PBM connects to OCI Object Storage using one of the following authentication types: + +| **Authentication type** | **Use when** | +| --- | --- | +| `userPrincipal` | PBM runs anywhere; authenticates with OCI API signing keys | +| `instancePrincipal` | PBM runs on an OCI Compute instance | +| `okeWorkloadIdentity` | PBM runs inside an OKE enhanced cluster (see [Workload Identity authentication](oci-wif.md)) | + + +## Prerequisites + +Before configuring PBM, ensure that you have: + +- An active OCI tenancy with at least one subscribed region +- The OCI CLI installed and configured (`oci setup config`). + See the [OCI CLI documentation](https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliinstall.htm) + for installation instructions +- An OCI user with permission to create compartments, buckets, + dynamic groups, and IAM policies in your tenancy +- An OCI API signing key pair: private key on the host running + PBM, public key uploaded to the OCI user + + +Initialize the OCI CLI configuration if you have not done so already: + +```sh +oci setup config +``` + +Use your tenancy home region as the default CLI region. If the setup generated a new API key, upload the public key +to your OCI user: + +```sh +cat ~/.oci/oci_api_key_public.pem +``` + +In the OCI Console, go to **User settings → Tokens and keys → +API keys → Add API key**, paste the public key, and confirm +the fingerprint matches `~/.oci/config`. + +If needed, update local file permissions: + +```bash +oci setup repair-file-permissions --file ~/.oci/config +oci setup repair-file-permissions --file ~/.oci/oci_api_key.pem +``` + +## Verify region access + +Check the regions available to your tenancy: + +```bash +oci iam region-subscription list \ + --region \ + --output table +``` + +!!! note + The region specified in the configuration must be enabled and subscribed to in your OCI tenancy. + +## Set up OCI resources + +### Export variables + +Set the following variables before running any commands in this +section. All subsequent commands reference them. + +```sh +export HOME_REGION= # e.g. us-ashburn-1 +export BUCKET_REGION= # e.g. eu-frankfurt-1 +export COMPARTMENT_NAME=pbm-backup +export BUCKET_NAME= +``` +Retrieve and export the values PBM requires: + +```sh +export TENANCY_OCID=$( + oci iam tenancy get \ + --tenancy-id "$(awk -F= '/^tenancy=/{print $2}' ~/.oci/config)" \ + --region "$HOME_REGION" \ + --query 'data.id' \ + --raw-output +) + +export USER_OCID=$(awk -F= '/^user=/{print $2}' ~/.oci/config) +export FINGERPRINT=$(awk -F= '/^fingerprint=/{print $2}' ~/.oci/config) +export KEY_FILE=$(awk -F= '/^key_file=/{print $2}' ~/.oci/config) +export KEY_FILE="${KEY_FILE/#\~/$HOME}" +export NAMESPACE=$( + oci os ns get \ + --region "$BUCKET_REGION" \ + --query 'data' \ + --raw-output +) + +echo "TENANCY_OCID: $TENANCY_OCID" +echo "USER_OCID: $USER_OCID" +echo "FINGERPRINT: $FINGERPRINT" +echo "KEY_FILE: $KEY_FILE" +echo "NAMESPACE: $NAMESPACE" +``` +Verify all five values are populated before continuing. An empty value means the OCI CLI is not authenticated or the variable was not set correctly. + +## Create a compartment + +Create a compartment for PBM backup resources: + +```sh +oci iam compartment create \ + --region "$HOME_REGION" \ + --compartment-id "$TENANCY_OCID" \ + --name "$COMPARTMENT_NAME" \ + --description "PBM OCI Object Storage backup" +``` +Wait until the compartment is active, then export its OCID: + +```sh +export COMPARTMENT_OCID=$( + oci iam compartment list \ + --region "$HOME_REGION" \ + --compartment-id "$TENANCY_OCID" \ + --compartment-id-in-subtree true \ + --all \ + --query "data[?name=='$COMPARTMENT_NAME' && \"lifecycle-state\"=='ACTIVE'].id | [0]" \ + --raw-output +) + +echo "COMPARTMENT_OCID: $COMPARTMENT_OCID" +``` +### Create an Object Storage bucket + +Create the bucket: + +```sh +oci os bucket create \ + --region "$BUCKET_REGION" \ + --namespace-name "$NAMESPACE" \ + --compartment-id "$COMPARTMENT_OCID" \ + --name "$BUCKET_NAME" +``` + +Verify the bucket was created: + +```sh +oci os bucket get \ + --region "$BUCKET_REGION" \ + --namespace-name "$NAMESPACE" \ + --bucket-name "$BUCKET_NAME" \ + --query 'data.{name:name,namespace:namespace}' \ + --output table +``` + +### Create IAM policies + +PBM must be able to create, read, overwrite, and delete backup objects. + +Two policies are required: + +**User access policy** — grants your OCI user group permission +to manage objects in the PBM compartment. Replace +`` with the name of the group containing +your PBM user: + +```sh +oci iam policy create \ + --region "$HOME_REGION" \ + --compartment-id "$TENANCY_OCID" \ + --name pbm-user-access \ + --description "Allow PBM user group to manage backup objects" \ + --statements "[\"Allow group to manage object-family in compartment $COMPARTMENT_NAME\"]" +``` + +**Native copy policy** — grants the OCI Object Storage service +permission to copy objects internally. PBM requires this for +server-side copy operations: + +```sh +oci iam policy create \ + --region "$HOME_REGION" \ + --compartment-id "$TENANCY_OCID" \ + --name "pbm-native-copy-$BUCKET_REGION" \ + --description "Allow Object Storage service to copy PBM objects" \ + --statements "[\"Allow service objectstorage-$BUCKET_REGION to manage object-family \ + in compartment $COMPARTMENT_NAME where any { \ + request.permission='OBJECT_READ', \ + request.permission='OBJECT_INSPECT', \ + request.permission='OBJECT_CREATE', \ + request.permission='OBJECT_OVERWRITE', \ + request.permission='OBJECT_DELETE'}\"]" +``` + +!!! note + IAM policy changes can take up to 2 minutes to propagate. If PBM reports an authorization error immediately after creating the policies, wait 2 minutes and retry. + +## Configure PBM + +### userPrincipal + +Use this when PBM runs outside OCI, or when you want to +authenticate with OCI API signing keys. + +Generate the correctly indented private key before creating +the config file: + +```sh +sed 's/^/ /' "$KEY_FILE" +``` +Create the configuration file: + +```yaml +storage: + type: oci + oci: + region: + namespace: + bucket: + prefix: pbm + credentials: + type: userPrincipal + userPrincipal: + tenancy: + user: + fingerprint: + privateKey: | + -----BEGIN PRIVATE KEY----- + ... + -----END PRIVATE KEY----- +``` +!!! warning + The `user` value must be a user OCID starting with + `ocid1.user.oc1`. A bucket or compartment OCID causes + a 401 authentication failure. + +!!! tip + Indent the private key correctly before adding it to the configuration: + + ```sh + sed 's/^/ /' "$KEY_FILE" + ``` + +### instancePrincipal + +Use this when PBM runs on an OCI Compute instance. No API +keys are required in the configuration file. + +1. Create a dynamic group that includes the compute instance: + + ```sh + oci iam dynamic-group create \ + --region "$HOME_REGION" \ + --compartment-id "$TENANCY_OCID" \ + --name pbm-instance-group \ + --description "PBM Compute instance principal" \ + --matching-rule "ANY {instance.id = ''}" + ``` + +2. Create a policy granting the dynamic group access to the bucket: + + ```sh + oci iam policy create \ + --region "$HOME_REGION" \ + --compartment-id "$TENANCY_OCID" \ + --name pbm-instance-policy \ + --description "Allow PBM instance to access backup bucket" \ + --statements "[\"Allow dynamic-group pbm-instance-group to manage objects \ + in compartment pbm-backup where target.bucket.name = ''\"]" + ``` + +3. Configure PBM: + + ```yaml + storage: + type: oci + oci: + region: + namespace: + bucket: + prefix: pbm + credentials: + type: instancePrincipal + ``` + + Wait for a few minutes for IAM policy propagation before testing the configuration. + + !!! note + IAM changes for dynamic groups can take 5 to 10 minutes to propagate. The native copy policy from the previous section is still required alongside the instance principal policy. + +## Apply the PBM configuration + +Apply the configuration: + +```bash +pbm config --file /path/to/oci-config.yaml +``` + +Force PBM to resync the storage configuration: + +```sh +pbm config --force-resync +``` + +## Verify the configuration + +Verify all agents connected and storage initialized successfully: + +```sh +pbm status +``` + +??? example "Output" + + ```sh + $ pbm status + Cluster: + ======== + rs1: + - rs101:27017 [S]: pbm-agent [v2.15.0] OK + - rs102:27017 [S]: pbm-agent [v2.15.0] OK + - rs103:27017 [P]: pbm-agent [v2.15.0] OK + + PITR incremental backup: + ======================== + Status [OFF] + + Currently running: + ================== + (none) + + Backups: + ======== + Main storage: + Type: OCI + Region: us-ashburn-1 + Path: oci://idvufsl0apl6/rasika-bucket/pbm + (no snapshots or PITR chunks) + ``` + +Every node must show `pbm-agent` as `OK` and storage as `ok`. + +Run a test backup to confirm end-to-end functionality: + +```sh +pbm backup +pbm list +``` + +??? example "Output" + + ```sh + $ pbm backup + Starting backup "2026-06-12T07:11:31Z"..... + Backup "2026-06-12T07:11:31Z" saved to remote store (path: "oci://idvufsl0apl6/rasika-bucket/pbm") + ``` + + ```sh + $ pbm list + Backup snapshots: + NAME TYPE PROFILE SELECTIVE BASE RESTORE TIME + ----------------------------------------------------- + 2026-06-11T13:14:51Z logical no no 2026-06-11T13:15:07 + 2026-06-12T07:04:27Z logical no no 2026-06-12T07:04:42 + 2026-06-12T07:11:31Z logical no no 2026-06-12T07:11:46 + + PITR : + ``` \ No newline at end of file diff --git a/docs/details/oci-wif.md b/docs/details/oci-wif.md new file mode 100644 index 00000000..5b376af1 --- /dev/null +++ b/docs/details/oci-wif.md @@ -0,0 +1,175 @@ +# Oracle Cloud Infrastructure (OCI) Object Storage with Workload Identity Authentication + +Percona Backup for MongoDB (PBM) supports multiple authentication methods for Oracle Cloud Infrastructure (OCI) Object Storage, including Workload Identity. With Workload Identity, PBM can access OCI resources without storing or managing API keys, reducing operational overhead and improving security. + +Percona Backup for MongoDB (PBM) supports the default `userPrincipal` authentication method as well as the following Workload Identity options: + +| Auth type | When to use | +|---|---| +|`userPrincipal`|PBM is running anywhere — on-premises, on other clouds, or on OCI| +| `instancePrincipal`| PBM is running on a virtual machine inside OCI | +| `okeWorkloadIdentity`| PBM is running inside an OKE enhanced cluster| + +## userPrincipal + +Choose `userPrincipal` when PBM runs outside OCI, or when you want a single authentication approach that works in any environment. PBM authenticates using an OCI user account and an API signing key. + +### Before you begin + +You need: + +- An OCI user account with access to the target bucket +- An [API signing key pair :octicons-link-external-16:](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm){:target="_blank"} (private key file and its fingerprint) +- The [Oracle Cloud Identifier (OCID) :octicons-link-external-16:](https://docs.oracle.com/en-us/iaas/Content/General/Concepts/identifiers.htm#Oracle){:target="_blank"} of the user and tenancy +- The name of the OCI bucket PBM will use for backups + +### Procedure + +1. **Create an IAM policy** + + Grant the user permission to manage objects in the target bucket: + + ```sh + oci iam policy create \ + --region "$HOME_REGION" \ + --compartment-id "$TENANCY_OCID" \ + --name "$USER_POLICY_NAME" \ + --description "Allow PBM user to access $BUCKET_NAME" \ + --statements "[\"Allow group $USER_GROUP_NAME to manage objects in compartment $COMPARTMENT_NAME where target.bucket.name = '$BUCKET_NAME'\"]" + ``` + + Replace the following variables: + + | Variable | Description | + |---|---| + | `HOME_REGION` | Your tenancy's home region (e.g. `us-ashburn-1`) | + | `TENANCY_OCID` | OCID of your OCI tenancy | + | `USER_POLICY_NAME` | A name for the policy (e.g. `pbm-user-policy`) | + | `USER_GROUP_NAME` | The IAM group the PBM user belongs to | + | `COMPARTMENT_NAME` | Name of the compartment containing the bucket | + | `BUCKET_NAME` | Name of the OCI Object Storage bucket | + +2. **Configure PBM authentication** + + In your PBM configuration, set the storage type to `oci` and the credentials type to `userPrincipal`. Provide the API signing key private key in PEM format. + + ```yaml + storage: + type: oci + oci: + region: + namespace: + bucket: + prefix: + credentials: + type: userPrincipal + userPrincipal: + tenancy: + user: + fingerprint: + privateKey: | + -----BEGIN PRIVATE KEY----- + ... + -----END PRIVATE KEY----- + ``` + +## instancePrincipal + +Choose `instancePrincipal` when PBM runs directly on an OCI Compute instance. PBM automatically obtains OCI credentials from the instance, eliminating the need for credential files or API keys. + +### Before you begin + +You need: + +- The [Oracle Cloud Identifier (OCID) :octicons-link-external-16:](https://docs.oracle.com/en-us/iaas/Content/General/Concepts/identifiers.htm#Oracle){:target="_blank"} of the OCI Compute instance running PBM +- The name of the OCI bucket PBM will use for backups. + +### Procedure + +Follow these steps to set up OCI using **`instancePrincipal`:** + +1. **Create a dynamic group for the instance** + + OCI IAM policies cannot target individual instances directly. You must first add the instance to a dynamic group, then write a policy against that group. + + ```sh + oci iam dynamic-group create \ + --region "$HOME_REGION" \ + --compartment-id "$TENANCY_OCID" \ + --name "$INSTANCE_DYNAMIC_GROUP_NAME" \ + --description "PBM VM instance principal" \ + --matching-rule "ANY {instance.id = '$INSTANCE_OCID'}" + ``` + + Replace the following variables: + + | Variable | Description | + |---|---| + | `HOME_REGION` | Your tenancy's home region (e.g. `us-ashburn-1`) | + | `TENANCY_OCID` | OCID of your OCI tenancy | + | `INSTANCE_DYNAMIC_GROUP_NAME` | A name for the dynamic group (e.g. `pbm-vm-group`) | + | `INSTANCE_OCID` | OCID of the Compute instance running PBM | + +2. **Create an IAM policy** + + Grant the dynamic group permission to manage objects in the target bucket: + + ```sh + export INSTANCE_POLICY_STATEMENT="Allow dynamic-group $INSTANCE_DYNAMIC_GROUP_NAME \ + to manage objects in compartment $COMPARTMENT_NAME \ + where target.bucket.name = '$BUCKET_NAME'" + + oci iam policy create \ + --region "$HOME_REGION" \ + --compartment-id "$TENANCY_OCID" \ + --name "$INSTANCE_POLICY_NAME" \ + --description "Allow PBM VM instance principal to access $BUCKET_NAME" \ + --statements "[\"$INSTANCE_POLICY_STATEMENT\"]" + ``` + + Replace the following additional variables: + + | Variable | Description | + |---|---| + | `COMPARTMENT_NAME` | Name of the compartment containing the bucket | + | `BUCKET_NAME` | Name of the OCI Object Storage bucket | + | `INSTANCE_POLICY_NAME` | A name for the policy (e.g. `pbm-vm-policy`) | + +3. **Configure PBM authentication** + + In your PBM configuration, set the storage type to `oci` and the credentials type to `instancePrincipal`. No key file or passphrase is needed. + + ```yaml + storage: + type: oci + oci: + region: + namespace: + bucket: + prefix: + credentials: + type: instancePrincipal + ``` + +## okeWorkloadIdentity + +Choose `okeWorkloadIdentity` when PBM runs as a workload in an Oracle Kubernetes Engine (OKE) enhanced cluster. The Kubernetes service account token is exchanged for OCI credentials automatically by the OKE Workload Identity service. + +!!! note + Your OKE cluster must be an **enhanced cluster** with Workload Identity enabled. Basic clusters do not support this feature. + +In your PBM configuration, set the storage type to `oci` and the credentials type to `okeWorkloadIdentity`: + +```yaml +storage: + type: oci + oci: + region: + namespace: + bucket: + prefix: + credentials: + type: okeWorkloadIdentity +``` + +For setup instructions, see [Configure OKE Workload Identity for workloads :octicons-link-external-16:](https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contenggrantingworkloadaccesstoresources.htm){:target="_blank"}. \ No newline at end of file diff --git a/docs/details/storage-configuration.md b/docs/details/storage-configuration.md index 5f49941f..d06bedab 100644 --- a/docs/details/storage-configuration.md +++ b/docs/details/storage-configuration.md @@ -17,6 +17,7 @@ Percona Backup for MongoDB supports the following storage types: * [MinIO and S3-compatible storage](minio.md) * [Filesystem server storage](filesystem-storage.md) * [Microsoft Azure Blob storage](azure.md) +* [Oracle Cloud Infrastructure Object Storage](oci-storage.md) * [Alibaba Cloud OSS storage](oss.md) ### Considerations for choosing a backup storage type for s3-compatible storages diff --git a/docs/reference/configuration-options.md b/docs/reference/configuration-options.md index 7a18330c..761e98c3 100644 --- a/docs/reference/configuration-options.md +++ b/docs/reference/configuration-options.md @@ -7,7 +7,7 @@ *Type*: string
*Required*: YES -Remote backup storage type. Supported values: `s3`, `minio`, `gcs`, `filesystem`, `azure`. +Remote backup storage type. Supported values: `s3`, `minio`, `gcs`, `filesystem`, `azure`, `oci`, `oss`. ## AWS S3 storage options @@ -679,6 +679,92 @@ The minimum time to wait before the next retry, specified as a `time.Duration`. The maximum time to wait before the next retry, specified as a `time.Duration`. Units like ms, s, etc., are supported. Defaults to nanoseconds if no unit is provided. +## OCI Object Storage options + +```yaml +storage: + type: oci + oci: + region: + namespace: + bucket: + prefix: + credentials: + type: userPrincipal + userPrincipal: + tenancy: + user: + fingerprint: + privateKey: | + -----BEGIN PRIVATE KEY----- + ... + -----END PRIVATE KEY----- +``` + +### storage.oci.region + +*Type*: string
+*Required*: YES + +The OCI region where your Object Storage bucket is located. + +### storage.oci.namespace + +*Type*: string
+*Required*: YES + +The Object Storage namespace for your OCI tenancy. + +### storage.oci.bucket + +*Type*: string
+*Required*: YES + +The name of the Object Storage bucket where PBM stores backups. + +### storage.oci.prefix + +*Type*: string
+*Required*: NO + +The path prefix in the bucket. If undefined, backups are stored in the bucket root. + +### storage.oci.credentials.type + +*Type*: string
+*Required*: NO
+*Default*: `userPrincipal` + +Authentication type for OCI access. Supported values: `userPrincipal`, `instancePrincipal`, `okeWorkloadIdentity`. + +### storage.oci.credentials.userPrincipal.tenancy + +*Type*: string
+*Required*: YES (when `storage.oci.credentials.type=userPrincipal`) + +The tenancy OCID for OCI API signing key authentication. + +### storage.oci.credentials.userPrincipal.user + +*Type*: string
+*Required*: YES (when `storage.oci.credentials.type=userPrincipal`) + +The user OCID for OCI API signing key authentication. + +### storage.oci.credentials.userPrincipal.fingerprint + +*Type*: string
+*Required*: YES (when `storage.oci.credentials.type=userPrincipal`) + +The fingerprint of the uploaded OCI API signing public key. + +### storage.oci.credentials.userPrincipal.privateKey + +*Type*: string
+*Required*: YES (when `storage.oci.credentials.type=userPrincipal`) + +The private key in PEM format that pairs with the uploaded OCI API signing public key. + ## Alibaba Cloud OSS storage options ```yaml diff --git a/mkdocs-base.yml b/mkdocs-base.yml index b5fde611..7b63fed5 100644 --- a/mkdocs-base.yml +++ b/mkdocs-base.yml @@ -242,6 +242,9 @@ nav: - Storage: - Remote backup storage overview: details/storage-configuration.md - AWS S3 storage: details/s3-storage.md + - Oracle Cloud Storage: + - Overview: details/oci-storage.md + - Workload Identity authentication: details/oci-wif.md - details/minio.md - details/gcs.md - Workload Identity authentication: details/workload-identity-auth.md