Pure Storage FlashArray

Pure Storage FlashArray

Certified
Enterprise Edition

Manage Pure Storage FlashArray systems from Kestra: volumes, snapshots, ActiveDR pods, and array/alert monitoring.

How to use the Pure Storage FlashArray plugin

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.

Authentication

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') }}"

Tasks

Volumes (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.

Snapshots (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).

ActiveDR pods (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.

Arrays (io.kestra.plugin.ee.purestorage.arrays)

Task API endpoint Key properties
GetInfo GET /api/{version}/arrays
ListAlerts GET /api/{version}/alerts pageSize, fetchType

Triggers

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 }}.