kestra-io / kestra-io/plugin-oci

[Plugin] OCI — Block Storage (Volumes & Backups)

Open
#5 0 comments 0 reactions 0 assignees View on GitHub
area/plugin
Dominant language
Java
Stars
0
Forks
0
Avg merge
18h 3m
Merged PRs (30d)
1

Description

## Summary

The OCI Block Storage sub-plugin for `plugin-oci` enables Kestra flows to create, attach, detach, and back up block volumes — making persistent disk management part of reproducible, auditable orchestration pipelines. Teams can automate snapshot schedules, pre-provision volumes before launching compute instances, and clean up disks as part of teardown flows.

## Motivation

Infrastructure automation teams provisioning ephemeral OCI environments need to manage block volumes alongside compute resources. Today this requires OCI CLI scripts or Terraform runs that are hard to coordinate with downstream tasks. A native Block Storage sub-plugin lets flows create a volume, attach it to a freshly launched instance (Compute sub-plugin), and back it up — all in a single typed, expression-aware flow.

## Context

Part of the OCI Plugin Suite EPIC: https://github.com/kestra-io/plugin-oci/issues/2
Block Storage shares the `oci-java-sdk-core` module with the Compute sub-plugin (see #7943).
Reference: `plugin-aws` EBS tasks.

## API Reference

- **Official docs**: https://docs.oracle.com/en-us/iaas/api/#/en/iaas/latest/Volume
- **Authentication**: Config-file (`~/.oci/config`), instance principal, or `SimpleAuthenticationDetailsProvider`
- **Base URL pattern**: `https://iaas.{region}.oraclecloud.com/20160918/`
- **SDK**: OCI Java SDK v3.87.0 via BOM

## Gradle Dependencies

Add to `build.gradle`:

```groovy
// OCI Java SDK BOM
implementation platform("com.oracle.oci.sdk:oci-java-sdk-bom:3.87.0")
// Block Storage shares the core module with Compute
implementation "com.oracle.oci.sdk:oci-java-sdk-core"
implementation "com.oracle.oci.sdk:oci-java-sdk-common"
```

## Plugin Structure

- **Repository**: `plugin-oci`
- **Namespace**: `io.kestra.plugin.oci.blockstorage`
- **Sub-plugins**: `blockstorage` (volumes, backups)

## Suggested Tasks

1. `CreateVolume` — provision a new block volume (size, compartment, AD)
2. `DeleteVolume` — delete a volume by OCID
3. `GetVolume` — fetch volume details and emit lifecycle state as output
4. `ListVolumes` — list volumes in a compartment
5. `AttachVolume` — attach a volume to a compute instance (iSCSI or paravirtualized)
6. `DetachVolume` — detach a volume from an instance
7. `CreateVolumeBackup` — create an on-demand backup of a volume
8. `DeleteVolumeBackup` — delete a volume backup
9. Add `VolumeLifecycleTrigger` — poll until volume reaches target lifecycle state
10. Write unit + integration tests

## YAML Examples

### Example 1 — Create a volume, attach it to an instance, and trigger a backup

```yaml
id: provision_and_backup_volume
namespace: company.platform

inputs:
- id: instance_ocid
type: STRING
- id: compartment_ocid
type: STRING

tasks:
- id: create_volume
type: io.kestra.plugin.oci.blockstorage.CreateVolume
region: eu-frankfurt-1
tenancyOcid: "{{ secret('OCI_TENANCY_OCID') }}"
userId: "{{ secret('OCI_USER_OCID') }}"
fingerprint: "{{ secret('OCI_FINGERPRINT') }}"
privateKey: "{{ secret('OCI_PRIVATE_KEY') }}"
compartmentId: "{{ inputs.compartment_ocid }}"
availabilityDomain: AD-1
sizeInGBs: 100
displayName: kestra-data-vol-{{ execution.id }}

- id: attach_volume
type: io.kestra.plugin.oci.blockstorage.AttachVolume
region: eu-frankfurt-1
tenancyOcid: "{{ secret('OCI_TENANCY_OCID') }}"
userId: "{{ secret('OCI_USER_OCID') }}"
fingerprint: "{{ secret('OCI_FINGERPRINT') }}"
privateKey: "{{ secret('OCI_PRIVATE_KEY') }}"
instanceId: "{{ inputs.instance_ocid }}"
volumeId: "{{ outputs.create_volume.volumeId }}"
type: PARAVIRTUALIZED

- id: backup_volume
type: io.kestra.plugin.oci.blockstorage.CreateVolumeBackup
region: eu-frankfurt-1
tenancyOcid: "{{ secret('OCI_TENANCY_OCID') }}"
userId: "{{ secret('OCI_USER_OCID') }}"
fingerprint: "{{ secret('OCI_FINGERPRINT') }}"
privateKey: "{{ secret('OCI_PRIVATE_KEY') }}"
volumeId: "{{ outputs.create_volume.volumeId }}"
displayName: backup-{{ execution.startDate | dateFormat('yyyy-MM-dd') }}
```

### Example 2 — List volumes and log their sizes

```yaml
id: audit_block_volumes
namespace: company.platform

tasks:
- id: list_volumes
type: io.kestra.plugin.oci.blockstorage.ListVolumes
region: eu-frankfurt-1
tenancyOcid: "{{ secret('OCI_TENANCY_OCID') }}"
userId: "{{ secret('OCI_USER_OCID') }}"
fingerprint: "{{ secret('OCI_FINGERPRINT') }}"
privateKey: "{{ secret('OCI_PRIVATE_KEY') }}"
compartmentId: "{{ secret('OCI_COMPARTMENT_OCID') }}"

- id: log_volumes
type: io.kestra.plugin.core.log.Log
message: "Found {{ outputs.list_volumes.count }} volumes"
```

### Example 3 — Trigger cleanup when a volume backup completes

```yaml
id: on_volume_backup_available
namespace: company.platform

triggers:
- id: backup_watcher
type: io.kestra.plugin.oci.blockstorage.VolumeLifecycleTrigger
region: eu-frankfurt-1
tenancyOcid: "{{ secret('OCI_TENANCY_OCID') }}"
userId: "{{ secret('OCI_USER_OCID') }}"
fingerprint: "{{ secret('OCI_FINGERPRINT') }}"
privateKey: "{{ secret('OCI_PRIVATE_KEY') }}"
volumeId: "{{ secret('OCI_VOLUME_OCID') }}"
targetLifecycleState: AVAILABLE
interval: PT3M

tasks:
- id: notify
type: io.kestra.plugin.core.log.Log
message: "Volume {{ trigger.volumeId }} is now AVAILABLE"
```

## Acceptance Criteria

- [ ] `CreateVolume`, `DeleteVolume`, `GetVolume`, `ListVolumes`, `AttachVolume`, `DetachVolume`, `CreateVolumeBackup`, `DeleteVolumeBackup` tasks implemented
- [ ] `VolumeLifecycleTrigger` polling trigger implemented
- [ ] All `Property` fields support Kestra expression language
- [ ] Unit + integration tests pass (`./gradlew test`)
- [ ] `package-info.java` with `@PluginSubGroup(category = PluginSubGroup.PluginCategory.CLOUD)`
- [ ] Build passes with `./gradlew build`

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in the plugin-oci repository by reviewing the existing Compute sub-plugin and the plugin-aws EBS tasks, then inspect build.gradle and package-info.java. Implement the eight block-storage tasks and VolumeLifecycleTrigger described in the issue, with expression-capable Property fields. Run ./gradlew test and ./gradlew build; done means the acceptance checklist passes, including unit and integration tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
cloud, infrastructure
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.