Pure Storage FlashArray Snapshots
Tasks for managing Pure Storage FlashArray volume snapshots: create, list, delete, and restore.
Manage Pure Storage FlashArray systems from Kestra: volumes, snapshots, ActiveDR pods, and array/alert monitoring.
Interact with Pure Storage FlashArray systems via the Purity//FA REST API (https://{host}: {port}/api/). The plugin covers volume management, snapshot operations, ActiveDR pod failover, and array/alert monitoring.
Every task authenticates with a two-step token exchange: a static apiToken is sent to POST /api/{version}/login (as the api-token request header) and exchanged for a short-lived session token returned in the x-auth-token response header. That session token is then sent as x-auth-token on every subsequent call. This plugin does not perform the username/password → API-token exchange (POST /api/1.x/auth/apitoken); generate apiToken out-of-band (Pure1 or pureadmin) and store it as a Kestra secret.
If a session expires mid-run (HTTP 401 on a data call), the task re-authenticates once and retries the failed request before giving up.
Required connection properties on every task:
| Property | Description |
|---|---|
host |
Array management IP or hostname (for example: flasharray.example.com) |
apiToken |
Static API token — store as a secret and reference via {{ secret('PURESTORAGE_API_TOKEN') }} |
Optional:
| Property | Description |
|---|---|
scheme |
Protocol scheme, defaults to https; set to http only for testing against local stubs |
port |
REST API port, defaults to 443 |
apiVersion |
Pins the REST API version (for example: 2.30), bypassing runtime discovery (GET /api/api_version) |
options |
HttpConfiguration block — set ssl: { insecureTrustAllCertificates: true } to accept self-signed array certs (insecure, lab use only). When timeout is not set, a default 10s connect / 60s read-idle timeout is applied so an unreachable or stalled array fails fast instead of hanging the task; set options.timeout explicitly to override. |
Use plugin defaults to avoid repeating connection properties across tasks:
pluginDefaults:
- type: io.kestra.plugin.ee.purestorage
values:
host: "{{ secret('PURESTORAGE_HOST') }}"
apiToken: "{{ secret('PURESTORAGE_API_TOKEN') }}"
io.kestra.plugin.ee.purestorage.volumes)| Task | API endpoint | Key properties |
|---|---|---|
List |
GET /api/{version}/volumes |
pageSize, fetchType |
Get |
GET /api/{version}/volumes?names={name} |
name |
Create |
POST /api/{version}/volumes?names={name} |
name, provisionedBytes |
Resize |
PATCH /api/{version}/volumes?names={name} |
name, provisionedBytes |
Delete |
PATCH …/volumes?names={name} (destroyed=true), then DELETE …/volumes?names={name} if eradicate |
name, eradicate (default false) |
List supports a fetchType property (default STORE): STORE writes results to Kestra internal storage and returns a URI (recommended for large arrays), FETCH returns all rows inline, FETCH_ONE returns a single row, and NONE returns only the count. Pagination uses FlashArray's continuation_token mechanism.
Delete soft-deletes by default (the volume enters a pending-eradication window and can be recovered); set eradicate: true to permanently remove it immediately. Resizing below used capacity is rejected by FlashArray with a descriptive error message.
io.kestra.plugin.ee.purestorage.snapshots)| Task | API endpoint | Key properties |
|---|---|---|
Create |
POST /api/{version}/volume-snapshots?source_names={vol} |
volumeName, suffix |
List |
GET /api/{version}/volume-snapshots?source_names={vol} |
volumeName, pageSize, fetchType |
Delete |
PATCH …/volume-snapshots?names={snapshot} (destroyed=true), then DELETE … if eradicate |
snapshotName, eradicate (default false) |
Restore |
POST /api/{version}/volumes?names={targetVolumeName} |
snapshotName, targetVolumeName |
Snapshots are named {volumeName}.{suffix}. Restore creates a brand-new volume as a full copy of the snapshot rather than overwriting the source volume in place; if targetVolumeName already exists, FlashArray rejects the request and the array's error is surfaced as-is (no silent overwrite).
io.kestra.plugin.ee.purestorage.pods)| Task | API endpoint | Key properties |
|---|---|---|
List |
GET /api/{version}/pods |
pageSize, fetchType |
Get |
GET /api/{version}/pods?names={name} |
name |
Create |
POST /api/{version}/pods?names={name} |
name |
Promote |
PATCH /api/{version}/pods?names={name} |
name, waitTimeout (default PT2M) |
Demote |
PATCH /api/{version}/pods?names={name} |
name, waitTimeout (default PT2M) |
Promote and Demote set requested_promotion_state to promoted / demoted and then poll (bounded by waitTimeout) until the pod's promotion_status reaches that state. A pod already in the target state is a no-op. If the pod is still transitioning when waitTimeout elapses, the task still returns successfully — the last-observed promotionStatus and reachedTargetState: false are exposed in the output rather than throwing. waitTimeout is only exposed on these two tasks.
io.kestra.plugin.ee.purestorage.arrays)| Task | API endpoint | Key properties |
|---|---|---|
GetInfo |
GET /api/{version}/arrays |
— |
ListAlerts |
GET /api/{version}/alerts |
pageSize, fetchType |
OnAlertCreated (io.kestra.plugin.ee.purestorage.arrays)Polls GET /api/{version}/alerts at interval and fires one execution per newly detected, unacknowledged alert (state == open).
Key properties: host, apiToken, interval.
On the very first poll, all pre-existing open alerts are recorded without triggering executions. If the array is unreachable, the trigger logs a warning and waits for the next cycle. Two alerts opening in the same millisecond are each fired exactly once thanks to an ID-based boundary tracked alongside the timestamp baseline.
Trigger outputs available as {{ trigger.alertId }}, {{ trigger.alertName }}, {{ trigger.summary }}, {{ trigger.severity }}, {{ trigger.opened }}, {{ trigger.newAlertCount }}.