使用 Python 脚本监控 EMC Unity 300 存储系统

存储系统的稳定运行对企业数据中心至关重要。为了确保EMCUnity300存储系统的高可用性和性能,管理员需要一个高效的监控解决方案。本文将介绍如何使用Python编写一个脚本,通过API接口监控EMCUnity300存储系统的多个关键指标,包括系统信息、存储池信息、逻辑单元信息和物理硬盘信息。

存储系统的稳定运行对企业数据中心至关重要。为了确保 EMC Unity 300 存储系统的高可用性和性能,管理员需要一个高效的监控解决方案。本文将介绍如何使用 Python 编写一个脚本,通过 API 接口监控 EMC Unity 300 存储系统的多个关键指标,包括系统信息、存储池信息、逻辑单元信息和物理硬盘信息。


一、准备工作


    安装必要的 Python 库

        确保已安装 requests 库,用于发送 HTTP 请求。

        安装命令:pip install requests


    获取存储系统访问权限

        确保具有 EMC Unity 300 存储系统的管理员访问权限。

        准备好存储系统的 IP 地址、用户名和密码。


二、Python 脚本详细介绍


以下是完整的 Python 脚本,用于监控 EMC Unity 300 存储系统。

#!/usr/bin/env python
# -*- coding : utf-8 -*-
# @Time : 2024/5/8 15:58
# @Author : 我是Rain呀 -- (。♥ᴗ♥。) 
# @File : EMC_UNITY300_DEMO.py
# @Software : PyCharm
import requests
import urllib3
import json
import argparse
import getpass

class UserInput:
    # 创建参数解析器
    parser = argparse.ArgumentParser(description="User Input Parser")
    parser.add_argument('--ipaddress', type=str, help='ipaddress', required=True)
    parser.add_argument('--username', type=str, help='Username', default='admin')
    parser.add_argument('--password', type=str, help='Password', default=None)
    parser.add_argument('--mode', type=str, help='models', required=True)
    # 解析用户输入的参数
    args = parser.parse_args()

class EmcUnity300(UserInput):
    # 常量
    BASE_URL = 'https://{}/api'.format(UserInput.args.ipaddress.strip()) # 存储系统的基础 URL
    if UserInput.args.password is None:
        UserInput.args.password = getpass.getpass("Enter your password: ")
    AUTH = (UserInput.args.username, UserInput.args.password) # 认证信息 (用户名, 密码)
    HEADERS = {
        "Accept": "application/json; version=1.0",
        "Accept-Language": "en-US",
        "Content-Type": "application/json",
        "X-EMC-REST-CLIENT": "true",
        "Application-Type": "your_plugin_name/your_plugin_version"
    } # 请求头
    def __init__(self):
        urllib3.disable_warnings()
        self.session = requests.Session()
        self.session.verify = False
    def send_request(self, endpoint, params=None):
        url = f"{self.BASE_URL}/{endpoint}"
        headers = self.HEADERS.copy()
        # 如果会话尚未进行身份验证,则使用默认身份验证信息
        if self.session.auth is None:
            self.session.auth = self.AUTH
        # 如果存在 CSRF 令牌,则添加到请求头中
        if self.session.auth and not self.session.auth[1]:
            del headers['EMC-CSRF-TOKEN']
        try:
            # 发送 HTTP 请求
            with self.session.get(url, headers=headers, params=params) as response:
                # 检查响应状态
                response.raise_for_status()
                # 解析 JSON 响应
                return response.json()
        except requests.RequestException as e:
            # 处理 HTTP 请求异常
            print("HTTP请求发生错误:", e)
            return None
        except json.JSONDecodeError as e:
            # 处理 JSON 解析异常
            print("JSON解析错误:", e)
            return None
    def get_system(self):
        # 获取物理系统信息
        endpoint = 'instances/system/0'
        params = {'fields': 'name,health,model,serialNumber,currentPower,avgPower'}
        result = self.send_request(endpoint, params=params)
        if result:
            # 构造系统信息的 JSON 字符串
            return json.dumps({
                "system_name": result.get("content", {}).get("name"),
                "system_model": result.get("content", {}).get("model"),
                "system_serialNumber": result.get("content", {}).get("serialNumber"),
                "system_currentPower": result.get("content", {}).get("currentPower"),
                "system_avgPower": result.get("content", {}).get("avgPower"),
                "system_health": result.get("content", {}).get("health", {}).get("value")
            })
        return None
    def get_pool(self):
        # 获取存储池信息
        endpoint = 'types/pool/instances'
        params = {
            'fields': 'health,name,sizeTotal,sizeFree,percentUsed::sizeTotal eq 0 ? 0.0 : ((sizeUsed / sizeTotal) * '
                      '100),snapSizeUsed,sizeUsed,type'}
        result = self.send_request(endpoint, params=params)
        if result:
            # 构造存储池信息的 JSON 字符串
            return json.dumps([{
                "name": data.get("content", {}).get("name"),
                "sizeFree": data.get("content", {}).get("sizeFree"),
                "sizeTotal": data.get("content", {}).get("sizeTotal"),
                "sizeUsed": data.get("content", {}).get("sizeUsed"),
                "percentUsed": data.get("content", {}).get("percentUsed"),
                "health": data.get("content", {}).get("health", {}).get("value")
            } for data in result.get("entries", [])])
        return None
    def get_lun(self):
        # 获取逻辑单元信息
        endpoint = 'types/lun/instances'
        params = {'filter': '(type eq 2)',
                  'fields': 'health,name,sizeTotal,percentAllocated::sizeTotal eq 0 ? 0.0 : ((sizeAllocated / '
                            'sizeTotal) * 100),sizeAllocated,wwn,sizeUsed'}
        result = self.send_request(endpoint, params=params)
        if result:
            # 构造逻辑单元信息的 JSON 字符串
            return json.dumps([{
                "name": data.get("content", {}).get("name"),
                "sizeTotal": data.get("content", {}).get("sizeTotal"),
                "sizeAllocated": data.get("content", {}).get("sizeAllocated"),
                "wwn": data.get("content", {}).get("wwn"),
                "percentAllocated": data.get("content", {}).get("percentAllocated"),
                "health": data.get("content", {}).get("health", {}).get("value")
            } for data in result.get("entries", [])])
        return None
    def get_disk(self):
        # 获取物理硬盘信息
        endpoint = 'types/disk/instances'
        params = {'fields': 'health,name,diskTechnology,tierType,size,rpm'}
        result = self.send_request(endpoint, params=params)
        if result:
            # 构造物理硬盘信息的 JSON 字符串
            return json.dumps([{
                "name": data.get("content", {}).get("name"),
                "size": data.get("content", {}).get("size"),
                "rpm": data.get("content", {}).get("rpm"),
                "health": data.get("content", {}).get("health", {}).get("value")
            } for data in result.get("entries", [])])
        return None
    def execute_function(self):
        func = getattr(self, UserInput.args.mode.strip(), None)
        print(func()) if func else print("Invalid function name. Please try again.")

if __name__ == '__main__':
    EmcUnity300().execute_function()

三、脚本使用说明


    参数说明

        --ipaddress:存储系统的 IP 地址,必需参数。

        --username:用户名,默认值为 admin。

        --password:密码,默认值为空。如果未提供,则在运行时提示输入。

        --mode:操作模式,必需参数。可以是 get_system、get_pool、get_lun 或 get_disk。

运行示例


    获取系统信息:python HP_DL380_DEMO.py --ipaddress 192.168.1.100 --username admin --password mypassword --mode get_system

    获取存储池信息:python HP_DL380_DEMO.py --ipaddress 192.168.1.100 --username admin --password mypassword --mode get_pool

    获取逻辑单元信息:python HP_DL380_DEMO.py --ipaddress 192.168.1.100 --username admin --password mypassword --mode get_lun

    获取物理硬盘信息:python HP_DL380_DEMO.py --ipaddress 192.168.1.100 --username admin --password mypassword --mode get_disk

四、脚本功能解析


    UserInput 类

        解析用户输入的参数,并将其作为全局变量



如果您在开发 Python/Shell 脚本或 Zabbix 模板过程中遇到问题,或者有开发模板或脚本的需求,欢迎随时添加 QQ:1030202304,与我一起沟通交流。

0 条评论

请先 登录 后评论
我是 Rain 呀
我是 Rain 呀

系统运维工程师/DBA 工程师

4 篇文章

作家榜 »

  1. 乐维君 397 文章
  2. YOHOHO 14 文章
  3. 机灵小和尚 13 文章
  4. 我是一只小菜鸡 12 文章
  5. 细雨闲花 11 文章
  6. 。。。 9 文章
  7. 御前侍卫张五哥 9 文章
  8. 小黄人 8 文章