基于Redfish的服务器管理小应用

  • 前言
    • 关于ipmi
    • 关于Redfish
    • 关于RedfishAPI
  • 效果
    • 开发环境
    • 功能介绍
  • 技术
    • Qt样式表
    • 信号槽
    • treeWidget的使用
    • https请求及解析
    • QSlite数据库的使用
  • 参考

前言

本文介绍了近期完成的一个小项目——基于Redfish的服务器管理小应用。一方面记录一下自己的开发经历;另一方面本项目适用于准备学习样式表,信号槽,treeWidget,https请求,SQlite数据库的人。代码在最下方。

注:公司内部网络才可以访问redfish接口,项目的网络请求无法发送成功,所以关于https请求部分仅供参考,也可以参看Qt开发之路——Json解析过程中遇到的readAll()清除内存缓冲区问题~

关于ipmi

IMPI(智能平台管理接口)是一种嵌入式功能,同时也是工业标准,由英特尔与戴尔、惠普和NEC合作开发,可实现对服务器的远程控制。但是这种规范也有它的局限性,层出不穷的安全问题使得它自从2015年更新2.0后没有再翻新,与此同时Redfish兴起。

关于Redfish

Redfish是由分布式管理任务组(DMTF)发布的开放式行业标准规范,旨在对平台硬件进行现代化和安全的管理,是一种管理标准,在超媒体RESTful接口中使用数据模型表示。它是一个超媒体API,所以它能够通过一个一致的接口来表示各种实现。它有管理数据中心资源、处理事件、长期任务和发现的机制。初识Redfish

关于RedfishAPI

RedfishAPI代表了一种新的编程风格,它能够以一致的方式管理从超级规模到刀片服务器再到独立服务器的系统。

对于背景可以移步https://blog.csdn.net/asmartkiller/article/details/106558952作更细致的了解。

效果

开发环境

应用:Qt Creator 4.11.1(Community)
开发环境:MinGW_32_bit
数据库:SQlite

功能介绍

添加服务器:

初始化:删除所有服务器
帮助:简单显示服务器小助手的功能
右键刷新告警及开关机状态信息(再次请求系统信息和告警信息,即两个get请求):

右键删除服务器

技术

1、Qt样式表,信号槽
2、通过treewidget组件显示数据。
3、通过解析https请求到的JSON数据获取相对应的特征信息。
4、将数据存储在Qt自带的SQlite数据库中,方便读取和删除。

Qt样式表

因为程序比较小,且界面不多,所以样式表直接在设计器里实现的。

比如存储按钮的点击状态

QPushButton#save{border-style:outset;
font: 75 16pt "宋体";
font-weight:bold;
color:rgb(255, 170, 0);
background-color:rgba(225, 225, 225, 0);
}QPushButton#save:hover{
background-color:rgba(225, 225, 225,200);
}QPushButton#save:pressed{background-color:rgba(225, 225, 225, 200);
}

信号槽

为了便于统一管理,将信号和槽写在main函数中。主要用于界面之间的切换和值传递。

 /* + functionui from widget to addid for adding servers*/QObject::connect(w,SIGNAL(showAddId()),i,SLOT(receive_widget_addid()));/* save functionui from addid to widget for showing servers data*/QObject::connect(i,SIGNAL(showLabel(QString,QString,QString,QString,QString,QString)),w,SLOT(receive_save(QString,QString,QString,QString,QString,QString)));/* cancel functionui from addid to widget for showing widget*/QObject::connect(i,SIGNAL(showWidget()),w,SLOT(receive_addid_cancel()));/* show loading uiui from addid to loading for showing waiting process*/QObject::connect(i,SIGNAL(showLoading()),l,SLOT(receive_addid_loading()));/* close loading uiui from addid to loading for showing widget ui*/QObject::connect(i,SIGNAL(closeLoading()),l,SLOT(receive_addid_closeloading()));/* refresh realdataui from widget to addid for refreshing realdata——powerstate and serveritynum*/QObject::connect(w,SIGNAL(refresh_realtimedata(QString)),i,SLOT(receive_widget_refresh(QString)));/* refresh realdataui from addid to widget for sending realdata——powerstate and serveritynum*/QObject::connect(i,SIGNAL(send_realTimeData(QString,QString)),w,SLOT(receive_realTimeData(QString,QString)));

treeWidget的使用

添加一行

      QStringList strs;strs<<QString("******")<<QString("*********")<<QString(powerstate)<<QString(severity)<<QString("***************");//set the header to appropriate sizeQHeaderView *head=ui->treeWidget->header();head->setSectionResizeMode(QHeaderView::ResizeToContents);//add one line for treewidget,content is strsQTreeWidgetItem *strsroot = new QTreeWidgetItem(ui->treeWidget,strs);//set currentitemui->treeWidget->setCurrentItem(strsroot);

删除一行

QTreeWidgetItem *item = ui->treeWidget->currentItem();
delete(item);

删除treewidget的所有数据

//delete the treewidget for uiui->treeWidget->clear();

https请求及解析

https请求:QNetworkRequest、QNetworkAccessManager、QNetworkReply、QEventLoop

JSON解析:QJsonDocument、QJsonParseError、QJsonObject、QJsonArray、QJsonValue

主要涉及到对三种形式JSON数据的解析。涉及到3条url,这里记为url1,url2,url3。首先获取token,然后根据token和url2发送get请求先后获取产品名称,开关机状态,健康状态以及uuid。通过url3和token获取服务器告警信息。
url1及用户名密码发送post请求获取token:

QString AddId::postToken(QString id)
{// new request objectQNetworkRequest request;// ready for sending https requestQSslConfiguration config;QSslConfiguration conf = request.sslConfiguration();conf.setPeerVerifyMode(QSslSocket::VerifyNone);conf.setProtocol(QSsl::TlsV1SslV3);request.setSslConfiguration(conf);request.setUrl(QUrl("https://www.baidu.com"));request.setUrl(QUrl(id));request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));//set raw header of requestrequest.setRawHeader("Content-Type", "application/json");//check supported agreementqDebug()<< manager->supportedSchemes();//("ftp", "file", "qrc", "http", "https", "data")//obtain form data——username and passwordQString submitMsg = QString(R"({"UserName": "%1","Password": "%2"})").arg(ui->lineEdit_2->text()).arg(ui->lineEdit_3->text());QNetworkReply *reply=manager->post(request,submitMsg.toUtf8());//open a local event loop, then wait reply but do not stop thread(significant)QEventLoop eventLoop;connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);eventLoop.exec();/* for  \"X-Auth-Token\":analysis json data*/QString token = analysisSessionsJson(reply);return token;

得到如下形式的JSON数据:

{"@odata.context": "/redfish/v1/$metadata#Session.Session","@odata.id": "/redfish/v1/****/*********","@odata.type": "#Session.*****.Session","Id": "********","Name": "User Session","Description": "Manager User Session","UserName": "****","SessionType": "Redfish","Oem": {"BMC": {"LoginTime": "2021-01-04T11:30:51+08:00\n","ClientAddress": "****","ServerAddress": "id","SessionId": "*****","EnabledHttps": true,"Role": "Administrator","Location": "/redfish/v1/*****/*************","X-Auth-Token": "lhe6Gqi4Lz2CA7rx15vc0IRNh22iz4Vb","UserId": 2}}
}

解析获取认证X-Token

/*analysis SessionsJson for token
url1
*/
QString AddId::analysisSessionsJson(QNetworkReply *reply){//judge if format of the json is rightif (reply->error() == QNetworkReply::NoError){QByteArray bytes = reply->readAll(); //read all bytesQJsonParseError jsonError_login;//switch to json documentQJsonDocument document = QJsonDocument::fromJson(bytes, &jsonError_login);//analysis Json  errorif (document.isObject()){QJsonObject obj = document.object();if (obj.contains("Oem")){QJsonObject object_value = obj.value("Oem").toObject();if (object_value.contains("BMC")){QJsonObject object1_value = object_value.value("BMC").toObject();if(object1_value.contains("X-Auth-Token")){QString token_val = object1_value.value("X-Auth-Token").toString();return token_val;}}}}}
}

url2及token发送get请求获取系统信息:

QStringList AddId::getCriticalMsg(QString url,QString token)
{QNetworkRequest request;QSslConfiguration config;QSslConfiguration conf = request.sslConfiguration();conf.setPeerVerifyMode(QSslSocket::VerifyNone);conf.setProtocol(QSsl::TlsV1SslV3);request.setSslConfiguration(conf);request.setUrl(QUrl("https://www.baidu.com"));//set url and xAuthTokenrequest.setUrl(QUrl(url));request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");request.setRawHeader(QByteArray("X-Auth-Token"),QByteArray(token.toUtf8()));QNetworkReply *systeminfo = manager->get(request);//if no below three codes,will first run the latter code after QNetworkReply *systeminfo = manager->get(request);then to run replyQEventLoop eventLoop;connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);eventLoop.exec();QStringList criticalstr = analysisSystemJson(systeminfo);return criticalstr;
}

得到如下形式的JSON数据:

{"@odata.context": "/redfish/v1/$metadata#ComputerSystem.ComputerSystem","@odata.id": "/redfish/v1/******","@odata.type": "#ComputerSystem.ComputerSystem","Id": "1","Name": "Computer System","Actions": {"ResetType@Redfish.AllowableValues": ["On","ForceOff","ForceRestart","GracefulShutdown","ForcePowerCycle","Nmi"],"target": "/redfish/v1/*******"},"AssetTag": "******","Manufacturer": "********","Model": "********","SerialNumber": "********","PartNumber": "********","HostingRole": "ApplicationServer","SystemType": "Physical","UUID": "4********","HostName": "********","PowerState": "On","PowerRestorePolicyTypes": "LastState","IndicatorLED": "Off","BIOSVersion": "********","Status": {"State": "Enabled","Health": "OK"}
}

解析得到Manufacturer,PowerState,UUID,Health

/*analysis processing*url2
for product name,state of on or off,warnings num,GUID*/
QStringList AddId::analysisSystemJson(QNetworkReply *sys){QStringList criticalstr;if (sys->error() == QNetworkReply::NoError){QByteArray bytes = sys->readAll();QJsonParseError jsonError_system;QJsonDocument document = QJsonDocument::fromJson(bytes, &jsonError_system);if (document.isObject()){QJsonObject obj = document.object();if (obj.contains("Manufacturer")) {QString manufacturer = obj.value("Manufacturer").toString();criticalstr.append(manufacturer);qDebug() << manufacturer;}if (obj.contains("PowerState")) {QString powerstate = obj.value("PowerState").toString();criticalstr.append(powerstate);qDebug() << powerstate;}if (obj.contains("UUID")) {QString uuid = obj.value("UUID").toString();criticalstr.append(uuid);qDebug() << uuid;}if (obj.contains("Status")){QJsonObject object_value = obj.value("Status").toObject();if (object_value.contains("Health")){QString health = object_value.value("Health").toString();criticalstr.append(health);qDebug() << health;}}}}
}

通过url3和token发送get请求获取告警率:

QString AddId::getSeverityMsg(QString url,QString token)
{QNetworkRequest request;QSslConfiguration config;QSslConfiguration conf = request.sslConfiguration();conf.setPeerVerifyMode(QSslSocket::VerifyNone);conf.setProtocol(QSsl::TlsV1SslV3);request.setSslConfiguration(conf);request.setUrl(QUrl("https://www.baidu.com"));//set url and xAuthTokenrequest.setUrl(QUrl(url));request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");request.setRawHeader(QByteArray("X-Auth-Token"),QByteArray(token.toUtf8()));QNetworkReply *logserverinfo = manager->get(request);//if no below three codes,will first run the latter code after QNetworkReply *systeminfo = manager->get(request);then to run replyQEventLoop eventLoop;connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);eventLoop.exec();QString healthrate = analysisLogServerJson(logserverinfo);return healthrate;
}

得到如下形式的JSON数据:

{"@odata.context": "/redfish/v1/******","@odata.id": "redfish/v1/******","@odata.type": "#LogEntryCollection.LogEntryCollection","Description": "Collection of entries for this log service","Name": "Log Service Entries Collection","Members@odata.count": 24,"Members": [{"@odata.id": "/redfish/v1/******/24","Id": "24","Name": "Log Entry 24","EntryType": "******","SensorNumber": 186,"Created": "2021-01-04T07:14:12","EventTimestamp": "2021-01-04T07:14:12","Severity": "Ok","EntryCode": "Assert","SensorType": "******/Interconnect","Message": "******/Interconnect is connected"},{"@odata.id": "/redfish/v1/******","Id": "23","Name": "Log Entry 23","EntryType": "SEL","SensorNumber": 184,"Created": "2021-01-04T07:14:12","EventTimestamp": "2021-01-04T07:14:12","Severity": "Ok","EntryCode": "Assert","SensorType": "******/Interconnect","Message": "******/Interconnect is connected"},...........]
}

解析获得Severity = ok的数量和 不等于ok(严重告警)的数量。

/*get request*https://id/redfish/v1/Systems
for product name,state of on or off,warnings num,GUID*/
QString AddId::analysisLogServerJson(QNetworkReply *logserver){int serveritynum = 0;int healthnum = 0;qint32 logcount = 0;if (logserver->error() == QNetworkReply::NoError){QByteArray bytes = logserver->readAll();QJsonParseError jsonError_logserver;QJsonDocument document = QJsonDocument::fromJson(bytes, &jsonError_logserver);if (document.isObject()){QJsonObject obj = document.object();if (obj.contains("Members@odata.count")){//note that value for "Members@odata.count" is not a stringlogcount = obj.value("Members@odata.count").toInt();}if (obj.contains("Members")){QJsonValue members = obj.value("Members");//the value of members is a arrayif(members.isArray()){for(int i = 0;i< logcount;i++){QJsonObject members_obj = members.toArray().at(i).toObject();if(members_obj.contains("Severity")){QString status_value = members_obj.value("Severity").toString();if(!(status_value == "Ok")){serveritynum +=1;}else{healthnum +=1;}}}}}}}

QSlite数据库的使用

QSqlDatabase、QSqlQuery、QSqlError、QSqlTableModel

Qt开发之路——SQlite的使用(简单粗暴)

github:https://github.com/hqy7777/SMS-Based-On-Redfish-Qt

参考

Qt开发之路——Json解析过程中遇到的readAll()清除内存缓冲区问题
Qt开发之路——SQlite的使用(简单粗暴)

欢迎讨论交流~

Qt开发之路——基于RedfishAPI的服务器管理小应用相关推荐

  1. 小程序·云开发实战:SCRM社交化客户管理小程序

    点击观看大咖分享 随着微信小程序不断发展壮大,传统的 CRM 厂商也在不断向微信上迁移,毕竟微信的背后是巨大的用户和流量,还有极其方便的移动支付渠道.用微信小程序来做CRM,和以前的做法存在一些比较明 ...

  2. 基于NodeJS健身房会员管理小程序的设计与实现

    随着社会的发展,社会的各行各业都在利用信息化时代的优势.计算机的优势和普及使得各种信息系统的开发成为必需. 健身房会员管理系统,主要的模块包括首页.个人中心.会员管理.教练管理.场地信息管理.课程信息 ...

  3. Qt网络程序:基于TCP的服务器、客户端实例

    首先我们需要设置服务器:  项目文件中加入:QT += network  相关头文件: #include<QTcpServer>//监听套接字 #include<QTcpSocket ...

  4. 我的嵌入式Qt开发第一课——基于BBB和hmc5843三轴电子罗盘

    几次想照着课本系统地学习Qt,但我发现还是有详细问题驱动时学习比較快. 于是我给自己设定了这个任务: 读取HMC5843的三轴磁场强度值,计算出角度,并把角度用直观形式显示在图形界面上. 这里面涉及到 ...

  5. Qt开发之路——Sleep函数

    #include <synchapi.h> synchapi.h是Qt自带的头文件 Sleep(1000);延迟1s sleep函数的线程休眠,线程主动放弃时间片,不能用作计时,只能起到延 ...

  6. Qt开发之路——整型与字符串 int与QString互转

    ( 1)QString转int 直接调用toInt()函数 代码: QString str; int tmp = str.toInt(); 2)int转QString 方法一:用QString的arg ...

  7. html游戏开发开题报告,基于H5 网页的打豆豆小游戏的设计与实现毕业论文+开题报告+设计源码...

    摘  要 网页游戏是一个用现实包装的快感反馈引擎,它的根本目的始终是让玩家能够得到舒畅的体验为了娱乐心神,所以开发出大家喜欢的,高品质的休闲游戏会受到人们的普遍欢迎.打豆豆小游戏这款游戏主要是利用cs ...

  8. 漫漫运维路——基于CentOS6平台软件包管理2

    上文(http://7703592.blog.51cto.com/7693592/1631539)已经介绍过使用rpm对CentOS6上的软件包进行管理,之所以强调是在CentOS6之上,是因为在新出 ...

  9. python搭建qt开发环境_QT开发环境搭建(Windows)

    正式启航踏上Qt开发之路 遇到的第一个难题,搭环境 我本来是准备装个虚拟机在Ubuntu上开发,搞了一天好像生成不了可执行文件,就决定从Windows先装个试试 下面是我的步骤和安装过程中遇到的一些小 ...

  10. Qt安装—图文并茂搭建VS2008/2010+QT开发环境

    VS2008: (一)工欲善其事,必先利其器,废话不多讲. 总结起来网上流行的VS2008+QT安装说明有以下几个问题需要解释清楚:      1,首先明确需要下载什么版本的QT.网上流行的安装说明只 ...

最新文章

  1. 教你如何处理Nginx禁止ip加端口访问的问题
  2. R语言威布尔分布函数F Distribution(dweibull, pweibull, qweibull rweibull )实战
  3. 【Python】如何学好Python
  4. Cpp 对象模型探索 / 程序转化语义
  5. Python 标准库 —— uuid(生成唯一 ID)
  6. navicat 只对比一张表的数据_Excel VBA批量新建工作表(对比数据透视表的使用)...
  7. VMware安装VMwaretools
  8. shell sed 替代1
  9. 栾川一高2021高考成绩查询,2017栾川一高录取分数线(附2017高考成绩喜报)
  10. [Alpha阶段]第二次Scrum Meeting
  11. 10 使用ViewPager实现导航
  12. Qt qtextstream读取文件
  13. C#通过LPT控制打印机——txt文档读取指令打印条码
  14. 线性代数笔记(5) 矩阵多项式的运用——哈密顿-凯莱定理
  15. 什么是单页面应用SPA?和多页面应用的区别?
  16. hcia hdcp实验
  17. SAS硬盘优缺点概述
  18. Linux命令总结归纳
  19. VAD检测原理及其过程
  20. cad渐开线齿轮轮廓绘制_CAD画齿轮的方法

热门文章

  1. EDIUS5.5快捷键大全
  2. 计算机博弈程序python_程序员大神们的经典编程语录
  3. C语言程序设计----C语言基础知识
  4. 共轭梯度法python实现
  5. 《keras中文文档》资料分享
  6. 微星z370安装linux系统,微星z370主板装win7及BIOS设置详细教程
  7. fanuc系统服务器连接,FANUC IO LINK i地址分配操作方法
  8. 正则表达式,js表单验证
  9. MATLAB拟合算法
  10. NS方程求解-NSFnet