parent
5211cdd4c0
commit
cf8a0efd0d
3 changed files with 165 additions and 4 deletions
|
@ -17,6 +17,9 @@ namespace
|
|||
constexpr char container[] = "container";
|
||||
constexpr char userData[] = "userData";
|
||||
constexpr char creationDate[] = "creationDate";
|
||||
constexpr char latestHandshake[] = "latestHandshake";
|
||||
constexpr char dataReceived[] = "dataReceived";
|
||||
constexpr char dataSent[] = "dataSent";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,6 +46,9 @@ QVariant ClientManagementModel::data(const QModelIndex &index, int role) const
|
|||
switch (role) {
|
||||
case ClientNameRole: return userData.value(configKey::clientName).toString();
|
||||
case CreationDateRole: return userData.value(configKey::creationDate).toString();
|
||||
case LatestHandshakeRole: return userData.value(configKey::latestHandshake).toString();
|
||||
case DataReceivedRole: return userData.value(configKey::dataReceived).toString();
|
||||
case DataSentRole: return userData.value(configKey::dataSent).toString();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
|
@ -112,6 +118,38 @@ ErrorCode ClientManagementModel::updateModel(const DockerContainer container, co
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<WgShowData> data;
|
||||
wgShow(container, credentials, serverController, data);
|
||||
|
||||
for (const auto &client : data) {
|
||||
int i = 0;
|
||||
for (const auto &it : std::as_const(m_clientsTable)) {
|
||||
if (it.isObject()) {
|
||||
QJsonObject obj = it.toObject();
|
||||
if (obj.contains(configKey::clientId) && obj[configKey::clientId].toString() == client.clientId) {
|
||||
QJsonObject userData = obj[configKey::userData].toObject();
|
||||
|
||||
if (!client.latestHandshake.isEmpty()) {
|
||||
userData[configKey::latestHandshake] = client.latestHandshake;
|
||||
}
|
||||
|
||||
if (!client.dataReceived.isEmpty()) {
|
||||
userData[configKey::dataReceived] = client.dataReceived;
|
||||
}
|
||||
|
||||
if (!client.dataSent.isEmpty()) {
|
||||
userData[configKey::dataSent] = client.dataSent;
|
||||
}
|
||||
|
||||
obj[configKey::userData] = userData;
|
||||
m_clientsTable.replace(i, obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
return error;
|
||||
}
|
||||
|
@ -195,6 +233,71 @@ ErrorCode ClientManagementModel::getWireGuardClients(const DockerContainer conta
|
|||
return error;
|
||||
}
|
||||
|
||||
ErrorCode ClientManagementModel::wgShow(const DockerContainer container, const ServerCredentials &credentials,
|
||||
const QSharedPointer<ServerController> &serverController, std::vector<WgShowData> &data)
|
||||
{
|
||||
if (container != DockerContainer::WireGuard && container != DockerContainer::Awg) {
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode error = ErrorCode::NoError;
|
||||
QString stdOut;
|
||||
auto cbReadStdOut = [&](const QString &data, libssh::Client &) {
|
||||
stdOut += data + "\n";
|
||||
return ErrorCode::NoError;
|
||||
};
|
||||
|
||||
const QString command = QString("sudo docker exec -i $CONTAINER_NAME bash -c '%1'").arg("wg show all");
|
||||
|
||||
QString script = serverController->replaceVars(command, serverController->genVarsForScript(credentials, container));
|
||||
error = serverController->runScript(credentials, script, cbReadStdOut);
|
||||
if (error != ErrorCode::NoError) {
|
||||
logger.error() << "Failed to execute wg show command";
|
||||
return error;
|
||||
}
|
||||
|
||||
if (stdOut.isEmpty()) {
|
||||
return error;
|
||||
}
|
||||
|
||||
const auto getStrValue = [](const auto str) { return str.mid(str.indexOf(":") + 1).trimmed(); };
|
||||
|
||||
const auto parts = stdOut.split('\n');
|
||||
const auto peerList = parts.filter("peer:");
|
||||
const auto latestHandshakeList = parts.filter("latest handshake:");
|
||||
const auto transferredDataList = parts.filter("transfer:");
|
||||
|
||||
if (latestHandshakeList.isEmpty() || transferredDataList.isEmpty() || peerList.isEmpty()) {
|
||||
return error;
|
||||
}
|
||||
|
||||
const auto changeHandshakeFormat = [](QString &latestHandshake) {
|
||||
const std::vector<std::pair<QString, QString>> replaceMap = { { " days", "d" }, { " hours", "h" }, { " minutes", "m" },
|
||||
{ " seconds", "s" }, { " day", "d" }, { " hour", "h" },
|
||||
{ " minute", "m" }, { " second", "s" } };
|
||||
|
||||
for (const auto &item : replaceMap) {
|
||||
latestHandshake.replace(item.first, item.second);
|
||||
}
|
||||
};
|
||||
|
||||
for (int i = 0; i < peerList.size() && i < transferredDataList.size(); ++i) {
|
||||
const auto transferredData = getStrValue(transferredDataList[i]).split(",");
|
||||
auto latestHandshake = getStrValue(latestHandshakeList[i]);
|
||||
auto bytesReceived = transferredData.front().trimmed();
|
||||
auto bytesSent = transferredData.back().trimmed();
|
||||
|
||||
changeHandshakeFormat(latestHandshake);
|
||||
|
||||
bytesReceived.chop(QStringLiteral(" received").length());
|
||||
bytesSent.chop(QStringLiteral(" sent").length());
|
||||
|
||||
data.push_back({ getStrValue(peerList[i]), latestHandshake, bytesReceived, bytesSent });
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
bool ClientManagementModel::isClientExists(const QString &clientId)
|
||||
{
|
||||
for (const QJsonValue &value : std::as_const(m_clientsTable)) {
|
||||
|
@ -486,5 +589,8 @@ QHash<int, QByteArray> ClientManagementModel::roleNames() const
|
|||
QHash<int, QByteArray> roles;
|
||||
roles[ClientNameRole] = "clientName";
|
||||
roles[CreationDateRole] = "creationDate";
|
||||
roles[LatestHandshakeRole] = "latestHandshake";
|
||||
roles[DataReceivedRole] = "dataReceived";
|
||||
roles[DataSentRole] = "dataSent";
|
||||
return roles;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,18 @@ class ClientManagementModel : public QAbstractListModel
|
|||
public:
|
||||
enum Roles {
|
||||
ClientNameRole = Qt::UserRole + 1,
|
||||
CreationDateRole
|
||||
CreationDateRole,
|
||||
LatestHandshakeRole,
|
||||
DataReceivedRole,
|
||||
DataSentRole
|
||||
};
|
||||
|
||||
struct WgShowData
|
||||
{
|
||||
QString clientId;
|
||||
QString latestHandshake;
|
||||
QString dataReceived;
|
||||
QString dataSent;
|
||||
};
|
||||
|
||||
ClientManagementModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||
|
@ -57,6 +68,9 @@ private:
|
|||
ErrorCode getWireGuardClients(const DockerContainer container, const ServerCredentials &credentials,
|
||||
const QSharedPointer<ServerController> &serverController, int &count);
|
||||
|
||||
ErrorCode wgShow(const DockerContainer container, const ServerCredentials &credentials,
|
||||
const QSharedPointer<ServerController> &serverController, std::vector<WgShowData> &data);
|
||||
|
||||
QJsonArray m_clientsTable;
|
||||
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
|
|
|
@ -766,9 +766,9 @@ PageType {
|
|||
}
|
||||
|
||||
anchors.fill: parent
|
||||
expandedHeight: root.height * 0.5
|
||||
|
||||
expandedContent: ColumnLayout {
|
||||
id: expandedContent
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
@ -778,6 +778,10 @@ PageType {
|
|||
|
||||
spacing: 8
|
||||
|
||||
onImplicitHeightChanged: {
|
||||
clientInfoDrawer.expandedHeight = expandedContent.implicitHeight + 32
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: clientInfoDrawer
|
||||
enabled: !GC.isMobile()
|
||||
|
@ -788,10 +792,47 @@ PageType {
|
|||
|
||||
Header2Type {
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
headerText: clientName
|
||||
descriptionText: qsTr("Creation date: ") + creationDate
|
||||
}
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
id: textColumn
|
||||
property string textColor: "#878B91"
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
ParagraphTextType {
|
||||
color: textColumn.textColor
|
||||
visible: creationDate
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Creation date: %1").arg(creationDate)
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
color: textColumn.textColor
|
||||
visible: latestHandshake
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Latest handshake: %1").arg(latestHandshake)
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
color: textColumn.textColor
|
||||
visible: dataReceived
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Data received: %1").arg(dataReceived)
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
color: textColumn.textColor
|
||||
visible: dataSent
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Data sent: %1").arg(dataSent)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue