Dell EMC

Dell EMC

Certified
Enterprise Edition

Manage Dell EMC storage systems from Kestra, starting with PowerStore: volumes, snapshots, replication, and array/alert monitoring.

How to use the Dell EMC plugin

Manage Dell EMC storage systems from Kestra. This first release covers Dell EMC PowerStore via its REST API (https://{host}/api/rest): volumes, snapshots, replication, and array/alert monitoring.

Authentication

Every task authenticates with HTTP Basic Auth exchanged for a session: GET /api/rest/login_session is called with an Authorization: Basic header built from username/password; the appliance responds with a session cookie (Set-Cookie) and a DELL-EMC-TOKEN CSRF value. Every subsequent request sends the Authorization header and the session cookie; write requests (POST/PATCH/DELETE) additionally send DELL-EMC-TOKEN. If a write is rejected with HTTP 403 (a stale or missing CSRF token), the task re-authenticates once and retries before failing.

Required connection properties on every task:

Property Description
host Management IP or hostname, optionally including a port (for example: powerstore.example.com or 192.168.1.20: 8443)
username PowerStore local or LDAP account username
password Password — store as a secret and reference via {{ secret('POWERSTORE_PASSWORD') }}

Optional:

Property Description
skipTlsVerification When true, accepts the appliance's TLS certificate without validation. Defaults to false. PowerStore management interfaces are commonly deployed with a self-signed certificate; intended for lab/non-production use only.

Use plugin defaults to avoid repeating connection properties across tasks:

pluginDefaults: 
  - type: io.kestra.plugin.ee.dellemc.powerstore
    values: 
      host: "{{ secret('POWERSTORE_HOST') }}"
      username: "{{ secret('POWERSTORE_USERNAME') }}"
      password: "{{ secret('POWERSTORE_PASSWORD') }}"

Tasks

Volumes (io.kestra.plugin.ee.dellemc.powerstore.volumes)

Task API endpoint Key properties
List GET /api/rest/volume pageSize, fetchType
Get GET /api/rest/volume/{id} volumeId
Create POST /api/rest/volume name, sizeBytes, wait, waitTimeout
Resize PATCH /api/rest/volume/{id} volumeId, sizeBytes, wait, waitTimeout
Delete DELETE /api/rest/volume/{id} volumeId

List supports a fetchType property (default STORE): STORE writes results to Kestra internal storage and returns a URI (recommended for large appliances), FETCH returns all rows inline, FETCH_ONE returns a single row, and NONE returns only the total count. Pagination uses PowerStore's limit/offset convention.

Create and Resize may be accepted asynchronously by the appliance (HTTP 202 with a job reference) and both expose the job ID via a jobId output while pending. When wait is true (default), the task polls GET /api/rest/job/{id} until completion, bounded by waitTimeout (default PT10M, capped at PT30M); a job failure fails the task with the job's error detail, while a client-side wait timeout returns successfully without confirmed completion instead of failing. Polling blocks the worker thread for the duration of the wait — size the worker pool accordingly if many job-aware tasks run concurrently. PowerStore exposes no job-cancellation endpoint: killing the execution stops the task from polling immediately, but the array-side operation itself keeps running to completion regardless.

Snapshots (io.kestra.plugin.ee.dellemc.powerstore.snapshots)

Task API endpoint Key properties
Create POST /api/rest/volume/{volumeId}/snapshot volumeId, name
List GET /api/rest/volume?type=eq.Snapshot&protection_data->>source_id=eq.{volumeId} volumeId, pageSize, fetchType
Delete DELETE /api/rest/volume/{snapshotId} snapshotId
Restore POST /api/rest/volume/{volumeId}/restore with body {"from_snap_id": "<snapshotId>"} volumeId, snapshotId, wait, waitTimeout

A snapshot is a volume resource under the hood in PowerStore, so Delete reuses the same /volume/{id} endpoint as a regular volume, and List has no dedicated sub-collection — it filters /volume by type=Snapshot and protection_data.source_id. Restore targets the parent volume (volumeId), restoring it in place to the state captured by snapshotId; any data written after the snapshot was taken is lost, and the source snapshot itself is left untouched. Like volumes.Resize/replication.Failover, Restore may be accepted asynchronously (HTTP 202 + job) and exposes the job ID via a jobId output while pending; see wait/waitTimeout.

Replication (io.kestra.plugin.ee.dellemc.powerstore.replication)

Task API endpoint Key properties
CreateRule POST /api/rest/replication_rule name, rpo (one of Five_Minutes, Fifteen_Minutes, Thirty_Minutes, One_Hour, Six_Hours, Twelve_Hours, One_Day, Zero), remoteSystemId
GetSessionStatus GET /api/rest/replication_session/{id} sessionId
Failover POST /api/rest/replication_session/{id}/failover sessionId, wait, waitTimeout
Synchronize POST /api/rest/replication_session/{id}/sync sessionId, wait, waitTimeout

Failover and Synchronize follow the same asynchronous job semantics as volumes.Create/Resize (see above): wait/waitTimeout control whether and how long the task polls for completion before returning.

Arrays (io.kestra.plugin.ee.dellemc.powerstore.arrays)

Task API endpoint Key properties
ListAlerts GET /api/rest/alert acknowledgedOnly (default false), pageSize, fetchType
GetMetrics POST /api/rest/metrics/generate entityType, entityId, interval, fetchType

ListAlerts returns every alert by default; set acknowledgedOnly: true to restrict results to already-acknowledged alerts. Both tasks support fetchType (default STORE, same semantics as the volumes/snapshots List tasks: STORE writes results to internal storage and returns a uri, FETCH returns all rows inline, FETCH_ONE returns one row, NONE returns only the count). The total output reflects the appliance-reported count regardless of fetchType, and an empty result set returns a 0 count rather than an error. GetMetrics's underlying /metrics/generate endpoint is not paginated, so the full data point set is always received and parsed in memory before fetchType is applied — STORE keeps data points out of the execution's output but does not reduce that parse-time memory peak.

Triggers

OnAlertCreated (io.kestra.plugin.ee.dellemc.powerstore.arrays)

Polls GET /api/rest/alert at interval, filtered server-side to unacknowledged alerts only (so poll cost scales with the open-alert backlog rather than the full alert history). Each poll emits at most one execution: when one or more new, unacknowledged alerts at or above minSeverity (NONE < INFO < MINOR < MAJOR < CRITICAL, default MINOR) are discovered, the output describes the newest one and lists every new alert from that poll cycle in alerts, so a burst of several new alerts is never reduced to just the newest. An alert reporting a severity string outside this set is logged and treated as not meeting the threshold, rather than crashing the poll cycle.

Key properties: host, username, password, minSeverity, interval (default PT1M).

On the very first poll, all pre-existing matching alerts are recorded without triggering executions. If the appliance is unreachable, the trigger logs a warning and waits for the next cycle. Two alerts raised 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.description }}, {{ trigger.severity }}, {{ trigger.raisedTimestamp }}, {{ trigger.newAlertCount }}, {{ trigger.alerts }} (the newest alert plus the full list of new alerts detected in the poll cycle).