3. Pure Storage Python SDK入门

Pure Storage 官方为 FlashArray 提供了 Python SDK,包名为 purestorage。它把 REST API 封装成 Python 对象,让运维脚本可以用 FlashArray 类直接调用卷、主机、快照、性能等资源,而不必手写 HTTP 请求、拼接 URL 或处理 JSON 解析。本节从安装配置开始,逐步完成连接、查询、异常处理与日志记录,形成一条可复用的最小脚本骨架。

安装与版本选择

SDK 通过 pip 安装,建议在虚拟环境中进行,避免与系统 Python 包冲突:

python -m venv pure-venv
source pure-venv/bin/activate        # Windows 使用 pure-venv\Scripts\activate
pip install purestorage
pip show purestorage                 # 确认版本,例如 1.19.0

SDK 版本与 Purity//FA 存在兼容关系:较新的 SDK 通常支持多个 Purity 版本,但过旧的 SDK 可能无法识别新接口。生产脚本应固定版本,例如在 requirements.txt 中写 purestorage==1.19.0,避免升级后行为变化。若使用 Ansible 的 purestorage.flasharray 集合,其底层同样依赖该 SDK,版本需一并核对。

连接 FlashArray 的三种认证方式

连接前需要在阵列上创建 API Token。登录 FlashArray GUI,进入 Settings → Access → API Tokens,为某个用户创建 Token,并记录角色(如 storage_admin、readonly)。SDK 支持三种认证方式:

  • API Token:最常用,Token 形如 xxxxx-xxxxx-xxxxx,配合用户名使用。
  • 用户名 + 密码:适合临时调试,但密码明文风险高,不建议写入脚本。
  • REST 会话:SDK 内部自动管理 session,无需手动登录。

推荐把 Token 放在环境变量或配置文件中,而不是硬编码。例如:

export PURE_FA_URL="10.20.30.40"
export PURE_FA_TOKEN="a1b2c3d4-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export PURE_FA_USER="pureuser"

连接代码示例:

import os
from purestorage import FlashArray

fa = FlashArray(
    os.environ["PURE_FA_URL"],
    api_token=os.environ["PURE_FA_TOKEN"],
    username=os.environ.get("PURE_FA_USER", "pureuser"),
    verify_https=True,          # 生产环境保持 True
    timeout=30
)

verify_https=True 会校验阵列证书。若使用自签名证书,应把 CA 证书路径传给 verify_https,而不是简单设为 False,否则会失去中间人攻击防护。

获取阵列信息与执行简单查询

连接成功后,SDK 提供大量 get_* 方法。常用查询包括:

  • fa.get():返回阵列基本信息,如阵列名、Purity 版本、容量。
  • fa.list_volumes():列出所有卷及其大小、创建时间。
  • fa.list_hosts():列出主机及 IQN/WWN。
  • fa.list_snapshots():列出快照。
  • fa.get_volume(name, space=True):获取单个卷的详细空间信息。

下面示例获取阵列版本并统计卷数量与总容量:

info = fa.get()
print("阵列名:", info["array_name"])
print("Purity 版本:", info["version"])

vols = fa.list_volumes()
total = sum(v["size"] for v in vols)
print(f"卷数量: {len(vols)}, 总容量: {total / 1024**4:.2f} TiB")

for v in vols[:5]:
    print(v["name"], v["size"] / 1024**3, "GiB")

查询结果以字典或字典列表返回,字段名与 REST API 一致。若需要分页,SDK 会自动处理 continuation_token,但数据量大时建议加 limit 参数控制单次返回量。

异常处理与日志记录

SDK 在遇到错误时抛出 purestorage.PureError,其属性包含 code、message、context。常见错误码:400 参数错误、401 认证失败、403 权限不足、404 对象不存在、429 请求过频。脚本应捕获并区分处理:

from purestorage import PureError, PureHTTPError

try:
    fa.get_volume("vol-not-exist")
except PureHTTPError as e:
    if e.code == 404:
        print("卷不存在,可创建")
    elif e.code == 401:
        print("Token 失效,请重新生成")
    else:
        raise
except PureError as e:
    print("SDK 错误:", e)

日志方面,SDK 使用 Python 标准 logging,logger 名为 purestorage。开启 DEBUG 可看到每次 REST 请求的 URL、方法、状态码和耗时,便于排障:

import logging
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(name)s %(levelname)s %(message)s",
    filename="pure_sdk.log"
)
logging.getLogger("purestorage").setLevel(logging.DEBUG)

注意 DEBUG 日志可能包含 Token 或敏感字段,生产环境应使用 INFO 级别,并对日志文件设置权限。

purestorage SDK 连接与查询链路 Python 脚本 FlashArray(...) get / list_volumes 认证凭据 API Token 用户名 / 密码 REST API HTTPS / JSON session 管理 FlashArray Purity//FA 卷 / 主机 / 快照 返回 dict / list[dict] 异常处理 PureHTTPError.code 401 认证失败 → 重新生成 Token 404 对象不存在 → 创建或跳过 429 请求过频 → 退避重试 日志记录 logger: purestorage INFO: 操作结果与耗时 DEBUG: REST URL / 状态码 输出到文件,权限 600 可观测结果 阵列名 / Purity 版本 / 卷数量 / 总容量 / 错误码 / 请求耗时

一个可复用的最小脚本骨架

把上述内容组合起来,形成如下脚本。它读取环境变量、连接阵列、打印版本与卷统计,并在异常时记录日志:

import os, logging
from purestorage import FlashArray, PureHTTPError, PureError

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(message)s",
    filename="pure_sdk.log"
)
log = logging.getLogger("pure-demo")

def main():
    try:
        fa = FlashArray(
            os.environ["PURE_FA_URL"],
            api_token=os.environ["PURE_FA_TOKEN"],
            username=os.environ.get("PURE_FA_USER", "pureuser"),
            verify_https=True,
            timeout=30
        )
        info = fa.get()
        log.info("连接成功: %s, Purity %s", info["array_name"], info["version"])

        vols = fa.list_volumes()
        total = sum(v["size"] for v in vols)
        log.info("卷数量=%d, 总容量=%.2f TiB", len(vols), total / 1024**4)

    except PureHTTPError as e:
        log.error("HTTP 错误 code=%s msg=%s", e.code, e.message)
    except PureError as e:
        log.error("SDK 错误: %s", e)
    except KeyError as e:
        log.error("环境变量缺失: %s", e)

if __name__ == "__main__":
    main()
调试阶段可临时把 verify_https 设为 False 以排除证书问题,但定位后必须改回 True 或传入正确的 CA 证书路径。Token 应通过环境变量、Vault 或配置文件注入,不要提交到 Git。
list_volumes() 在卷数量很多时会返回较大列表,可能占用较多内存。若只需统计,可考虑使用 limit 分页或直接调用性能接口;对生产阵列执行批量查询时,注意控制频率,避免触发 429。