├── .editorconfig ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── feature_request.yml ├── .gitignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── 3rd-party-licenses.md ├── Build.ps1 ├── CODE_OF_CONDUCT.md ├── Corsinvest.ProxmoxVE.Admin.sln ├── Corsinvest.ProxmoxVE.Admin.sln.licenseheader ├── Initialize-Tools.ps1 ├── Invoke-Utils.ps1 ├── LICENSE ├── README.md ├── icon.png └── src ├── Corsinvest.ProxmoxVE.Admin.AutoSnap ├── Components │ ├── Histories.razor │ ├── Histories.razor.cs │ ├── Hooks.razor │ ├── Hooks.razor.cs │ ├── Jobs.razor │ ├── Jobs.razor.cs │ ├── RenderIndex.razor │ ├── RenderOptions.razor │ ├── RenderWidget.razor │ ├── RenderWidget.razor.cs │ ├── RenderWidgetInfo.razor │ ├── RenderWidgetInfo.razor.cs │ ├── Status.razor │ ├── Status.razor.cs │ ├── Timeline.razor │ └── Timeline.razor.cs ├── Corsinvest.ProxmoxVE.Admin.AutoSnap.csproj ├── Helper.cs ├── Job.cs ├── Migrations │ ├── 20230407173026_Initial.Designer.cs │ ├── 20230407173026_Initial.cs │ └── AutoSnapDbContextModelSnapshot.cs ├── Models │ ├── AutoSnapInfo.cs │ ├── AutoSnapJob.cs │ ├── AutoSnapJobHistory.cs │ ├── AutoSnapJobHook.cs │ └── AutoSnapJobHookHttpMethod.cs ├── Module.cs ├── Notify.cs ├── Options.cs ├── Persistence │ └── AutoSnapDbContext.cs ├── Repository │ ├── AutoSnapJobHistorySpec.cs │ └── AutoSnapJobSpec.cs ├── SearchMode.cs ├── TextFile1.txt ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.Botgram ├── BotgramService.cs ├── Components │ ├── RenderIndex.razor │ ├── RenderIndex.razor.cs │ ├── RenderOptions.razor │ ├── RenderWidget.razor │ └── RenderWidget.razor.cs ├── Corsinvest.ProxmoxVE.Admin.Botgram.csproj ├── Module.cs ├── Options.cs ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.ClusterStatus ├── Components │ ├── RenderIndex.razor │ ├── RenderIndex.razor.cs │ ├── RenderOptions.razor │ ├── RenderWidget1.razor │ ├── RenderWidget1.razor.cs │ ├── WidgetCluster │ │ ├── RenderWidgetCpu.razor │ │ ├── RenderWidgetMemory.razor │ │ ├── RenderWidgetStorage.razor │ │ ├── WidgetBase.razor │ │ └── WidgetBase.razor.cs │ └── WidgetInfo │ │ ├── RenderWidgetInfoBackups.razor │ │ ├── RenderWidgetInfoClusterStatus.razor │ │ ├── RenderWidgetInfoNodesOnlines.razor │ │ ├── RenderWidgetInfoNodesTasks.razor │ │ └── RenderWidgetInfoNodesUpdates.razor ├── Corsinvest.ProxmoxVE.Admin.ClusterStatus.csproj ├── Module.cs ├── Options.cs ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.ClusterUsage ├── Components │ ├── Costs.razor │ ├── Costs.razor.cs │ ├── RenderIndex.razor │ ├── RenderOptions.razor │ ├── RenderOptions.razor.cs │ ├── RenderSettingClusterStorage.razor │ ├── RenderSettingClusterStorage.razor.cs │ ├── Storages.razor │ ├── Storages.razor.cs │ ├── Vms.razor │ └── Vms.razor.cs ├── Corsinvest.ProxmoxVE.Admin.ClusterUsage.csproj ├── Helper.cs ├── Job.cs ├── Migrations │ ├── 20230414124704_Initial.Designer.cs │ ├── 20230414124704_Initial.cs │ └── ClusterUsageDbContextModelSnapshot.cs ├── Models │ ├── DataVm.cs │ └── DataVmStorage.cs ├── Module.cs ├── Options.cs ├── Persistence │ └── ClusterUsageDbContext.cs ├── Repository │ └── DataVmSpec.cs ├── StorageOptions.cs ├── TextFile1.txt ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.Core ├── Corsinvest - Backup.ProxmoxVE.Admin.Core.csproj ├── Corsinvest.ProxmoxVE.Admin.Core.csproj ├── Extensions │ ├── EnumerableExtension.cs │ ├── JobExtension.cs │ ├── QueryableExtension.cs │ ├── ServiceScopeExtension.cs │ └── StringExtension.cs ├── Helpers │ ├── JobHelper.cs │ ├── PveAdminExtensions.cs │ ├── PveAdminHelper.cs │ ├── PveBlazorHelper.cs │ ├── SshHelper.cs │ └── StringWriterEvent.cs ├── Models │ ├── ClusterResourceVmExtraInfo.cs │ ├── IName.cs │ ├── INode.cs │ ├── ISnapshotsSize.cs │ ├── IVmId.cs │ ├── ResourceUsage.cs │ └── ThresholdPercentual.cs ├── Modularity │ ├── AdminModuleCategory.cs │ └── PveAdminModuleBase.cs ├── ModuleCore.cs ├── Options │ ├── AdminOptions.cs │ ├── ClusterNodeOptions.cs │ ├── ClusterOptions.cs │ ├── Module.cs │ ├── RenderAdminOptions.razor │ ├── RenderAdminOptions.razor.cs │ ├── RenderApiLoginOptions.razor │ ├── RenderClustersOptions.razor │ ├── RenderClustersOptions.razor.cs │ ├── RenderContactOptions.razor │ ├── RenderNodesOptions.razor │ ├── RenderNodesOptions.razor.cs │ └── RenderSshLoginOptions.razor ├── README.MD ├── Repository │ ├── ClusterByNameSpec.cs │ └── IClusterName.cs ├── Services │ ├── DiskInfo │ │ ├── CephDiskInfo.cs │ │ ├── DiskInfoBase.cs │ │ └── ZfsDiskInfo.cs │ ├── IPveClientService.cs │ ├── IPveUtilityService.cs │ ├── ISshService.cs │ ├── PveClientService.cs │ ├── PveUtilityService.cs │ └── SshService.cs ├── Support │ ├── Buy │ │ └── Module.cs │ ├── RequestSupport │ │ ├── Module.cs │ │ ├── RenderSupport.razor │ │ └── RenderSupport.razor.cs │ └── Subscription │ │ ├── Helper.cs │ │ ├── Info.cs │ │ ├── Module.cs │ │ ├── RenderIndex.razor │ │ ├── RenderIndex.razor.cs │ │ └── Status.cs ├── UI │ ├── Components │ │ ├── InfoCalculateSnapshots.razor │ │ └── InfoScheduler.razor │ ├── Dialogs │ │ ├── DialogFastConfig.razor │ │ └── DialogFastConfig.razor.cs │ ├── Layout │ │ ├── PveWidgets.razor │ │ ├── PveWidgets.razor.cs │ │ ├── SelectCluster.razor │ │ ├── SelectCluster.razor.cs │ │ ├── WidgetInfoBase.razor │ │ └── WidgetInfoBase.razor.cs │ ├── Options │ │ ├── PveModuleClustersOptions.cs │ │ ├── PveOptionsModuleRender.razor │ │ ├── PveOptionsModuleRender.razor.cs │ │ └── ThresholdPercentageOptions.razor │ └── ProxmoxVE │ │ ├── Cluster │ │ ├── ClusterSelector.razor │ │ ├── ClusterSelector.razor.cs │ │ ├── DisksNotBackedUp.razor │ │ ├── DisksNotBackedUp.razor.cs │ │ ├── Logs.razor │ │ ├── Logs.razor.cs │ │ ├── Resources.razor │ │ ├── Resources.razor.cs │ │ ├── Snapshots.razor │ │ ├── Summary.razor │ │ └── Summary.razor.cs │ │ ├── Common │ │ ├── IconStatusResource.razor │ │ ├── IconStatusResource.razor.cs │ │ ├── Tasks.razor │ │ └── Tasks.razor.cs │ │ ├── Nodes │ │ ├── StorageContents.razor │ │ ├── StorageContents.razor.cs │ │ ├── StorageUsage.razor │ │ └── StorageUsage.razor.cs │ │ ├── Storage │ │ ├── Storages.razor │ │ └── Storages.razor.cs │ │ └── Vm │ │ ├── BackupFileRestore.razor │ │ ├── BackupFileRestore.razor.cs │ │ ├── BackupsManager.razor │ │ ├── BackupsManager.razor.cs │ │ ├── Chart.razor │ │ ├── Chart.razor.cs │ │ ├── Charts.razor │ │ ├── Charts.razor.cs │ │ ├── Detail.razor │ │ ├── Detail.razor.cs │ │ ├── SnapshotManager.razor │ │ ├── SnapshotManager.razor.cs │ │ ├── ToolBarStatus.razor │ │ ├── ToolBarStatus.razor.cs │ │ ├── VmChart.cs │ │ ├── VmManager.razor │ │ └── VmManager.razor.cs ├── _Import.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.Diagnostic ├── Components │ ├── Detail.razor │ ├── Detail.razor.cs │ ├── Issues.razor │ ├── Issues.razor.cs │ ├── RenderIndex.razor │ ├── RenderOptions.razor │ ├── RenderOptions.razor.cs │ ├── RenderWidget.razor │ ├── RenderWidget.razor.cs │ ├── Results.razor │ └── Results.razor.cs ├── Corsinvest.ProxmoxVE.Admin.Diagnostic.csproj ├── Doc.txt ├── Helper.cs ├── Job.cs ├── Migrations │ ├── 20230411155801_Initial.Designer.cs │ ├── 20230411155801_Initial.cs │ └── DiagnosticDbContextModelSnapshot.cs ├── Models │ ├── Execution.cs │ ├── ExecutionData.cs │ └── IgnoredIssue.cs ├── Module.cs ├── Options.cs ├── Persistence │ └── DiagnosticDbContext.cs ├── Repository │ ├── ExecutionSpec.cs │ └── IgnoredIssueSpec.cs ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.DisksStatus ├── Components │ ├── DiskSmarts.razor │ ├── DiskSmarts.razor.cs │ ├── DisksList.razor │ ├── DisksList.razor.cs │ ├── RenderIndex.razor │ └── RenderIndex.razor.cs ├── Corsinvest.ProxmoxVE.Admin.DisksStatus.csproj ├── Module.cs ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.MetricsExporter ├── Components │ ├── RenderIndex.razor │ ├── RenderOptions.razor │ └── RenderWidget.razor ├── Corsinvest.ProxmoxVE.Admin.MetricsExporter.csproj ├── Info.cs ├── Module.cs ├── Options.cs ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.NodeFreeMemory ├── Corsinvest.ProxmoxVE.Admin.NodeFreeMemory.csproj ├── Module.cs ├── RenderIndex.razor ├── RenderIndex.razor.cs ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.NodeProtect ├── Components │ ├── RenderIndex.razor │ ├── RenderIndex.razor.cs │ ├── RenderOptions.razor │ ├── RenderOptions.razor.cs │ ├── Widget.razor │ └── Widget.razor.cs ├── Corsinvest.ProxmoxVE.Admin.NodeProtect.csproj ├── Doc.txt ├── Helper.cs ├── Job.cs ├── Migrations │ ├── 20230405161700_Initial.Designer.cs │ ├── 20230405161700_Initial.cs │ └── NodeProtectDbContextModelSnapshot.cs ├── Models │ └── NodeProtectJobHistory.cs ├── Module.cs ├── Options.cs ├── Persistence │ └── NodeProtectDbContext.cs ├── Repository │ └── NodeProtectJobHistorySpec.cs ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.QemuMonitor ├── Corsinvest.ProxmoxVE.Admin.QemuMonitor.csproj ├── Module.cs ├── RenderIndex.razor ├── RenderIndex.razor.cs ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.ReplicationTrend ├── Components │ ├── ClusterReplications.razor │ ├── ClusterReplications.razor.cs │ ├── DataAnalysis.razor │ ├── DataAnalysis.razor.cs │ ├── Jobs.razor │ ├── Jobs.razor.cs │ ├── RenderIndex.razor │ ├── RenderOptions.razor │ ├── RenderOptions.razor.cs │ ├── RenderWidget.razor │ └── RenderWidget.razor.cs ├── Corsinvest.ProxmoxVE.Admin.ReplicationTrend.csproj ├── Doc.txt ├── Helper.cs ├── Job.cs ├── Migrations │ ├── 20230519165629_Initial.Designer.cs │ ├── 20230519165629_Initial.cs │ └── ReplicationTrendDbContextModelSnapshot.cs ├── Models │ └── ReplicationResult.cs ├── Module.cs ├── Options.cs ├── Persistence │ └── ReplicationTrendDbContext.cs ├── Repository │ └── ReplicationResultSpec.cs ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.VmUnlock ├── Corsinvest.ProxmoxVE.Admin.VmUnlock.csproj ├── Helper.cs ├── Module.cs ├── RenderIndex.razor ├── RenderIndex.razor.cs ├── Widget.razor ├── Widget.razor.cs ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin.VzDumpTrend ├── Components │ ├── ClusterBackups.razor │ ├── ClusterBackups.razor.cs │ ├── DataAnalysis.razor │ ├── DataAnalysis.razor.cs │ ├── Jobs.razor │ ├── Jobs.razor.cs │ ├── RenderIndex.razor │ ├── RenderIndex.razor.cs │ ├── RenderOptions.razor │ ├── RenderOptions.razor.cs │ ├── RenderWidget.razor │ └── RenderWidget.razor.cs ├── Corsinvest.ProxmoxVE.Admin.VzDumpTrend.csproj ├── Doc.txt ├── Helper.cs ├── Job.cs ├── LICENSE.md ├── Migrations │ ├── 20230412162204_Initial.Designer.cs │ ├── 20230412162204_Initial.cs │ └── VzDumpTrendDbContextModelSnapshot.cs ├── Models │ ├── VzDumpDetail.cs │ └── VzDumpTask.cs ├── Module.cs ├── Options.cs ├── Persistence │ └── VzDumpTrendDbContext.cs ├── Repository │ ├── VzDumpDetailSpec.cs │ └── VzDumpTaskSpec.cs ├── _Imports.cs └── _Imports.razor ├── Corsinvest.ProxmoxVE.Admin ├── Corsinvest.ProxmoxVE.Admin.csproj ├── Emailing │ └── Templates │ │ ├── Layout.tpl │ │ └── Message.tpl ├── Info.MD ├── Migrations │ ├── 20230426184027_Initail.Designer.cs │ ├── 20230426184027_Initail.cs │ └── ApplicationDbContextModelSnapshot.cs ├── Pages │ └── _Host.cshtml ├── Persistence │ └── ApplicationDbContext.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── Security │ └── Identity │ │ └── EmailTemplates │ │ ├── ConfirmRegistration.tpl │ │ └── ResetPassword.tpl ├── ServiceCollectionExtensions.cs ├── _Imports.razor ├── appsettings.Default.json ├── appsettings.Development.json ├── libman.json └── wwwroot │ ├── android-chrome-192x192.png │ ├── android-chrome-512x512.png │ ├── apple-touch-icon.png │ ├── doc │ ├── commands.adoc │ ├── cron.adoc │ ├── faq.adoc │ ├── gui.adoc │ ├── images │ │ ├── favicon.ico │ │ ├── screenshot │ │ │ ├── login │ │ │ │ └── loginadm.png │ │ │ ├── modules │ │ │ │ ├── administration │ │ │ │ │ └── modules-administration.png │ │ │ │ ├── autosnap │ │ │ │ │ ├── in-errors.png │ │ │ │ │ ├── job-history.png │ │ │ │ │ ├── job-status.png │ │ │ │ │ ├── modules-safe-autosnap-conf.png │ │ │ │ │ ├── modules-safe-autosnap-hook-conf.png │ │ │ │ │ ├── modules-safe-autosnap.png │ │ │ │ │ ├── task-new-edit.png │ │ │ │ │ ├── tasks-status.png │ │ │ │ │ ├── tasks.png │ │ │ │ │ └── time-line.png │ │ │ │ ├── botgram │ │ │ │ │ ├── modules-control-telegrambot-mobile-ok.png │ │ │ │ │ └── modules-control-telegrambot-ok.png │ │ │ │ ├── cluster-usage │ │ │ │ │ ├── by-costs1.png │ │ │ │ │ ├── by-costs2.png │ │ │ │ │ ├── by-costs3.png │ │ │ │ │ ├── by-storage.png │ │ │ │ │ ├── by-vm.png │ │ │ │ │ └── configurations.png │ │ │ │ ├── diagnostic │ │ │ │ │ ├── issues.png │ │ │ │ │ ├── modules-health-diag.png │ │ │ │ │ └── results.png │ │ │ │ ├── disks-status │ │ │ │ │ ├── disks.png │ │ │ │ │ ├── nodes.png │ │ │ │ │ └── smart.png │ │ │ │ ├── home │ │ │ │ │ ├── home-computerscreen.png │ │ │ │ │ └── homepage.png │ │ │ │ ├── metrics-exporter │ │ │ │ │ └── data.png │ │ │ │ ├── node-free-memory │ │ │ │ │ └── nodes.png │ │ │ │ ├── node-protect │ │ │ │ │ └── grid.png │ │ │ │ ├── qemu-monitor │ │ │ │ │ └── grid.png │ │ │ │ ├── settings │ │ │ │ │ ├── cluster-settings1.png │ │ │ │ │ ├── cluster-settings2.png │ │ │ │ │ ├── cluster-settings3.png │ │ │ │ │ ├── clustermanagement-options.png │ │ │ │ │ ├── global-settings.png │ │ │ │ │ ├── module-settings.png │ │ │ │ │ ├── options.png │ │ │ │ │ ├── service-general-cv4pve-admin-add-cluster1.png │ │ │ │ │ ├── service-general-cv4pve-admin-add-cluster2.png │ │ │ │ │ ├── service-general-cv4pve-admin.png │ │ │ │ │ ├── service-general-localization.png │ │ │ │ │ ├── service-general-smtp-config.png │ │ │ │ │ └── service-general-smtp.png │ │ │ │ ├── status │ │ │ │ │ ├── modules-health-clusterusage-object.png │ │ │ │ │ ├── modules-health-clusterusage-tasks.png │ │ │ │ │ ├── modules-health-clusterusage.png │ │ │ │ │ ├── objects.png │ │ │ │ │ ├── summary.png │ │ │ │ │ └── tasks_logs.png │ │ │ │ ├── vm-unlock │ │ │ │ │ └── vms.png │ │ │ │ └── vzdump-trend │ │ │ │ │ ├── backups-inline.png │ │ │ │ │ ├── disks_not_backupped.png │ │ │ │ │ ├── duration.png │ │ │ │ │ ├── job-detail.png │ │ │ │ │ ├── job.png │ │ │ │ │ ├── not-scheduled.png │ │ │ │ │ ├── range.png │ │ │ │ │ ├── scheduled.png │ │ │ │ │ ├── size.png │ │ │ │ │ ├── speed.png │ │ │ │ │ ├── storage.png │ │ │ │ │ ├── task-detail.png │ │ │ │ │ └── vm-ct.png │ │ │ └── multicluster │ │ │ │ └── multicluster-management.png │ │ └── social │ │ │ ├── docker-24.png │ │ │ ├── domain-24.png │ │ │ ├── github-24.png │ │ │ └── youtube-play-24.png │ ├── index.adoc │ ├── index.html │ ├── installation.adoc │ ├── intro.adoc │ ├── module-administration.adoc │ ├── module-control.adoc │ ├── module-health.adoc │ ├── module-home.adoc │ ├── module-safe.adoc │ ├── module-utilities.adoc │ └── subscription.adoc │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon.ico │ ├── images │ ├── community.png │ ├── enterprise.png │ ├── logo.png │ └── wallpaper.png │ └── site.webmanifest ├── Docker ├── .dockerignore ├── Dockerfile ├── Nginx │ └── ReverseProxy │ │ ├── .env │ │ ├── docker-compose.yml │ │ └── nginx.conf └── README.md └── common.props /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "dotnet.defaultSolution": "Corsinvest.ProxmoxVE.Admin.sln" 3 | } -------------------------------------------------------------------------------- /3rd-party-licenses.md: -------------------------------------------------------------------------------- 1 | # License overview of included 3rd party libraries 2 | 3 | The project is licensed under the terms of the [LICENSE](LICENSE) 4 | 5 | However, includes several third-party Open-Source libraries, which are licensed under their own respective Open-Source licenses. 6 | 7 | ## Libraries directly included 8 | 9 | [Corsinvest ProxmoxVE Api](https://github.com/Corsinvest/cv4pve-api-dotnet) 10 | License: GPLv3 11 | 12 | [Corsinvest ProxmoxVE Api Extension](https://github.com/Corsinvest/cv4pve-api-dotnet) 13 | License: GPLv3 14 | 15 | [Dotnet Core](https://github.com/dotnet/core) 16 | License: MIT 17 | -------------------------------------------------------------------------------- /Corsinvest.ProxmoxVE.Admin.sln.licenseheader: -------------------------------------------------------------------------------- 1 | extensions: designer.cs generated.cs 2 | extensions: .cs 3 | /* 4 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 5 | * SPDX-License-Identifier: AGPL-3.0-only 6 | */ 7 | extensions: .xml .config .xsd 8 | 12 | extensions: .cshtml .razor 13 | @* 14 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 15 | * SPDX-License-Identifier: AGPL-3.0-only 16 | *@ 17 | extensions: .ps1 18 | # 19 | # SPDX-FileCopyrightText: Copyright Corsinvest Srl 20 | # SPDX-License-Identifier: AGPL-3.0-only 21 | # -------------------------------------------------------------------------------- /Initialize-Tools.ps1: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright Corsinvest Srl 2 | # SPDX-License-Identifier: GPL-3.0-only 3 | 4 | Import-Module ..\..\..\cmds\Corsinvest.Dotnet.Develop.psm1 -Verbose -Force -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/icon.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Components/RenderIndex.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | 8 | 9 | 10 | 11 | @*Height="calc(100vh - 295px)"*@ 12 | 13 | 14 | 15 |
16 | 17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
-------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Components/RenderWidget.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @L["Scheduled:"] @Scheduled - @L["Snapshot:"] @SnapCount 8 | @L["Last:"] @Last - @L["Vms managed:"] @VmScheduled -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Components/RenderWidget.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap.Components; 6 | 7 | public partial class RenderWidget 8 | { 9 | [Inject] private IServiceScopeFactory ScopeFactory { get; set; } = default!; 10 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 11 | 12 | private int Scheduled { get; set; } 13 | private DateTime? Last { get; set; } 14 | private int SnapCount { get; set; } 15 | private int VmScheduled { get; set; } 16 | 17 | protected override async Task OnAfterRenderAsync(bool firstRender) 18 | { 19 | (Scheduled, Last, SnapCount, VmScheduled, _) = await Helper.InfoAsync(ScopeFactory, await PveClientService.GetCurrentClusterNameAsync()); 20 | StateHasChanged(); 21 | } 22 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Components/RenderWidgetInfo.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Components/RenderWidgetInfo.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Api; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap.Components; 8 | 9 | public partial class RenderWidgetInfo 10 | { 11 | [Inject] private IServiceScopeFactory ScopeFactory { get; set; } = default!; 12 | 13 | private string Description { get; set; } = default!; 14 | 15 | private async Task GetStatusAsync(PveClient client, string clusterName) 16 | { 17 | var ret = false; 18 | Description = "AutoSnap"; 19 | 20 | var (scheduled, _, snapCount, _, inError) = await Helper.InfoAsync(ScopeFactory, clusterName); 21 | if (scheduled == 0) { Description = L["AutoSnap not scheduled!"]; } 22 | else if (inError > 0) { Description = L["AutoSnap in error!"]; } 23 | else if (snapCount == 0) { Description = L["AutoSnap not found!"]; } 24 | else { ret = true; } 25 | 26 | StateHasChanged(); 27 | return ret; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Components/Timeline.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Ardalis.Specification; 6 | using Corsinvest.AppHero.Core.Domain.Repository; 7 | using Corsinvest.ProxmoxVE.Admin.AutoSnap.Models; 8 | using Corsinvest.ProxmoxVE.Admin.AutoSnap.Repository; 9 | 10 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap.Components; 11 | 12 | public partial class Timeline 13 | { 14 | [Inject] public IReadRepository History { get; set; } = default!; 15 | [Inject] public IPveClientService PveClientService { get; set; } = default!; 16 | 17 | private IEnumerable> Data { get; set; } = default!; 18 | 19 | protected override async Task OnInitializedAsync() 20 | { 21 | var spec = new AutoSnapJobHistorySpec(await PveClientService.GetCurrentClusterNameAsync()); 22 | Data = (await History.ListAsync(spec)).GroupBy(a => a.Start.Date).Take(10); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Corsinvest.ProxmoxVE.Admin.AutoSnap.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | all 9 | runtime; build; native; contentfiles; analyzers; buildtransitive 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Job.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Extensions; 6 | using Corsinvest.ProxmoxVE.Admin.AutoSnap.Models; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap; 9 | 10 | internal class Job(IServiceScopeFactory scopeFactory) 11 | { 12 | private static bool ModuleEnabled(IServiceScope scope) => scope.GetModule()!.Enabled; 13 | 14 | public async Task CreateAsync(int id) 15 | { 16 | using var scope = scopeFactory.CreateScope(); 17 | if (ModuleEnabled(scope)) { await Helper.CreateAsync(scope, id); } 18 | } 19 | 20 | public async Task PurgeAsync(int id) 21 | { 22 | using var scope = scopeFactory.CreateScope(); 23 | await Helper.PurgeAsync(scope, id); 24 | } 25 | 26 | public async Task DeleteAsync(IEnumerable ids) 27 | { 28 | using var scope = scopeFactory.CreateScope(); 29 | await Helper.DeleteAsync(scope, ids); 30 | } 31 | 32 | public async Task DeleteAsync(IEnumerable snapshots, string clusterName) 33 | { 34 | using var scope = scopeFactory.CreateScope(); 35 | await Helper.DeleteAsync(scope, snapshots, clusterName); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Models/AutoSnapInfo.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Models; 6 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Vm; 7 | using Corsinvest.ProxmoxVE.Api.Shared.Utils; 8 | using System.ComponentModel; 9 | 10 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap.Models; 11 | 12 | internal class AutoSnapInfo : INode, IVmId, ISnapshotsSize, IName 13 | { 14 | public string Node { get; set; } = default!; 15 | public long VmId { get; set; } 16 | public string VmName { get; set; } = default!; 17 | public VmType VmType { get; set; } 18 | public DateTime Date { get; set; } 19 | public string Parent { get; set; } = default!; 20 | public string Name { get; set; } = default!; 21 | public string Label { get; set; } = default!; 22 | public string Description { get; set; } = default!; 23 | public bool VmStatus { get; set; } 24 | 25 | [Display(Name = "Snapshots Size")] 26 | [DisplayFormat(DataFormatString = "{0:" + FormatHelper.FormatBytes + "}")] 27 | public double SnapshotsSize { get; set; } 28 | 29 | [DisplayName("Size")] 30 | public string TextSize => FormatHelper.FromBytes(SnapshotsSize); 31 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Models/AutoSnapJobHistory.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Domain.Entities; 6 | using Corsinvest.AppHero.Core.Domain.Models; 7 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 8 | using System.ComponentModel; 9 | using System.ComponentModel.DataAnnotations.Schema; 10 | 11 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap.Models; 12 | 13 | public class AutoSnapJobHistory : JobHistory, IAggregateRoot, IClusterName 14 | { 15 | [Required] 16 | public int Id { get; set; } 17 | 18 | [Required] 19 | public string ClusterName { get; set; } = default!; 20 | 21 | [Required] 22 | public AutoSnapJob Job { get; set; } = default!; 23 | 24 | [NotMapped] 25 | [DisplayName("Job Id")] 26 | public int JobIdTmp => Job?.Id ?? -1; 27 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Models/AutoSnapJobHook.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Domain.Entities; 6 | using Corsinvest.ProxmoxVE.AutoSnap.Api; 7 | using System.ComponentModel; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap.Models; 10 | 11 | public class AutoSnapJobHook : EntityBase, IAggregateRoot 12 | { 13 | [Required] 14 | public AutoSnapJob Job { get; set; } = default!; 15 | 16 | [Required] 17 | public string Description { get; set; } = default!; 18 | 19 | public bool Enabled { get; set; } 20 | public int Order { get; set; } = 0; 21 | public string? Username { get; set; } 22 | public string? Password { get; set; } 23 | public HookPhase Phase { get; set; } = default!; 24 | 25 | [Required] 26 | public string Url { get; set; } = default!; 27 | 28 | public AutoSnapJobHookHttpMethod HttpMethod { get; set; } = default!; 29 | public string Data { get; set; } = string.Empty; 30 | 31 | [DisplayName("Data Is Key Value (JSON Format)")] 32 | public bool DataIsKeyValue { get; set; } 33 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Models/AutoSnapJobHookHttpMethod.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap.Models; 6 | 7 | public enum AutoSnapJobHookHttpMethod 8 | { 9 | Get = 0, 10 | Post = 1, 11 | Put = 2 12 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Notify.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap; 6 | 7 | public enum Notify 8 | { 9 | None = 0, 10 | Allways = 1, 11 | 12 | [Display(Description = "On Failure Only")] 13 | OnFailureOnly = 2 14 | } 15 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Persistence/AutoSnapDbContext.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.AutoSnap.Models; 6 | using Microsoft.EntityFrameworkCore; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap.Persistence; 9 | 10 | public class AutoSnapDbContext(DbContextOptions options) : DbContext(options) 11 | { 12 | public DbSet Jobs { get; set; } = default!; 13 | public DbSet JobHistories { get; set; } = default!; 14 | public DbSet JobHooks { get; set; } = default!; 15 | 16 | protected override void OnModelCreating(ModelBuilder modelBuilder) 17 | { 18 | base.OnModelCreating(modelBuilder); 19 | modelBuilder.UseCollation("NOCASE"); 20 | 21 | modelBuilder.Entity() 22 | .HasMany(c => c.Histories) 23 | .WithOne(a => a.Job) 24 | .OnDelete(DeleteBehavior.Cascade); 25 | 26 | modelBuilder.Entity() 27 | .HasMany(c => c.Hooks) 28 | .WithOne(a => a.Job) 29 | .OnDelete(DeleteBehavior.Cascade); 30 | } 31 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Repository/AutoSnapJobHistorySpec.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Ardalis.Specification; 6 | using Corsinvest.ProxmoxVE.Admin.AutoSnap.Models; 7 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap.Repository; 10 | 11 | internal class AutoSnapJobHistorySpec : ClusterByNameSpec 12 | { 13 | public AutoSnapJobHistorySpec(string clusterName, int jobId, bool showOnlyError) : base(clusterName) 14 | { 15 | Query.Where(a => a.Job.Id == jobId, jobId > 0) 16 | .Where(a => !a.Status, showOnlyError); 17 | } 18 | 19 | public AutoSnapJobHistorySpec(string clusterName) : base(clusterName) 20 | { 21 | Query.OrderByDescending(a => a.Start.Date); 22 | } 23 | 24 | public AutoSnapJobHistorySpec InError(int days) 25 | { 26 | var start = DateTime.Now.Date.AddDays(-days).Date; 27 | Query.Where(a => !a.Status && a.Start >= start); 28 | return this; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/Repository/AutoSnapJobSpec.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Ardalis.Specification; 6 | using Corsinvest.ProxmoxVE.Admin.AutoSnap.Models; 7 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap.Repository; 10 | 11 | internal class AutoSnapJobSpec : ClusterByNameSpec 12 | { 13 | public AutoSnapJobSpec(string clusterName) : base(clusterName) 14 | => Query.Include(a => a.Hooks).AsSplitQuery(); 15 | 16 | public AutoSnapJobSpec(int id) : base(string.Empty) 17 | => Query.Where(a => a.Id == id) 18 | .Include(a => a.Histories) 19 | .Include(a => a.Hooks) 20 | .AsSplitQuery(); 21 | 22 | public AutoSnapJobSpec Enabled() 23 | { 24 | Query.Where(a => a.Enabled); 25 | return this; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/SearchMode.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.AutoSnap; 6 | 7 | public enum SearchMode 8 | { 9 | Managed = 0, 10 | All = 1 11 | } 12 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/TextFile1.txt: -------------------------------------------------------------------------------- 1 | dotnet ef migrations Add Initial --startup-project ..\Corsinvest.ProxmoxVE.Admin -c AutoSnapDbContext -v -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Corsinvest.AppHero.Core.BackgroundJob; 6 | global using Corsinvest.AppHero.Core.Modularity; 7 | global using Corsinvest.AppHero.Core.Security.Auth.Permissions; 8 | global using Corsinvest.AppHero.Core.UI; 9 | global using Corsinvest.ProxmoxVE.Admin.Core.Helpers; 10 | global using Corsinvest.ProxmoxVE.Admin.Core.Services; 11 | global using Microsoft.AspNetCore.Components; 12 | global using Microsoft.Extensions.DependencyInjection; 13 | global using Microsoft.Extensions.Localization; 14 | global using Microsoft.Extensions.Options; 15 | global using MudBlazor; 16 | global using System.ComponentModel.DataAnnotations; 17 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.AutoSnap/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using MudBlazor 7 | @using Microsoft.EntityFrameworkCore 8 | @using Microsoft.Extensions.Localization 9 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 10 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Options 11 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 12 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components 13 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components.DataGrid 14 | @using Corsinvest.AppHero.Core.MudBlazorUI.Extensions; 15 | @using Corsinvest.AppHero.Core.Extensions; 16 | @using Corsinvest.ProxmoxVE.Admin.AutoSnap.Models; 17 | @using Corsinvest.AppHero.Core.Domain.Repository; 18 | @using Corsinvest.ProxmoxVE.Admin.Core.Helpers; 19 | @using MudExtensions 20 | @using MudExtensions.Enums 21 | @using Corsinvest.ProxmoxVE.Admin.Core.UI.Options 22 | @using Corsinvest.ProxmoxVE.Admin.Core.UI.Layout 23 | @using Corsinvest.ProxmoxVE.Api; 24 | @using Corsinvest.ProxmoxVE.Api.Shared.Utils; 25 | 26 | @inject IUINotifier UINotifier 27 | @inject IUIMessageBox UIMessageBox -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Botgram/Components/RenderOptions.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHModuleOptionsBase 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 18 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Botgram/Components/RenderWidget.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @L["Users:"] @Count 8 | @L["Last:"] @LastUpdate -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Botgram/Components/RenderWidget.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Services; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.Extensions.Hosting; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.Botgram.Components; 10 | 11 | public partial class RenderWidget 12 | { 13 | [Inject] private IServiceScopeFactory ServiceScopeFactory { get; set; } = default!; 14 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 15 | 16 | private int Count { get; set; } 17 | private DateTime? LastUpdate { get; set; } 18 | 19 | protected override async Task OnInitializedAsync() 20 | { 21 | var scope = ServiceScopeFactory.CreateScope(); 22 | var botgramService = scope.ServiceProvider.GetServices() 23 | .OfType() 24 | .FirstOrDefault(); 25 | 26 | var clusterName = await PveClientService.GetCurrentClusterNameAsync(); 27 | 28 | Count = botgramService?.GetChats(clusterName).Count ?? 0; 29 | LastUpdate = botgramService?.GetLastUpdate(clusterName); 30 | } 31 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Botgram/Corsinvest.ProxmoxVE.Admin.Botgram.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Botgram/Options.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 6 | using Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 7 | using System.ComponentModel.DataAnnotations; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.Botgram; 10 | 11 | public class Options : PveModuleClustersOptions { } 12 | 13 | public class ModuleClusterOptions : IClusterName 14 | { 15 | public string ClusterName { get; set; } = default!; 16 | 17 | [Display(Name = "Enabled")] 18 | public bool Enabled { get; set; } 19 | 20 | [Display(Name = "BOT API Token")] 21 | public string Token { get; set; } = default!; 22 | 23 | [Display(Name = "Chats Id (new line separator). Empty non control access.")] 24 | public string ChatsId { get; set; } = default!; 25 | 26 | public long[] GetChatsId() 27 | => [.. ChatsId.Split(Environment.NewLine) 28 | .Select(a => new 29 | { 30 | Valid = long.TryParse(a, out var chatId), 31 | ChatId = chatId 32 | }) 33 | .Where(a => a.Valid) 34 | .Select(a => a.ChatId)]; 35 | } 36 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Botgram/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Corsinvest.ProxmoxVE.Admin.Core.Helpers; 6 | global using Microsoft.AspNetCore.Components; 7 | global using MudBlazor; 8 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Botgram/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using MudBlazor 7 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 8 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Options; 9 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components; 10 | @using MudExtensions 11 | @using Corsinvest.ProxmoxVE.Admin.Core.UI.Options 12 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 13 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/Components/RenderOptions.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHModuleOptionsBase 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/Components/WidgetCluster/RenderWidgetCpu.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Corsinvest.ProxmoxVE.Admin.Core.Helpers; 6 | @* 7 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 8 | * SPDX-License-Identifier: AGPL-3.0-only 9 | *@ 10 | @inherits AHComponentBase 11 | 12 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/Components/WidgetCluster/RenderWidgetMemory.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Corsinvest.ProxmoxVE.Admin.Core.Helpers; 6 | @* 7 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 8 | * SPDX-License-Identifier: AGPL-3.0-only 9 | *@ 10 | @inherits AHComponentBase 11 | 12 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/Components/WidgetCluster/RenderWidgetStorage.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Corsinvest.ProxmoxVE.Admin.Core.Helpers; 6 | @* 7 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 8 | * SPDX-License-Identifier: AGPL-3.0-only 9 | *@ 10 | @inherits AHComponentBase 11 | 12 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/Components/WidgetCluster/WidgetBase.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @if (DataUsage == null) 8 | { 9 | 10 | } 11 | else 12 | { 13 |
14 |
15 | 16 | @L[$"{DataUsage.Name} Usage"] 17 | @DataUsage.Usage % 18 |
19 | 20 | @if (DataUsage.Usage >= Threshold.Critical) 21 | { 22 | @L["Critical: the usage is too high!"] 23 | } 24 | else if (DataUsage.Usage >= Threshold.Warning) 25 | { 26 | @L["Warning: the usage is high!"] 27 | } 28 | else 29 | { 30 | @L["The usage is normal!"] 31 | } 32 |
33 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/Components/WidgetInfo/RenderWidgetInfoBackups.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | 8 | 9 | @code 10 | { 11 | private async Task GetStatusAsync(PveClient client, string clusterName) 12 | { 13 | var dateCheck = new DateTimeOffset(DateTime.Now.Date.AddDays(-10)).ToUnixTimeSeconds(); 14 | var ret = true; 15 | 16 | foreach (var node in (await client.Nodes.GetAsync()).Where(a => a.IsOnline)) 17 | { 18 | if ((await client.Nodes[node.Node].Tasks.GetAsync(errors: true, limit: 1, typefilter: "vzdump")) 19 | .Count(a => a.StartTime >= dateCheck) > 0) 20 | { 21 | ret = false; 22 | break; 23 | } 24 | } 25 | return ret; 26 | } 27 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/Components/WidgetInfo/RenderWidgetInfoClusterStatus.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @inject IPveClientService PveClientService 8 | 9 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/Components/WidgetInfo/RenderWidgetInfoNodesOnlines.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | 8 | 9 | @code 10 | { 11 | private string Description { get; set; } = default!; 12 | 13 | private async Task GetStatusAsync(PveClient client, string clusterName) 14 | { 15 | var nodes = await client.Nodes.GetAsync(); 16 | var onLine = nodes.Where(a => a.IsOnline).Count(); 17 | Description = L["{0} of {1} Nodes online", onLine, nodes.Count()]; 18 | StateHasChanged(); 19 | return onLine == nodes.Count(); 20 | } 21 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/Components/WidgetInfo/RenderWidgetInfoNodesTasks.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | 8 | 9 | @code 10 | { 11 | private async Task GetStatusAsync(PveClient client, string clusterName) 12 | { 13 | var dateCheck = new DateTimeOffset(DateTime.Now.Date.AddDays(-100)).ToUnixTimeSeconds(); 14 | var ret = true; 15 | foreach (var node in (await client.Nodes.GetAsync()).Where(a => a.IsOnline)) 16 | { 17 | if ((await client.Nodes[node.Node].Tasks.GetAsync(errors: true, limit: 1)) 18 | .Count(a => a.StartTime >= dateCheck) > 0) 19 | { 20 | ret = false; 21 | break; 22 | } 23 | } 24 | return ret; 25 | } 26 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/Components/WidgetInfo/RenderWidgetInfoNodesUpdates.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | 8 | 9 | @code 10 | { 11 | private async Task GetStatusAsync(PveClient client, string clusterName) 12 | { 13 | var ret = true; 14 | foreach (var node in (await client.Nodes.GetAsync()).Where(a => a.IsOnline)) 15 | { 16 | if ((await client.Nodes[node.Node].Apt.Update.GetAsync()).Count() > 0) 17 | { 18 | ret = false; 19 | break; 20 | } 21 | } 22 | return ret; 23 | } 24 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/Corsinvest.ProxmoxVE.Admin.ClusterStatus.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/Options.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Models; 6 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 7 | using Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.ClusterStatus; 10 | 11 | public class Options : PveModuleClustersOptions { } 12 | 13 | public class ModuleClusterOptions : IClusterName 14 | { 15 | public string ClusterName { get; set; } = default!; 16 | 17 | public ThresholdPercentual Cpu { get; set; } = new ThresholdPercentual(); 18 | public ThresholdPercentual Memory { get; set; } = new ThresholdPercentual(); 19 | public ThresholdPercentual Storage { get; set; } = new ThresholdPercentual(); 20 | 21 | // [Range(0, 100)] 22 | // [Display(Name = "Max Storage Usage (default: 85%)")] 23 | // public int MaxStorageUsage { get; set; } = 85; 24 | 25 | // [Range(0, 100)] 26 | // [Display(Name = "Days Previous (default: 2)")] 27 | // public int DaysPrevious { get; set; } = 2; 28 | } 29 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Corsinvest.ProxmoxVE.Admin.Core.Services; 6 | global using Microsoft.AspNetCore.Components; 7 | global using MudBlazor; 8 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterStatus/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Corsinvest.AppHero.Core.UI; 6 | @using Microsoft.AspNetCore.Components 7 | @using MudBlazor 8 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 9 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components 10 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components.DataGrid 11 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster; 12 | @using Corsinvest.AppHero.Core.MudBlazorUI.Extensions; 13 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Options; 14 | @using Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 15 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Node 16 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 17 | @using Corsinvest.ProxmoxVE.Admin.Core.Helpers; 18 | @using Corsinvest.ProxmoxVE.Api; 19 | @using Corsinvest.ProxmoxVE.Api.Extension; 20 | @using Corsinvest.ProxmoxVE.Admin.Core.UI.Layout 21 | @using Corsinvest.ProxmoxVE.Admin.Core.Models; 22 | 23 | @inject IUINotifier UINotifier 24 | @inject IUIMessageBox UIMessageBox -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterUsage/Components/RenderIndex.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterUsage/Components/RenderOptions.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.ClusterUsage.Components; 6 | 7 | public partial class RenderOptions 8 | { 9 | [Inject] private IJobService JobService { get; set; } = default!; 10 | 11 | public override async Task SaveAsync() 12 | { 13 | foreach (var item in Options.Clusters) 14 | { 15 | JobService.ScheduleOrRemove(a => a.ScanAsync(item.ClusterName), item.CronExpression, item.Enabled, item.ClusterName); 16 | } 17 | 18 | await base.SaveAsync(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterUsage/Corsinvest.ProxmoxVE.Admin.ClusterUsage.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | all 8 | runtime; build; native; contentfiles; analyzers; buildtransitive 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterUsage/Job.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.ClusterUsage; 6 | 7 | internal class Job(IServiceScopeFactory scopeFactory) 8 | { 9 | private static bool ModuleEnabled(IServiceScope scope) => scope.GetModule()!.Enabled; 10 | 11 | public async Task ScanAsync(string clusterName) 12 | { 13 | using var scope = scopeFactory.CreateScope(); 14 | if (ModuleEnabled(scope)) { await Helper.ScanAsync(scope, clusterName); } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterUsage/Models/DataVmStorage.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Domain.Entities; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.ClusterUsage.Models; 8 | 9 | public class DataVmStorage : EntityBase 10 | { 11 | public DataVm DataVm { get; set; } = default!; 12 | public string Storage { get; set; } = default!; 13 | public long Size { get; set; } 14 | } 15 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterUsage/Options.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Validators; 6 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 7 | using Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.ClusterUsage; 10 | 11 | public class Options : PveModuleClustersOptions { } 12 | 13 | public class ModuleClusterOptions : IClusterName 14 | { 15 | public string ClusterName { get; set; } = default!; 16 | 17 | [Required] 18 | [Display(Name = "Cron Schedule")] 19 | [CronExpressionValidator] 20 | public string CronExpression { get; set; } = "0 1 * * *"; 21 | 22 | public bool Enabled { get; set; } 23 | 24 | [Display(Name = "Number of months which should will keep")] 25 | public int Keep { get; set; } = 12; 26 | 27 | public List Storages { get; set; } = []; 28 | 29 | [Display(Name = "Cost Day CPU Running")] 30 | public double CostDayCpuRunning { get; set; } 31 | 32 | [Display(Name = "Cost Day CPU Stopped")] 33 | public double CostDayCpuStopped { get; set; } 34 | 35 | [Display(Name = "Cost Day GB Running")] 36 | public double CostDayMemoryGbRunning { get; set; } 37 | 38 | [Display(Name = "Cost Day GB Stopped")] 39 | public double CostDayMemoryGbStopped { get; set; } 40 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterUsage/Persistence/ClusterUsageDbContext.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.ClusterUsage.Persistence; 8 | 9 | internal class ClusterUsageDbContext(DbContextOptions options) : DbContext(options) 10 | { 11 | public DbSet DataVms { get; set; } = default!; 12 | public DbSet DataVmStorages { get; set; } = default!; 13 | 14 | protected override void OnModelCreating(ModelBuilder modelBuilder) 15 | { 16 | base.OnModelCreating(modelBuilder); 17 | modelBuilder.UseCollation("NOCASE"); 18 | 19 | modelBuilder.Entity() 20 | .HasMany(c => c.Storages) 21 | .WithOne(a => a.DataVm) 22 | .OnDelete(DeleteBehavior.Cascade); 23 | } 24 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterUsage/StorageOptions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.ClusterUsage; 6 | 7 | public class StorageOptions 8 | { 9 | public string Storage { get; set; } = default!; 10 | 11 | [Display(Name = "Cost Day GB Running")] 12 | public double CostDayGbRunning { get; set; } 13 | 14 | [Display(Name = "Cost Day GB Stopped")] 15 | public double CostDayGbStopped { get; set; } 16 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterUsage/TextFile1.txt: -------------------------------------------------------------------------------- 1 | dotnet ef migrations Add Initial --startup-project ..\Corsinvest.ProxmoxVE.Admin -c ClusterUsageDbContext -v -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterUsage/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Corsinvest.AppHero.Core.BackgroundJob; 6 | global using Corsinvest.AppHero.Core.Extensions; 7 | global using Corsinvest.AppHero.Core.UI; 8 | global using Corsinvest.ProxmoxVE.Admin.ClusterUsage.Models; 9 | global using Corsinvest.ProxmoxVE.Admin.Core.Services; 10 | global using Microsoft.AspNetCore.Components; 11 | global using Microsoft.Extensions.DependencyInjection; 12 | global using Microsoft.Extensions.Options; 13 | global using MudBlazor; 14 | global using System.ComponentModel.DataAnnotations; 15 | global using Corsinvest.ProxmoxVE.Admin.Core.Extensions; 16 | 17 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ClusterUsage/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using MudBlazor 7 | @using Corsinvest.ProxmoxVE.Api.Shared.Utils 8 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 9 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Options; 10 | @using Corsinvest.ProxmoxVE.Admin.Core.Helpers; 11 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components 12 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components.DataGrid 13 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster; 14 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Storage; 15 | @using Corsinvest.AppHero.Core.Security.Auth.Permissions; 16 | @using Corsinvest.AppHero.Core.UI; 17 | @using Corsinvest.AppHero.Core.MudBlazorUI.Extensions; 18 | @using Corsinvest.ProxmoxVE.Admin.Core.UI.Options 19 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 20 | 21 | @inject IUINotifier UINotifier 22 | @inject IUIMessageBox UIMessageBox -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Corsinvest - Backup.ProxmoxVE.Admin.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | true 6 | Library 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Corsinvest.ProxmoxVE.Admin.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Extensions/EnumerableExtension.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.Extensions; 8 | 9 | public static class EnumerableExtension 10 | { 11 | public static ulong Sum(this IEnumerable source, Func summer) 12 | { 13 | ulong total = 0; 14 | foreach (var item in source) { total += summer(item); } 15 | return total; 16 | } 17 | 18 | public static T? IsCluster(this IEnumerable query, string clusterName) where T : IClusterName 19 | => query.FirstOrDefault(a => a.ClusterName == clusterName); 20 | } 21 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Extensions/JobExtension.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.BackgroundJob; 6 | using System.Linq.Expressions; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.Core.Extensions; 9 | 10 | public static class JobExtension 11 | { 12 | public static void ScheduleOrRemove(this IJobService JobService, 13 | Expression> methodCall, 14 | string cronExpression, 15 | bool enabled, 16 | string clusterName, 17 | params object?[] args) 18 | { 19 | var jobId = JobHelper.GetJobId(clusterName, args); 20 | if (enabled) 21 | { 22 | JobService.Schedule(jobId, methodCall, cronExpression, TimeZoneInfo.Local); 23 | } 24 | else 25 | { 26 | JobService.RemoveIfExists(jobId); 27 | } 28 | } 29 | 30 | public static void RemoveIfExists(this IJobService JobService, string clusterName, params object?[] args) 31 | => JobService.RemoveIfExists(JobHelper.GetJobId(clusterName, args)); 32 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Extensions/QueryableExtension.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.Extensions; 8 | 9 | public static class QueryableExtension 10 | { 11 | public static T? IsCluster(this IQueryable query, string clusterName) where T : IClusterName 12 | => query.FirstOrDefault(a => a.ClusterName == clusterName); 13 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Extensions/ServiceScopeExtension.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 6 | using Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 7 | using Corsinvest.ProxmoxVE.Api; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | namespace Corsinvest.ProxmoxVE.Admin.Core.Extensions; 11 | 12 | public static class ServiceScopeExtension 13 | { 14 | public static async Task GetPveClientAsync(this IServiceScope scope, string clusterName) 15 | => (await scope.GetPveClientService().GetClientAsync(clusterName))!; 16 | 17 | public static IPveClientService GetPveClientService(this IServiceScope scope) 18 | => scope.ServiceProvider.GetRequiredService(); 19 | 20 | public static TModuleClusterOptions GetModuleClusterOptions(this IServiceScope scope, string clusterName) 21 | where TOptions : PveModuleClustersOptions 22 | where TModuleClusterOptions : IClusterName 23 | => scope.ServiceProvider.GetRequiredService>().Value.Get(clusterName); 24 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Extensions/StringExtension.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Extensions; 6 | 7 | public static class StringExtension 8 | { 9 | public static bool IsNullOrEmptyOrWhiteSpace(this string value) 10 | => string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value); 11 | } 12 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Helpers/JobHelper.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Helpers; 6 | 7 | public static class JobHelper 8 | { 9 | public static string GetJobId(string clusterName, params object?[] args) 10 | => $"{typeof(T).FullName}-{clusterName}" + 11 | (args != null && args.Length > 0 12 | ? "-" + args.JoinAsString("-") 13 | : ""); 14 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Helpers/PveAdminExtensions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Api; 6 | using Corsinvest.ProxmoxVE.Api.Shared.Utils; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.Core.Helpers; 9 | 10 | public static class PveAdminExtensions 11 | { 12 | public static async Task<(string Type, string Name)> GetClusterInfoAsync(this PveClient client) 13 | { 14 | var status = await client.Cluster.Status.GetAsync(); 15 | var clusterName = status.FirstOrDefault(a => a.Type == PveConstants.KeyApiCluster)?.Name; 16 | var type = string.IsNullOrEmpty(clusterName) 17 | ? "NODE" 18 | : "CLUSTER"; 19 | 20 | var name = string.IsNullOrEmpty(clusterName) 21 | ? status.FirstOrDefault()!.Name 22 | : clusterName; 23 | return (type, name); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Helpers/StringWriterEvent.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Helpers; 6 | 7 | public class StringWriterEvent : StringWriter 8 | { 9 | public event EventHandler WritedData = default!; 10 | private void InvokeWriteData(string value) => WritedData?.Invoke(this, value); 11 | 12 | public override void Write(char value) 13 | { 14 | base.Write(value); 15 | InvokeWriteData(value + ""); 16 | } 17 | 18 | public override void Write(string? value) 19 | { 20 | base.Write(value); 21 | InvokeWriteData(value + ""); 22 | } 23 | 24 | public override void WriteLine() 25 | { 26 | base.WriteLine(); 27 | InvokeWriteData(Environment.NewLine); 28 | } 29 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Models/ClusterResourceVmExtraInfo.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster; 6 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Vm; 7 | using Corsinvest.ProxmoxVE.Api.Shared.Utils; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.Core.Models; 10 | 11 | public class ClusterResourceVmExtraInfo : ClusterResource, IClusterResourceVmOsInfo, INode, IVmId, ISnapshotsSize 12 | { 13 | [Display(Name = "Snapshots Size")] 14 | [DisplayFormat(DataFormatString = "{0:" + FormatHelper.FormatBytes + "}")] 15 | public double SnapshotsSize { get; set; } 16 | 17 | public VmQemuAgentOsInfo VmQemuAgentOsInfo { get; set; } = default!; 18 | 19 | [Display(Name = "Host Name")] 20 | public string HostName { get; set; } = default!; 21 | 22 | [Display(Name = "Os Version")] 23 | public string OsVersion { get; set; } = default!; 24 | 25 | [Display(Name = "Os Type")] 26 | public VmOsType? OsType { get; set; } = default!; 27 | } 28 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Models/IName.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Models; 6 | 7 | public interface IName 8 | { 9 | string Name { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Models/INode.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Models; 6 | 7 | public interface INode 8 | { 9 | string Node { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Models/ISnapshotsSize.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Api.Shared.Utils; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.Models; 8 | 9 | public interface ISnapshotsSize 10 | { 11 | [Display(Name = "Snapshots Size")] 12 | [DisplayFormat(DataFormatString = "{0:" + FormatHelper.FormatBytes + "}")] 13 | double SnapshotsSize { get; set; } 14 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Models/IVmId.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Models; 6 | 7 | public interface IVmId 8 | { 9 | long VmId { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Models/ThresholdPercentual.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Models; 6 | 7 | public class ThresholdPercentual 8 | { 9 | [Range(0, 100)] 10 | public double Warning { get; set; } = 70; 11 | 12 | [Range(0, 100)] 13 | public double Critical { get; set; } = 80; 14 | } 15 | 16 | ///// 17 | ///// Settings Threshold 18 | ///// 19 | //public class Threshold 20 | //{ 21 | // /// 22 | // /// Warning 23 | // /// 24 | // [DisplayName("Warning")] 25 | // public T Warning { get; set; } 26 | 27 | // /// 28 | // /// Critical 29 | // /// 30 | // /// 31 | // [DisplayName("Critical")] 32 | // public T Critical { get; set; } 33 | //} 34 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Modularity/AdminModuleCategory.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Modularity; 6 | 7 | public enum AdminModuleCategory 8 | { 9 | General, 10 | Safe, 11 | Health, 12 | Control, 13 | Utilities, 14 | Management, 15 | Develop, 16 | System, 17 | Info, 18 | Support, 19 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Modularity/PveAdminModuleBase.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Modularity; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.Modularity; 8 | 9 | public abstract class PveAdminModuleBase : ModuleBase 10 | { 11 | protected void SetCategory(AdminModuleCategory category) 12 | { 13 | if (PveAdminHelper.ModuleCategories.TryGetValue(category, out var value)) { Category = value.Name; } 14 | } 15 | 16 | public IEnumerable PvePermissionRequired { get; protected set; } = []; 17 | } 18 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Options/AdminOptions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Configurations; 6 | 7 | public class AdminOptions 8 | { 9 | public List Clusters { get; set; } = []; 10 | public string FirstName { get; set; } = default!; 11 | public string LastName { get; set; } = default!; 12 | public string Company { get; set; } = default!; 13 | public string Email { get; set; } = default!; 14 | } 15 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Options/ClusterNodeOptions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Options; 6 | 7 | public class ClusterNodeOptions 8 | { 9 | [Required] 10 | public string IpAddress { get; set; } = default!; 11 | 12 | public int ApiPort { get; set; } = 8006; 13 | public int SshPort { get; set; } = 22; 14 | 15 | public string ServerId { get; set; } = default!; 16 | public string SubscriptionId { get; set; } = default!; 17 | } 18 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Options/RenderAdminOptions.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHModuleOptionsBase 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Options/RenderAdminOptions.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.UI; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.Options; 8 | 9 | public partial class RenderAdminOptions 10 | { 11 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 12 | 13 | public override async Task SaveAsync() 14 | { 15 | foreach (var item in Options.Clusters) 16 | { 17 | try 18 | { 19 | await PveClientService.PopulateInfoNodesAsync(item); 20 | } 21 | catch (Exception ex) { UINotifier.Show(ex.Message, UINotifierSeverity.Error); } 22 | } 23 | StateHasChanged(); 24 | 25 | await base.SaveAsync(); 26 | } 27 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Options/RenderClustersOptions.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Options; 6 | 7 | public partial class RenderClustersOptions 8 | { 9 | [EditorRequired][Parameter] public AdminOptions Options { get; set; } = default!; 10 | [Inject] private IDataGridManager DataGridManager { get; set; } = default!; 11 | 12 | protected override void OnInitialized() 13 | { 14 | DataGridManager.Title = L["Clusters"]; 15 | DataGridManager.DefaultSort = new() { [nameof(ClusterOptions.Name)] = false }; 16 | DataGridManager.QueryAsync = async () => await Task.FromResult(Options.Clusters); 17 | 18 | DataGridManager.SaveAsync = async (item, isNew) => 19 | { 20 | if (isNew) { Options.Clusters.Add(item); } 21 | return await Task.FromResult(true); 22 | }; 23 | 24 | DataGridManager.DeleteAsync = async (items) => 25 | { 26 | foreach (var item in items) { Options.Clusters.Remove(item); } 27 | return await Task.FromResult(true); 28 | }; 29 | } 30 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Options/RenderContactOptions.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | @code 23 | { 24 | [EditorRequired][Parameter] public AdminOptions AdminOptions { get; set; } = default!; 25 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Options/RenderSshLoginOptions.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @L["All nodes in the cluster must have the same credentials!"] 8 | 9 | 10 | 11 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | @code 24 | { 25 | [EditorRequired][Parameter] public ClusterOptions ClusterOptions { get; set; } = default!; 26 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/README.MD: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Repository/ClusterByNameSpec.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Ardalis.Specification; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.Repository; 8 | 9 | public class ClusterByNameSpec : Specification where T : IClusterName 10 | { 11 | public ClusterByNameSpec(string clusterName) 12 | => Query.Where(c => c.ClusterName == clusterName, !string.IsNullOrEmpty(clusterName)); 13 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Repository/IClusterName.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Repository; 6 | 7 | public interface IClusterName 8 | { 9 | string ClusterName { get; set; } 10 | } 11 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Services/DiskInfo/DiskInfoBase.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Services.DiskInfo; 6 | 7 | public abstract class DiskInfoBase(long vmId, string disk, string host, string spaceName,bool hostContainSnapshot) 8 | { 9 | public long VmId { get; } = vmId; 10 | public string Disk { get; } = disk; 11 | public string Host { get; } = host; 12 | public bool HostContainSnapshot { get; }= hostContainSnapshot; 13 | public string SpaceName { get; } = spaceName; 14 | public abstract string Type { get; } 15 | 16 | public List Snapshots { get; } = []; 17 | 18 | public class DiskInfoSnapshot(string name, double size, bool replication) 19 | { 20 | public string Name { get; } = name; 21 | public double Size { get; } = size; 22 | public bool Replication { get; } = replication; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Services/IPveUtilityService.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.DependencyInjection; 6 | using FluentResults; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.Core.Services; 9 | 10 | public interface IPveUtilityService : IScopedDependency 11 | { 12 | Task> FreeMemoryAsync(string clusterName, IEnumerable nodes); 13 | Task BlinkDiskLedAsync(string clusterName, string node, string devPath, bool blink); 14 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Services/ISshService.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.DependencyInjection; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.Services; 8 | 9 | public interface ISshService : IScopedDependency 10 | { 11 | IEnumerable<(int ExitCode, string StdOut, string Error)> Execute(string host, 12 | int port, 13 | string username, 14 | string password, 15 | IEnumerable commands); 16 | 17 | IEnumerable<(int ExitCode, string StdOut, string Error)> Execute(ClusterOptions clusterOptions, 18 | string host, 19 | int port, 20 | IEnumerable commands); 21 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Services/SshService.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Services; 6 | 7 | public class SshService : ISshService 8 | { 9 | public IEnumerable<(int ExitCode, string StdOut, string Error)> Execute(string host, 10 | int port, 11 | string username, 12 | string password, 13 | IEnumerable commands) 14 | => SshHelper.Execute(host, port, username, password, commands); 15 | 16 | public IEnumerable<(int ExitCode, string StdOut, string Error)> Execute(ClusterOptions clusterOptions, 17 | string host, 18 | int port, 19 | IEnumerable commands) 20 | => SshHelper.Execute(clusterOptions, host, port, commands); 21 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Support/Buy/Module.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Modularity; 6 | using Corsinvest.ProxmoxVE.Admin.Core.Modularity; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.Core.Support.Buy; 9 | 10 | public class Module : PveAdminModuleBase, IForceLoadModule 11 | { 12 | public Module() 13 | { 14 | Authors = "Corsinvest Srl"; 15 | Company = "Corsinvest Srl"; 16 | Keywords = "Subscription,Buy Subscription"; 17 | SetCategory(AdminModuleCategory.Support); 18 | Icon = Icons.Material.Filled.Shield; 19 | Type = ModuleType.Application; 20 | Description = "Buy Subscription"; 21 | Slug = "BuySubscription"; 22 | 23 | Link = new ModuleLink(this, Description, "https://shop.corsinvest.it", true) 24 | { 25 | Icon = Icons.Material.Filled.ShoppingCart, 26 | Order = 2 27 | }; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Support/RequestSupport/Module.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Modularity; 6 | using Corsinvest.ProxmoxVE.Admin.Core.Modularity; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.Core.Support.RequestSupport; 9 | 10 | public class Module : PveAdminModuleBase, IForceLoadModule 11 | { 12 | public Module() 13 | { 14 | Authors = "Corsinvest Srl"; 15 | Company = "Corsinvest Srl"; 16 | Keywords = "Subscription,Request Support"; 17 | SetCategory(AdminModuleCategory.Support); 18 | Icon = Icons.Material.Filled.Shield; 19 | Type = ModuleType.Application; 20 | Description = "Request Support"; 21 | Slug = "RequestSupport"; 22 | 23 | Link = new ModuleLink(this, Description) 24 | { 25 | Icon = Icons.Material.Filled.SupportAgent, 26 | Render = typeof(RenderSupport), 27 | Order = 3 28 | }; 29 | } 30 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Support/RequestSupport/RenderSupport.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Support.RequestSupport; 6 | 7 | public partial class RenderSupport 8 | { 9 | [Inject] private IOptionsSnapshot AdminOptions { get; set; } = default!; 10 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 11 | 12 | private string WhoUsing { get; set; } = string.Empty; 13 | private string Info { get; set; } = string.Empty; 14 | 15 | private async Task ClusterNameChanged(string clustername) 16 | { 17 | Info = string.Empty; 18 | WhoUsing = string.Empty; 19 | var clusterOptions = PveClientService.GetClusterOptions(clustername)!; 20 | var client = await PveClientService.GetClientAsync(clusterOptions); 21 | if (client != null) 22 | { 23 | WhoUsing = await PveAdminHelper.GenerateWhoUsingAsync(client, AdminOptions.Value); 24 | Info = await PveAdminHelper.GetClusterInfoAsync(client, clusterOptions); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Support/Subscription/Info.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using System.Xml.Serialization; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.Support.Subscription; 8 | 9 | public class Info 10 | { 11 | [XmlElement("status")] 12 | public Status Status { get; set; } 13 | 14 | [XmlElement("validdirectory")] 15 | public string ServerId { get; set; } = default!; 16 | 17 | [XmlElement("productname")] 18 | public string ProductName { get; set; } = default!; 19 | 20 | [XmlIgnore] 21 | public DateTime? RegistrationDate { get; set; } = default!; 22 | 23 | [XmlElement("regdate")] 24 | public string RegistrationDateString 25 | { 26 | get => RegistrationDate?.ToString("yyyy-MM-dd HH:mm:ss") ?? string.Empty; 27 | set => RegistrationDate = DateTime.TryParse(value, out var date) ? date : null; 28 | } 29 | 30 | [XmlIgnore] 31 | public DateTime? NextDueDate { get; set; } = default!; 32 | 33 | [XmlElement("nextduedate")] 34 | public string NextDueDateString 35 | { 36 | get => NextDueDate?.ToString("yyyy-MM-dd HH:mm:ss") ?? string.Empty; 37 | set => NextDueDate = DateTime.TryParse(value, out var date) ? date : null; 38 | } 39 | 40 | [XmlElement("message")] 41 | public string Message { get; set; } = default!; 42 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/Support/Subscription/Status.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.Support.Subscription; 6 | 7 | public enum Status 8 | { 9 | /// subscription set and active 10 | Active, 11 | /// subscription set but invalid for this server 12 | Invalid, 13 | /// subscription set but expired for this server 14 | Expired, 15 | /// subscription got (recently) suspended 16 | Suspended, 17 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/Components/InfoCalculateSnapshots.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @if (Enabled) 8 | { 9 | 10 | @L["Calculation snapshots occupation enabled (require time)!"] 11 | 12 | } 13 | else 14 | { 15 | 16 | @L["Calculation snapshots occupation disabled! (Options cluster for enabled)"] 17 | 18 | } 19 | 20 | @code 21 | { 22 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 23 | 24 | private bool Enabled { get; set; } 25 | 26 | protected override async Task OnInitializedAsync() 27 | { 28 | if (PveClientService != null) 29 | { 30 | var clusterOptions = await PveClientService.GetCurrentClusterOptionsAsync(); 31 | if (clusterOptions != null) { Enabled = clusterOptions.CalculateSnapshotSize; } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/Components/InfoScheduler.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Cronos 6 | @inherits AHComponentBase 7 | 8 | @if (Enabled) 9 | { 10 | @if (CronHelper.IsValid(CronExpression)) 11 | { 12 | 13 |
14 |
15 | 16 | @L["Frequency"]: @CronHelper.GetDescription(CronExpression) 17 |
18 |
19 | 20 | @L["Next Occurrence"]: @CronHelper.NextOccurrence(CronExpression)!.Value.ToString("G") 21 |
22 |
23 |
24 | } 25 | } 26 | else 27 | { 28 | 29 | @L["[Scheduling / Schedule] not active!"] 30 | 31 | } 32 | 33 | @code 34 | { 35 | [Parameter] public bool Enabled { get; set; } 36 | [Parameter] public string CronExpression { get; set; } = default!; 37 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/Layout/PveWidgets.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @if (Valid) 8 | { 9 | @* 10 | 11 | 12 | @L["Subscription Proxmox VE - status Invalid!"] 13 | 14 | 15 | 16 | 17 | 18 | @L["Subscription cv4pve-admin - status Invalid!"] 19 | 20 | 21 | 22 |
23 | *@ 24 | 25 | 26 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/Layout/PveWidgets.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.UI.Layout; 6 | 7 | public partial class PveWidgets 8 | { 9 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 10 | 11 | private bool Valid { get; set; } 12 | private string MailTo { get; set; } = "#"; 13 | 14 | protected override async Task OnInitializedAsync() 15 | { 16 | MailTo = "#"; 17 | try 18 | { 19 | Valid = await PveClientService.ExistsCurrentClusterNameAsync(); 20 | 21 | var data = await PveAdminHelper.GetSupportInfoAsync(await PveClientService.GetClientCurrentClusterAsync()); 22 | MailTo = $"mailto:support@corsinvets.it?subject=Request%20quote%20license&body=" + 23 | data.ToArray().Select(a => Uri.HexEscape(a)).JoinAsString(""); 24 | } 25 | catch { } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/Layout/SelectCluster.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | 10 | 11 | @context.FullName 12 | 13 | 14 | @if (Helper.IsOkSubscriptions(Checks, context)) 15 | { 16 | SUBSCRIPTION OK 17 | } 18 | else 19 | { 20 | NO SUBSCRIPTION 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/Layout/WidgetInfoBase.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @if (Status == null) 8 | { 9 | 10 | } 11 | else 12 | { 13 | 16 | @Description 17 | 18 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/Layout/WidgetInfoBase.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Api; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.UI.Layout; 8 | 9 | public partial class WidgetInfoBase 10 | { 11 | [Parameter] public string Description { get; set; } = default!; 12 | [Parameter] public Func> GetStatus { get; set; } = default!; 13 | 14 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 15 | private bool? Status { get; set; } 16 | 17 | protected override async Task OnInitializedAsync() 18 | { 19 | if (GetStatus != null) 20 | { 21 | Status = await GetStatus(await PveClientService.GetClientCurrentClusterAsync(), await PveClientService.GetCurrentClusterNameAsync()); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/Options/PveModuleClustersOptions.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 8 | 9 | public abstract class PveModuleClustersOptions where T : IClusterName 10 | { 11 | public List Clusters { get; set; } = []; 12 | 13 | public T Get(string clusterName) 14 | { 15 | var ret = Clusters.IsCluster(clusterName); 16 | if (ret == null) 17 | { 18 | ret = Activator.CreateInstance(); 19 | ret.ClusterName = clusterName; 20 | Clusters.Add(ret); 21 | } 22 | 23 | return ret; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/Options/PveOptionsModuleRender.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @typeparam T 8 | 9 | 10 | @foreach (var item in PveClientService.GetClusters()) 11 | { 12 | 13 | @Row(Options.Get(item.Name)) 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/Options/PveOptionsModuleRender.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 8 | 9 | public partial class PveOptionsModuleRender where T : IClusterName 10 | { 11 | [Parameter] public PveModuleClustersOptions Options { get; set; } = default!; 12 | [Parameter] public RenderFragment Row { get; set; } = default!; 13 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 14 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/ProxmoxVE/Cluster/ClusterSelector.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Service; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.UI.ProxmoxVE.Cluster; 8 | 9 | public partial class ClusterSelector 10 | { 11 | [Parameter] public EventCallback ClusterNameChanged { get; set; } 12 | [Parameter] public string ClusterName { get; set; } = default!; 13 | [Parameter] public bool OpenPve { get; set; } 14 | [Parameter] public RenderFragment RenderRow { get; set; } = default!; 15 | 16 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 17 | [Inject] private IBrowserService BrowserService { get; set; } = default!; 18 | 19 | private async Task ValueChanged(string value) 20 | { 21 | ClusterName = await PveClientService.ClusterIsValidAsync(value) 22 | ? value 23 | : string.Empty; 24 | await ClusterNameChanged.InvokeAsync(ClusterName); 25 | StateHasChanged(); 26 | } 27 | 28 | public async Task OpenUrlAsync(ClusterOptions item) => await BrowserService.OpenAsync(PveClientService.GetUrl(item), "_blank"); 29 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/ProxmoxVE/Cluster/Logs.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Domain.Contracts; 6 | using Corsinvest.AppHero.Core.Security.Auth.Permissions; 7 | using Corsinvest.ProxmoxVE.Api; 8 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster; 9 | 10 | namespace Corsinvest.ProxmoxVE.Admin.Core.UI.ProxmoxVE.Cluster; 11 | 12 | public partial class Logs : IRefreshable 13 | { 14 | [EditorRequired][Parameter] public PveClient PveClient { get; set; } = default!; 15 | [Parameter] public PermissionsRead Permissions { get; set; } = default!; 16 | 17 | [Inject] private IDataGridManager DataGridManager { get; set; } = default!; 18 | 19 | public async Task RefreshAsync() => await DataGridManager.RefreshAsync(); 20 | 21 | protected override void OnInitialized() 22 | { 23 | DataGridManager.Title = L["Cluster Log"]; 24 | DataGridManager.DefaultSort = new() { [nameof(ClusterLog.Time)] = true }; 25 | DataGridManager.QueryAsync = async () => await PveClient.Cluster.Log.GetAsync(100); 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/ProxmoxVE/Common/IconStatusResource.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits MudComponentBase 6 | 7 | @* 8 | 9 | *@ 10 | 11 |
12 | 13 | 15 |
-------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/ProxmoxVE/Common/IconStatusResource.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Api.Shared.Utils; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Core.UI.ProxmoxVE.Common; 8 | 9 | public partial class IconStatusResource 10 | { 11 | [Parameter] public string Type { get; set; } = default!; 12 | [Parameter] public string Status { get; set; } = default!; 13 | [Parameter] public bool Locked { get; set; } 14 | 15 | private string GetStyleTypeStatus() 16 | => Status switch 17 | { 18 | var s when s == PveConstants.StatusVmStopped || s == PveConstants.StatusUnknown => "color: #888;", 19 | _ => "", 20 | }; 21 | 22 | private string GetIconType() => PveBlazorHelper.Icons.GetResourceType(Type); 23 | private string GetIconStatus() => PveBlazorHelper.Icons.GetResourceStatus(Status, Locked); 24 | private Color GetColorStatus() => PveBlazorHelper.GetResourcesColorStatus(Status, Locked); 25 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/ProxmoxVE/Storage/Storages.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Security.Auth.Permissions; 6 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Storage; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.Core.UI.ProxmoxVE.Storage; 9 | 10 | public partial class Storages 11 | { 12 | [Parameter] public string Height { get; set; } = default!; 13 | [EditorRequired][Parameter] public Func>> GetItems { get; set; } = default!; 14 | [Parameter] public PermissionsRead Permissions { get; set; } = default!; 15 | 16 | [Inject] private IDataGridManager DataGridManager { get; set; } = default!; 17 | 18 | protected override void OnInitialized() 19 | { 20 | DataGridManager.Title = L["Storages"]; 21 | DataGridManager.DefaultSort = new() { [nameof(StorageItem.Storage)] = false }; 22 | DataGridManager.QueryAsync = GetItems; 23 | } 24 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/ProxmoxVE/Vm/BackupFileRestore.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | 7 | 8 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/ProxmoxVE/Vm/Chart.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using ApexCharts 6 | 7 | @inherits AHComponentBase 8 | 9 |
10 | 11 | 12 | @Title 13 | 14 |
15 | 16 |
17 | 18 | 22 | 29 | 30 | 37 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/ProxmoxVE/Vm/Charts.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | @if (Items != null) 23 | { 24 | @foreach (var item in new[] { VmChart.Cpu, VmChart.Memory, VmChart.DiskIO, /*VmChart.DiskUsage,*/ VmChart.Network }) 25 | { 26 | 27 | 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/ProxmoxVE/Vm/Charts.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Common; 6 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Vm; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.Core.UI.ProxmoxVE.Vm; 9 | 10 | public partial class Charts 11 | { 12 | [Parameter] public Func>> GetItems { get; set; } = default!; 13 | 14 | private RrdDataTimeFrame RrdDataTimeFrame { get; set; } = RrdDataTimeFrame.Day; 15 | private RrdDataConsolidation RrdDataConsolidation { get; set; } = RrdDataConsolidation.Average; 16 | private IEnumerable Items { get; set; } = default!; 17 | 18 | protected override async Task OnInitializedAsync() => await Refresh(); 19 | 20 | public async Task Refresh() 21 | { 22 | Items = null!; 23 | Items = await GetItems(RrdDataTimeFrame, RrdDataConsolidation); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/ProxmoxVE/Vm/ToolBarStatus.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster; 6 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Vm; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.Core.UI.ProxmoxVE.Vm; 9 | 10 | public partial class ToolBarStatus 11 | { 12 | [Parameter] public Size Size { get; set; } = Size.Medium; 13 | [Parameter] public bool CanNoVnc { get; set; } 14 | [Parameter] public bool CanChangeStatus { get; set; } 15 | [Parameter] public IClusterResourceVm Vm { get; set; } = default!; 16 | [Parameter] public EventCallback OnStatusChanged { get; set; } 17 | [Parameter] public RenderFragment ToolBarContent { get; set; } = default!; 18 | [Parameter] public EventCallback OnShowConsole { get; set; } 19 | private async Task ChageStatus(VmStatus status) => await OnStatusChanged.InvokeAsync(status); 20 | } 21 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/UI/ProxmoxVE/Vm/VmChart.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Core.UI.ProxmoxVE.Vm; 6 | 7 | public enum VmChart 8 | { 9 | Memory, 10 | Cpu, 11 | DiskIO, 12 | DiskUsage, 13 | Network 14 | } 15 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/_Import.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Corsinvest.AppHero.Core.BaseUI.DataManager; 6 | global using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 7 | global using Corsinvest.AppHero.Core.Extensions; 8 | global using Corsinvest.ProxmoxVE.Admin.Core.Configurations; 9 | global using Corsinvest.ProxmoxVE.Admin.Core.Helpers; 10 | global using Corsinvest.ProxmoxVE.Admin.Core.Services; 11 | global using Corsinvest.ProxmoxVE.Admin.Core.Extensions; 12 | global using Corsinvest.ProxmoxVE.Api.Extension; 13 | global using Microsoft.AspNetCore.Components; 14 | global using Microsoft.Extensions.Logging; 15 | global using Microsoft.Extensions.Options; 16 | global using MudBlazor; 17 | global using System.ComponentModel.DataAnnotations; 18 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Core/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Corsinvest.AppHero.Core.UI; 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using MudBlazor 8 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Options; 9 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 10 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components.DataGrid 11 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components 12 | @using Corsinvest.AppHero.Core.Helpers; 13 | @using Corsinvest.ProxmoxVE.Api.Shared.Utils; 14 | @using Corsinvest.AppHero.Core.MudBlazorUI.Extensions; 15 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Node; 16 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Vm; 17 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Common; 18 | @using MudExtensions 19 | @using System.Linq.Expressions; 20 | @using MudExtensions.Enums; 21 | @using Corsinvest.ProxmoxVE.Admin.Core.Support.Subscription; 22 | @using Corsinvest.ProxmoxVE.Admin.Core.Models; 23 | 24 | @inject IUINotifier UINotifier 25 | @inject IUIMessageBox UIMessageBox -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Components/RenderIndex.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Components/RenderOptions.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Extensions; 6 | using Corsinvest.ProxmoxVE.Api.Shared.Utils; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.Diagnostic.Components; 9 | 10 | public partial class RenderOptions 11 | { 12 | [Inject] private IJobService JobService { get; set; } = default!; 13 | 14 | private string[] ThresholdTexts { get; } = ["CPU", "Memory", "Network"]; 15 | private string[] ThresholdIcons { get; } = [PveBlazorHelper.Icons.Cpu, PveBlazorHelper.Icons.Memory, PveBlazorHelper.Icons.Network]; 16 | 17 | public override async Task SaveAsync() 18 | { 19 | foreach (var item in Options.Clusters) 20 | { 21 | JobService.ScheduleOrRemove(a => a.Create(item.ClusterName), item.CronExpression, item.Enabled, item.ClusterName); 22 | } 23 | 24 | await base.SaveAsync(); 25 | } 26 | 27 | private static string GetIconType(int index) 28 | => PveBlazorHelper.Icons.GetResourceType(new[] { PveConstants.KeyApiNode, PveConstants.KeyApiQemu, PveConstants.KeyApiLxc }[index]); 29 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Components/RenderWidget.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 |
8 |
9 | @L["Warning:"] 10 | @Last?.Warning 11 |
12 | 13 |
14 | @L["Critical:"] 15 | @Last?.Critical 16 |
17 | 18 |
19 | @L["Info:"] 20 | @Last?.Info 21 |
22 | 23 | @L["Exec.:"] @Count 24 |
25 | 26 |
27 | @L["Last:"] @Last?.Date 28 | 29 | @L["Scheduled:"] 30 | 31 |
-------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Components/RenderWidget.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Services; 6 | using Corsinvest.ProxmoxVE.Admin.Diagnostic.Repository; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.Diagnostic.Components; 9 | 10 | public partial class RenderWidget 11 | { 12 | [Inject] private IReadRepository Execution { get; set; } = default!; 13 | [Inject] private IOptionsSnapshot Options { get; set; } = default!; 14 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 15 | 16 | private Execution? Last { get; set; } 17 | private ModuleClusterOptions ModuleClusterOptions { get; set; } = new(); 18 | private int Count { get; set; } 19 | 20 | protected override async Task OnInitializedAsync() 21 | { 22 | var clusterName = await PveClientService.GetCurrentClusterNameAsync(); 23 | ModuleClusterOptions = Options.Value.Get(clusterName); 24 | Count = await Execution.CountAsync(new ExecutionSpec(clusterName)); 25 | Last = await Execution.FirstOrDefaultAsync(new ExecutionSpec(clusterName).Last()); 26 | } 27 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Corsinvest.ProxmoxVE.Admin.Diagnostic.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | all 9 | runtime; build; native; contentfiles; analyzers; buildtransitive 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Doc.txt: -------------------------------------------------------------------------------- 1 | dotnet ef migrations Add Initial --startup-project ..\Corsinvest.ProxmoxVE.Admin -c DiagnosticDbContext -v -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Job.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Diagnostic; 6 | 7 | internal class Job(IServiceScopeFactory scopeFactory) 8 | { 9 | private static bool ModuleEnabled(IServiceScope scope) => scope.GetModule()!.Enabled; 10 | 11 | public async Task Create(string clusterName) 12 | { 13 | using var scope = scopeFactory.CreateScope(); 14 | if (ModuleEnabled(scope)) { await Helper.Create(scope, clusterName); } 15 | } 16 | 17 | public async Task Delete(IEnumerable ids) 18 | { 19 | using var scope = scopeFactory.CreateScope(); 20 | await Helper.Delete(scope, ids); 21 | } 22 | 23 | public async Task Rescan(string clusterName) 24 | { 25 | using var scope = scopeFactory.CreateScope(); 26 | await Helper.Rescan(scope, clusterName); 27 | } 28 | 29 | public static void ScheduleRescan(IJobService JobService, string clusterName) 30 | => JobService.Schedule(a => a.Rescan(clusterName), TimeSpan.FromSeconds(10)); 31 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Models/Execution.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Domain.Entities; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Diagnostic.Models; 8 | 9 | public class Execution : EntityBase, IClusterName 10 | { 11 | [Required] 12 | public string ClusterName { get; set; } = default!; 13 | 14 | public int Warning { get; set; } 15 | public int Critical { get; set; } 16 | public int Info { get; set; } 17 | public DateTime Date { get; set; } 18 | 19 | [Required] 20 | public ExecutionData Data { get; set; } = default!; 21 | } 22 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Models/ExecutionData.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Domain.Entities; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Diagnostic.Models; 8 | 9 | public class ExecutionData : EntityBase 10 | { 11 | public int ExecutionId { get; set; } 12 | 13 | [Required] 14 | public Execution Execution { get; set; } = default!; 15 | 16 | public string Data { get; set; } = default!; 17 | } 18 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Models/IgnoredIssue.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Domain.Entities; 6 | using Corsinvest.ProxmoxVE.Diagnostic.Api; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.Diagnostic.Models; 9 | 10 | public class IgnoredIssue : EntityBase, IClusterName 11 | { 12 | [Required] 13 | public string ClusterName { get; set; } = default!; 14 | 15 | public string? IdResource { get; set; } 16 | public DiagnosticResultGravity Gravity { get; set; } 17 | public DiagnosticResultContext Context { get; set; } 18 | public string? SubContext { get; set; } 19 | public string? Description { get; set; } 20 | 21 | public DiagnosticResult ToDiagnosticResult() 22 | => new() 23 | { 24 | Context = Context, 25 | Description = Description, 26 | Gravity = Gravity, 27 | SubContext = SubContext, 28 | Id = IdResource 29 | }; 30 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Options.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Notification; 6 | using Corsinvest.AppHero.Core.Validators; 7 | using Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 8 | using Newtonsoft.Json; 9 | using DiagnosticApiOptions = Corsinvest.ProxmoxVE.Diagnostic.Api.Settings; 10 | 11 | namespace Corsinvest.ProxmoxVE.Admin.Diagnostic; 12 | 13 | public class Options : PveModuleClustersOptions { } 14 | 15 | public class ModuleClusterOptions : DiagnosticApiOptions, IClusterName, INotificationChannelsOptions 16 | { 17 | public string ClusterName { get; set; } = default!; 18 | 19 | [Required] 20 | [Display(Name = "Cron Schedule")] 21 | [CronExpressionValidator] 22 | public string CronExpression { get; set; } = default!; 23 | 24 | [Display(Name = "Enabled")] 25 | public bool Enabled { get; set; } 26 | 27 | [Display(Name = "Number which should will keep")] 28 | public int Keep { get; set; } = 30; 29 | 30 | public IEnumerable NotificationChannels { get; set; } = default!; 31 | } 32 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Persistence/DiagnosticDbContext.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Diagnostic.Persistence; 8 | 9 | public class DiagnosticDbContext(DbContextOptions options) : DbContext(options) 10 | { 11 | public DbSet Executions { get; set; } = default!; 12 | public DbSet ExecutionDatas { get; set; } = default!; 13 | public DbSet IgnoredIssues { get; set; } = default!; 14 | 15 | protected override void OnModelCreating(ModelBuilder modelBuilder) 16 | { 17 | base.OnModelCreating(modelBuilder); 18 | modelBuilder.UseCollation("NOCASE"); 19 | 20 | modelBuilder.Entity() 21 | .HasOne(a => a.Data) 22 | .WithOne(a => a.Execution) 23 | .HasForeignKey(a => a.ExecutionId) 24 | .OnDelete(DeleteBehavior.Cascade); 25 | } 26 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Repository/ExecutionSpec.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Ardalis.Specification; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.Diagnostic.Repository; 8 | 9 | internal class ExecutionSpec(string clusterName) : ClusterByNameSpec(clusterName) 10 | { 11 | public ExecutionSpec(string clusterName, int keep) : this(clusterName) 12 | => Query.OrderByDescending(a => a.Date) 13 | .Skip(keep); 14 | 15 | public ExecutionSpec Last() 16 | { 17 | Query.OrderBy(a => a.Date); 18 | return this; 19 | } 20 | 21 | public ExecutionSpec Include() 22 | { 23 | Query.Include(a => a.Data); 24 | return this; 25 | } 26 | 27 | public ExecutionSpec ByKey(int id) 28 | { 29 | Query.Where(a => a.Id == id); 30 | return this; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/Repository/IgnoredIssueSpec.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.Diagnostic.Repository; 6 | 7 | internal class IgnoredIssueSpec(string clusterName) : ClusterByNameSpec(clusterName) 8 | { 9 | } 10 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Corsinvest.AppHero.Core.BackgroundJob; 6 | global using Corsinvest.AppHero.Core.BaseUI.DataManager; 7 | global using Corsinvest.AppHero.Core.Domain.Repository; 8 | global using Corsinvest.AppHero.Core.Extensions; 9 | global using Corsinvest.AppHero.Core.Modularity; 10 | global using Corsinvest.AppHero.Core.Options; 11 | global using Corsinvest.AppHero.Core.UI; 12 | global using Corsinvest.ProxmoxVE.Admin.Core.Helpers; 13 | global using Corsinvest.ProxmoxVE.Admin.Core.Repository; 14 | global using Corsinvest.ProxmoxVE.Admin.Diagnostic.Models; 15 | global using Corsinvest.ProxmoxVE.Admin.Diagnostic.Persistence; 16 | global using Microsoft.AspNetCore.Components; 17 | global using Microsoft.Extensions.DependencyInjection; 18 | global using Microsoft.Extensions.Localization; 19 | global using Microsoft.Extensions.Options; 20 | global using MudBlazor; 21 | global using System.ComponentModel.DataAnnotations; 22 | global using System.Text.RegularExpressions; 23 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.Diagnostic/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Corsinvest.AppHero.Core.UI; 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using MudBlazor 8 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components 9 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Options 10 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components 11 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components.DataGrid 12 | @using Corsinvest.ProxmoxVE.Admin.Diagnostic.Models 13 | @using Corsinvest.AppHero.Core.MudBlazorUI.Extensions; 14 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 15 | @using MudExtensions 16 | 17 | @inject IUINotifier UINotifier 18 | @inject IUIMessageBox UIMessageBox -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.DisksStatus/Components/DiskSmarts.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Api; 6 | using Corsinvest.ProxmoxVE.Api.Extension; 7 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Node; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.DisksStatus.Components; 10 | 11 | public partial class DiskSmarts 12 | { 13 | [Parameter] public string Node { get; set; } = default!; 14 | [Parameter] public string Disk { get; set; } = default!; 15 | [Parameter] public PveClient PveClient { get; set; } = default!; 16 | 17 | [Inject] private IDataGridManager DataGridManager { get; set; } = default!; 18 | private NodeDiskSmart Data { get; set; } = default!; 19 | 20 | protected override async Task OnInitializedAsync() 21 | { 22 | var data = await PveClient.Nodes[Node].Disks.Smart.GetAsync(Disk); 23 | data.Text = (data.Text + "").Replace("\n", "
"); 24 | Data = data; 25 | 26 | if (Data.Attributes != null) 27 | { 28 | DataGridManager.Title = L["Smarts"]; 29 | DataGridManager.DefaultSort = new() { [nameof(NodeDiskSmart.NodeDiskSmartAttribute.Name)] = false }; 30 | DataGridManager.QueryAsync = async () => await Task.FromResult(Data.Attributes); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.DisksStatus/Components/RenderIndex.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Api; 6 | using Corsinvest.ProxmoxVE.Api.Extension; 7 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.DisksStatus.Components; 10 | 11 | public partial class RenderIndex 12 | { 13 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 14 | private PveClient PveClient { get; set; } = default!; 15 | protected override async Task OnInitializedAsync() 16 | { 17 | try 18 | { 19 | PveClient = await PveClientService.GetClientCurrentClusterAsync(); 20 | } 21 | catch { } 22 | } 23 | 24 | public async Task> GetNodes() => (await PveClient.GetResourcesAsync(ClusterResourceType.Node)).Where(a => a.IsOnline); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.DisksStatus/Corsinvest.ProxmoxVE.Admin.DisksStatus.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.DisksStatus/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Corsinvest.AppHero.Core.BaseUI.DataManager; 6 | global using Corsinvest.ProxmoxVE.Admin.Core.Services; 7 | global using Microsoft.AspNetCore.Components; 8 | global using MudBlazor; 9 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.DisksStatus/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using MudBlazor 7 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Options; 8 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components; 9 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 10 | @using Corsinvest.AppHero.Core.UI; 11 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components.DataGrid; 12 | @using Corsinvest.AppHero.Core.MudBlazorUI.Extensions; 13 | @using Corsinvest.ProxmoxVE.Api.Shared.Utils; 14 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster; 15 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Node 16 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 17 | 18 | @inject IUINotifier UINotifier 19 | @inject IUIMessageBox UIMessageBox -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.MetricsExporter/Components/RenderIndex.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @if (ClusterOptions != null) 8 | { 9 | @L["Prometeus Exporter"] 10 | @ClusterOptions.FullName 11 | } 12 | 13 | @code 14 | { 15 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 16 | 17 | private ClusterOptions ClusterOptions { get; set; } = default!; 18 | 19 | protected override async Task OnInitializedAsync() => ClusterOptions = (await PveClientService.GetCurrentClusterOptionsAsync())!; 20 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.MetricsExporter/Components/RenderWidget.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @L["Request:"] @Info?.CountRequest 8 | @L["Last:"] @Info?.LastRequest 9 | 10 | @code 11 | { 12 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 13 | 14 | private Info Info { get; set; } = default!; 15 | 16 | protected override async Task OnInitializedAsync() 17 | { 18 | if (Module.Infos.TryGetValue(await PveClientService.GetCurrentClusterNameAsync(), out var info)) 19 | { 20 | Info = info; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.MetricsExporter/Corsinvest.ProxmoxVE.Admin.MetricsExporter.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.MetricsExporter/Info.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Prometheus; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.MetricsExporter; 8 | 9 | public class Info 10 | { 11 | public DateTime? LastRequest { get; set; } 12 | public long CountRequest { get; set; } 13 | public CollectorRegistry Registry { get; set; } = default!; 14 | } 15 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.MetricsExporter/Options.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 6 | using Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 7 | using System.ComponentModel.DataAnnotations; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.MetricsExporter; 10 | 11 | public class Options : PveModuleClustersOptions { } 12 | 13 | public class ModuleClusterOptions : IClusterName 14 | { 15 | public string ClusterName { get; set; } = default!; 16 | 17 | //[Display(Name = "Prometheus Exporter Node Disk Info (require more time)")] 18 | //public bool PrometheusExporterNodeDiskInfo { get; set; } 19 | 20 | [Display(Name = "Prometheus Exporter Prefix")] 21 | public string PrometheusExporterPrefix { get; set; } = "cv4pve"; 22 | } 23 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.MetricsExporter/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Microsoft.Extensions.Options; 6 | global using MudBlazor; -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.MetricsExporter/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using MudBlazor 7 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 8 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Options; 9 | @using Corsinvest.ProxmoxVE.Admin.Core.Services; 10 | @using Corsinvest.ProxmoxVE.Admin.Core.Configurations; 11 | @using Corsinvest.ProxmoxVE.Admin.Core.UI.Options 12 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 13 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeFreeMemory/Corsinvest.ProxmoxVE.Admin.NodeFreeMemory.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeFreeMemory/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Corsinvest.ProxmoxVE.Admin.Core.Services; 6 | global using Microsoft.AspNetCore.Components; 7 | global using MudBlazor; 8 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeFreeMemory/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Corsinvest.AppHero.Core.UI; 6 | @using Microsoft.AspNetCore.Components 7 | @using MudBlazor 8 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 9 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components 10 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components.DataGrid 11 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster; 12 | @using Corsinvest.AppHero.Core.MudBlazorUI.Extensions; 13 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 14 | 15 | @inject IUINotifier UINotifier 16 | @inject IUIMessageBox UIMessageBox -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeProtect/Components/RenderOptions.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Extensions; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.NodeProtect.Components; 8 | 9 | public partial class RenderOptions 10 | { 11 | [Inject] private IJobService JobService { get; set; } = default!; 12 | 13 | public override async Task SaveAsync() 14 | { 15 | foreach (var item in Options.Clusters) 16 | { 17 | JobService.ScheduleOrRemove(a => a.Protect(item.ClusterName), item.CronExpression, item.Enabled, item.ClusterName); 18 | } 19 | 20 | await base.SaveAsync(); 21 | } 22 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeProtect/Components/Widget.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @L["Saved:"] @Count 8 |
9 | @L["Last:"] @Last 10 | @L["Scheduled:"] 11 | 12 |
-------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeProtect/Components/Widget.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Domain.Repository; 6 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 7 | using Corsinvest.ProxmoxVE.Admin.Core.Services; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.NodeProtect.Components; 10 | 11 | public partial class Widget 12 | { 13 | [Inject] private IReadRepository JobHistories { get; set; } = default!; 14 | [Inject] private IOptionsSnapshot Options { get; set; } = default!; 15 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 16 | private string Last { get; set; } = default!; 17 | private bool Enabled { get; set; } 18 | private int Count { get; set; } 19 | 20 | protected override async Task OnInitializedAsync() 21 | { 22 | var clusterName = await PveClientService.GetCurrentClusterNameAsync(); 23 | 24 | Enabled = Options.Value.Get(clusterName).Enabled; 25 | var spec = new ClusterByNameSpec(clusterName); 26 | Count = await JobHistories.CountAsync(spec); 27 | 28 | var item = (await JobHistories.ListAsync(spec)).OrderByDescending(a => a.Start).FirstOrDefault(); 29 | Last = item == null 30 | ? "-" 31 | : item.Start.ToString(); 32 | } 33 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeProtect/Corsinvest.ProxmoxVE.Admin.NodeProtect.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | all 9 | runtime; build; native; contentfiles; analyzers; buildtransitive 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeProtect/Doc.txt: -------------------------------------------------------------------------------- 1 | dotnet ef migrations Add Initial --startup-project ..\Corsinvest.ProxmoxVE.Admin -c NodeProtectDbContext -v -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeProtect/Job.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Extensions; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.NodeProtect; 8 | 9 | internal class Job(IServiceScopeFactory scopeFactory) 10 | { 11 | private static bool ModuleEnabled(IServiceScope scope) => scope.GetModule()!.Enabled; 12 | 13 | public async Task Protect(string clusterName) 14 | { 15 | using var scope = scopeFactory.CreateScope(); 16 | if (ModuleEnabled(scope)) { await Helper.Protect(scope, clusterName); } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeProtect/Models/NodeProtectJobHistory.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Domain.Entities; 6 | using Corsinvest.AppHero.Core.Domain.Models; 7 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 8 | using Corsinvest.ProxmoxVE.Api.Shared.Utils; 9 | using System.ComponentModel.DataAnnotations.Schema; 10 | 11 | namespace Corsinvest.ProxmoxVE.Admin.NodeProtect.Models; 12 | 13 | public class NodeProtectJobHistory : JobHistory, IAggregateRoot, IClusterName 14 | { 15 | [Required] 16 | public int Id { get; set; } 17 | 18 | [Required] 19 | public string ClusterName { get; set; } = default!; 20 | 21 | [Required] 22 | public string JobId { get; set; } = default!; 23 | 24 | [Required] 25 | public string IpAddress { get; set; } = default!; 26 | public long Size { get; set; } 27 | 28 | [NotMapped] 29 | [Display(Name = "Size")] 30 | public string SizeText => FormatHelper.FromBytes(Size); 31 | 32 | public string FileName { get; set; } = default!; 33 | 34 | public string GetPath() => Helper.GetPath(ClusterName, JobId, FileName); 35 | public string GetDirectoryWorkJobId() => Helper.GetDirectoryWorkJobId(ClusterName, JobId); 36 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeProtect/Options.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Validators; 6 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 7 | using Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 8 | using Newtonsoft.Json; 9 | 10 | namespace Corsinvest.ProxmoxVE.Admin.NodeProtect; 11 | 12 | public class Options : PveModuleClustersOptions { } 13 | 14 | public class ModuleClusterOptions : IClusterName 15 | { 16 | public string ClusterName { get; set; } = default!; 17 | 18 | [Required] 19 | [Display(Name = "Cron Schedule")] 20 | [CronExpressionValidator] 21 | public string CronExpression { get; set; } = default!; 22 | 23 | [Display(Name = "Enabled")] 24 | public bool Enabled { get; set; } 25 | 26 | [Display(Name = "Directory or file to backup")] 27 | public string PathsToBackup { get; set; } = @"/etc/. 28 | /var/lib/pve-cluster/. 29 | /var/lib/ceph/."; 30 | 31 | [Display(Name = "Number which should will keep")] 32 | public int Keep { get; set; } = 30; 33 | 34 | public IEnumerable NotificationChannels { get; set; } = default!; 35 | } 36 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeProtect/Persistence/NodeProtectDbContext.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.NodeProtect.Persistence; 8 | 9 | internal class NodeProtectDbContext(DbContextOptions options) : DbContext(options) 10 | { 11 | public DbSet JobHistories { get; set; } = default!; 12 | 13 | protected override void OnModelCreating(ModelBuilder modelBuilder) 14 | { 15 | base.OnModelCreating(modelBuilder); 16 | modelBuilder.UseCollation("NOCASE"); 17 | } 18 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeProtect/Repository/NodeProtectJobHistorySpec.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Ardalis.Specification; 6 | using Corsinvest.ProxmoxVE.Admin.Core.Repository; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.NodeProtect.Repository; 9 | 10 | internal class NodeProtectJobHistorySpec : ClusterByNameSpec 11 | { 12 | public NodeProtectJobHistorySpec(string clusterName) : base(clusterName) 13 | => Query.OrderByDescending(a => a.End); 14 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeProtect/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Corsinvest.AppHero.Core.BackgroundJob; 6 | global using Corsinvest.ProxmoxVE.Admin.Core.Configurations; 7 | global using Corsinvest.ProxmoxVE.Admin.Core.Helpers; 8 | global using Corsinvest.ProxmoxVE.Admin.NodeProtect.Models; 9 | global using Microsoft.AspNetCore.Components; 10 | global using Microsoft.Extensions.DependencyInjection; 11 | global using Microsoft.Extensions.Logging; 12 | global using Microsoft.Extensions.Options; 13 | global using MudBlazor; 14 | global using System.ComponentModel.DataAnnotations; 15 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.NodeProtect/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using MudBlazor 7 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Options; 8 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components; 9 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 10 | @using Corsinvest.AppHero.Core.UI; 11 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components.DataGrid; 12 | @using Corsinvest.AppHero.Core.MudBlazorUI.Extensions; 13 | @using Corsinvest.ProxmoxVE.Api.Shared.Utils; 14 | @using Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 15 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 16 | 17 | @inject IUINotifier UINotifier 18 | @inject IUIMessageBox UIMessageBox -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.QemuMonitor/Corsinvest.ProxmoxVE.Admin.QemuMonitor.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.QemuMonitor/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Microsoft.AspNetCore.Components; 6 | global using MudBlazor; 7 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.QemuMonitor/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using MudBlazor 7 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 8 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components.DataGrid 9 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components 10 | @using Corsinvest.ProxmoxVE.Api.Shared.Utils; 11 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 12 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ReplicationTrend/Components/RenderIndex.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 |
21 |
22 | 23 |
-------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ReplicationTrend/Components/RenderOptions.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.BackgroundJob; 6 | using Corsinvest.ProxmoxVE.Admin.Core.Extensions; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.ReplicationTrend.Components; 9 | 10 | public partial class RenderOptions 11 | { 12 | [Inject] private IJobService JobService { get; set; } = default!; 13 | 14 | public override async Task SaveAsync() 15 | { 16 | foreach (var item in Options.Clusters) 17 | { 18 | JobService.ScheduleOrRemove(a => a.Scan(item.ClusterName), item.CronExpression, item.Enabled, item.ClusterName); 19 | } 20 | await base.SaveAsync(); 21 | } 22 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ReplicationTrend/Components/RenderWidget.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 |
8 | @L["Last day:"] 9 | 10 |
11 | @CountOk 12 | 13 | 14 | @CountKo 15 | 16 |
17 |
18 | 19 | @L["Last:"] @Last -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ReplicationTrend/Components/RenderWidget.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.Services; 6 | using Corsinvest.ProxmoxVE.Admin.ReplicationTrend.Repository; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.ReplicationTrend.Components; 9 | 10 | public partial class RenderWidget 11 | { 12 | [Inject] private IReadRepository ReplicationResults { get; set; } = default!; 13 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 14 | 15 | private string Last { get; set; } = default!; 16 | private int CountOk { get; set; } 17 | private int CountKo { get; set; } 18 | 19 | protected override async Task OnInitializedAsync() 20 | { 21 | var clusterName = await PveClientService.GetCurrentClusterNameAsync(); 22 | 23 | var date = DateTime.Now.AddDays(-1); 24 | CountOk = await ReplicationResults.CountAsync(new ReplicationResultSpec(clusterName, true, date)); 25 | CountKo = await ReplicationResults.CountAsync(new ReplicationResultSpec(clusterName, false, date)); 26 | var item = await ReplicationResults.FirstOrDefaultAsync(new ReplicationResultSpec(clusterName).OrderDescStart()); 27 | if (item != null) { Last = item.Start.ToString()!; } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ReplicationTrend/Corsinvest.ProxmoxVE.Admin.ReplicationTrend.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | true 5 | Library 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ReplicationTrend/Doc.txt: -------------------------------------------------------------------------------- 1 | dotnet ef migrations Add Initial --startup-project ..\Corsinvest.ProxmoxVE.Admin -c ReplicationTrendDbContext -v -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ReplicationTrend/Job.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.ReplicationTrend; 6 | 7 | internal class Job(IServiceScopeFactory scopeFactory) 8 | { 9 | private static bool ModuleEnabled(IServiceScope scope) => scope.GetModule()!.Enabled; 10 | 11 | public async Task Scan(string clusterName) 12 | { 13 | using var scope = scopeFactory.CreateScope(); 14 | if (ModuleEnabled(scope)) { await Helper.Scan(scope, clusterName); } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ReplicationTrend/Models/ReplicationResult.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Domain.Entities; 6 | using Corsinvest.ProxmoxVE.Api.Shared.Utils; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.ReplicationTrend.Models; 9 | 10 | public class ReplicationResult : EntityBase, IClusterName 11 | { 12 | [Required] 13 | public string ClusterName { get; set; } = default!; 14 | 15 | public string JobId { get; set; } = default!; 16 | public DateTime Start { get; set; } 17 | public DateTime? End { get; set; } 18 | public double DurationCalc => End.HasValue ? (End - Start).Value.TotalSeconds : 0; 19 | public double Duration { get; set; } 20 | 21 | [Display(Name = "Duration")] 22 | public string DurationText 23 | => End.HasValue 24 | ? (End - Start).Value.ToString("hh':'mm':'ss") 25 | : "00:00:00"; 26 | 27 | public string VmId { get; set; } = default!; 28 | public double Size { get; set; } 29 | 30 | [Display(Name = "Size")] 31 | public string SizeString => FormatHelper.FromBytes(Size); 32 | 33 | public string Log { get; set; } = default!; 34 | public DateTime LastSync { get; set; } 35 | public string? Error { get; set; } 36 | public bool Status { get; set; } 37 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ReplicationTrend/Options.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Validators; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.ReplicationTrend; 8 | 9 | public class Options : PveModuleClustersOptions { } 10 | 11 | public class ModuleClusterOptions : IClusterName 12 | { 13 | public string ClusterName { get; set; } = default!; 14 | 15 | [Display(Name = "Enabled")] 16 | public bool Enabled { get; set; } 17 | 18 | [Required] 19 | [Display(Name = "Cron Schedule")] 20 | [CronExpressionValidator] 21 | public string CronExpression { get; set; } = "*/5 * * * *"; 22 | 23 | [Display(Name = "Max days logs")] 24 | public int MaxDaysLogs { get; set; } = 30; 25 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ReplicationTrend/Persistence/ReplicationTrendDbContext.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.ReplicationTrend.Persistence; 8 | 9 | public class ReplicationTrendDbContext(DbContextOptions options) : DbContext(options) 10 | { 11 | public DbSet ReplicationResults { get; set; } = default!; 12 | 13 | protected override void OnModelCreating(ModelBuilder modelBuilder) 14 | { 15 | base.OnModelCreating(modelBuilder); 16 | 17 | modelBuilder.UseCollation("NOCASE"); 18 | 19 | modelBuilder.Entity().HasIndex(a => a.LastSync); 20 | modelBuilder.Entity().HasIndex(a => a.Start); 21 | modelBuilder.Entity().HasIndex(a => a.End); 22 | modelBuilder.Entity().HasIndex(a => a.VmId); 23 | } 24 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ReplicationTrend/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Corsinvest.AppHero.Core.BaseUI.DataManager; 6 | global using Corsinvest.AppHero.Core.Domain.Repository; 7 | global using Corsinvest.AppHero.Core.Extensions; 8 | global using Corsinvest.ProxmoxVE.Admin.Core.Repository; 9 | global using Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 10 | global using Corsinvest.ProxmoxVE.Admin.ReplicationTrend.Models; 11 | global using Microsoft.AspNetCore.Components; 12 | global using Microsoft.Extensions.DependencyInjection; 13 | global using Microsoft.Extensions.Options; 14 | global using MudBlazor; 15 | global using System.ComponentModel.DataAnnotations; 16 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.ReplicationTrend/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Corsinvest.AppHero.Core.UI; 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using MudBlazor 8 | @using Corsinvest.ProxmoxVE.Admin.Core.UI.Options 9 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Options; 10 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components; 11 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 12 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components.DataGrid 13 | @using Corsinvest.ProxmoxVE.Admin.ReplicationTrend.Models; 14 | @using Corsinvest.ProxmoxVE.Api.Shared.Utils; 15 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster; 16 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Node; 17 | 18 | @* 19 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster 20 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Node 21 | @using Corsinvest.AppHero.Core.MudBlazorUI.Extensions; 22 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 23 | *@ 24 | 25 | @inject IUINotifier UINotifier 26 | @inject IUIMessageBox UIMessageBox -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VmUnlock/Corsinvest.ProxmoxVE.Admin.VmUnlock.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VmUnlock/RenderIndex.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Admin.Core.UI.ProxmoxVE.Cluster; 6 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.VmUnlock; 9 | 10 | public partial class RenderIndex 11 | { 12 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 13 | 14 | private Resources? RefResources { get; set; } = default!; 15 | private bool LoadingUnlock { get; set; } 16 | 17 | private async Task> GetItems() => await Helper.GetVmLocks(await PveClientService.GetClientCurrentClusterAsync()); 18 | 19 | private async Task UnlockAsync() 20 | { 21 | LoadingUnlock = true; 22 | if (await UIMessageBox.ShowQuestionAsync(L["Unlock"], L["Unlock VM/CT?"])) 23 | { 24 | await Helper.Unlock(await PveClientService.GetClientCurrentClusterAsync(), RefResources!.DataGridManager.SelectedItems); 25 | RefResources!.DataGridManager.SelectedItems.Clear(); 26 | await RefResources!.DataGridManager.RefreshAsync(); 27 | } 28 | LoadingUnlock = false; 29 | } 30 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VmUnlock/Widget.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 | @if (Count >= 0) 8 | { 9 |   10 |
11 | @L["VM/CT:"] @Count @Locks 12 | 14 |
15 | } 16 | else 17 | { 18 | 19 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VmUnlock/Widget.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Extensions; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.VmUnlock; 8 | 9 | public partial class Widget 10 | { 11 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 12 | 13 | private int Count { get; set; } = -1; 14 | private string? Locks { get; set; } 15 | 16 | protected override async Task OnInitializedAsync() 17 | { 18 | var data = await Helper.GetVmLocks(await PveClientService.GetClientCurrentClusterAsync()); 19 | Count = data.Count(); 20 | Locks = data.Select(a => a.Lock).Distinct().JoinAsString(","); 21 | } 22 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VmUnlock/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Corsinvest.ProxmoxVE.Admin.Core.Services; 6 | global using Microsoft.AspNetCore.Components; 7 | global using MudBlazor; 8 | //global using ClasterStatusModel = Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster.ClusterStatus; 9 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VmUnlock/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Corsinvest.AppHero.Core.UI; 6 | @using Microsoft.AspNetCore.Components 7 | @using MudBlazor 8 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 9 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components 10 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components.DataGrid 11 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster; 12 | @using Corsinvest.AppHero.Core.MudBlazorUI.Extensions; 13 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 14 | 15 | @inject IUINotifier UINotifier 16 | @inject IUIMessageBox UIMessageBox -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/Components/ClusterBackups.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.ProxmoxVE.Api; 6 | using Corsinvest.ProxmoxVE.Api.Extension; 7 | using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.VzDumpTrend.Components; 10 | 11 | public partial class ClusterBackups 12 | { 13 | [Parameter] public string Height { get; set; } = default!; 14 | [EditorRequired][Parameter] public PveClient PveClient { get; set; } = default!; 15 | 16 | [Inject] private IDataGridManager DataGridManager { get; set; } = default!; 17 | 18 | protected override void OnInitialized() 19 | { 20 | DataGridManager.Title = L["VZ Dump Trend"]; 21 | DataGridManager.QueryAsync = async () => (await PveClient.Cluster.Backup.GetAsync()).OrderBy(a => a.Id); 22 | } 23 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/Components/RenderOptions.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.BackgroundJob; 6 | using Corsinvest.ProxmoxVE.Admin.Core.Extensions; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.VzDumpTrend.Components; 9 | 10 | public partial class RenderOptions 11 | { 12 | [Inject] private IJobService JobService { get; set; } = default!; 13 | 14 | public override async Task SaveAsync() 15 | { 16 | foreach (var item in Options.Clusters) 17 | { 18 | JobService.ScheduleOrRemove(a => a.Scan(item.ClusterName), item.CronExpression, item.Enabled, item.ClusterName); 19 | } 20 | await base.SaveAsync(); 21 | } 22 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/Components/RenderWidget.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @inherits AHComponentBase 6 | 7 |
8 | @L["Last month:"] 9 | 10 |
11 | @CountOk 12 | 13 | 14 | @CountKo 15 | 16 |
17 |
18 | 19 | @L["Last:"] @Last -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/Components/RenderWidget.razor.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Domain.Repository; 6 | using Corsinvest.ProxmoxVE.Admin.Core.Services; 7 | using Corsinvest.ProxmoxVE.Admin.VzDumpTrend.Repository; 8 | 9 | namespace Corsinvest.ProxmoxVE.Admin.VzDumpTrend.Components; 10 | 11 | public partial class RenderWidget 12 | { 13 | [Inject] private IReadRepository VzDumpDetails { get; set; } = default!; 14 | [Inject] private IPveClientService PveClientService { get; set; } = default!; 15 | 16 | private string Last { get; set; } = default!; 17 | private int CountOk { get; set; } 18 | private int CountKo { get; set; } 19 | 20 | protected override async Task OnInitializedAsync() 21 | { 22 | var clusterName = await PveClientService.GetCurrentClusterNameAsync(); 23 | 24 | var date = DateTime.Now.AddDays(-30); 25 | CountOk = await VzDumpDetails.CountAsync(new VzDumpDetailSpec(clusterName, true, date)); 26 | CountKo = await VzDumpDetails.CountAsync(new VzDumpDetailSpec(clusterName, false, date)); 27 | var item = await VzDumpDetails.FirstOrDefaultAsync(new VzDumpDetailSpec(clusterName).OrderDescStart()); 28 | if (item != null) { Last = item.Start.ToString()!; } 29 | } 30 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/Corsinvest.ProxmoxVE.Admin.VzDumpTrend.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/Doc.txt: -------------------------------------------------------------------------------- 1 | dotnet ef migrations Add Initial --startup-project ..\Corsinvest.ProxmoxVE.Admin -c VzDumpTrendDbContext -v -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/Job.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | namespace Corsinvest.ProxmoxVE.Admin.VzDumpTrend; 6 | 7 | internal class Job(IServiceScopeFactory scopeFactory) 8 | { 9 | private static bool ModuleEnabled(IServiceScope scope) => scope.GetModule()!.Enabled; 10 | 11 | public async Task Scan(string clusterName) 12 | { 13 | using var scope = scopeFactory.CreateScope(); 14 | if (ModuleEnabled(scope)) { await Helper.Scan(scope, clusterName); } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/Models/VzDumpTask.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Domain.Entities; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.VzDumpTrend.Models; 8 | 9 | public class VzDumpTask : EntityBase, IClusterName 10 | { 11 | [Required] 12 | public string ClusterName { get; set; } = default!; 13 | 14 | public DateTime Start { get; set; } 15 | public DateTime? End { get; set; } 16 | public double Duration => End.HasValue ? (End - Start).Value.TotalSeconds : 0; 17 | public string? TaskId { get; set; } 18 | public string? Status { get; set; } 19 | public string? Node { get; set; } 20 | public string? Log { get; set; } 21 | public string? Storage { get; set; } 22 | public List Details { get; set; } = []; 23 | } 24 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/Options.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Core.Validators; 6 | using Corsinvest.ProxmoxVE.Admin.Core.UI.Options; 7 | 8 | namespace Corsinvest.ProxmoxVE.Admin.VzDumpTrend; 9 | 10 | public class Options : PveModuleClustersOptions { } 11 | 12 | public class ModuleClusterOptions : IClusterName 13 | { 14 | public string ClusterName { get; set; } = default!; 15 | 16 | [Display(Name = "Enabled")] 17 | public bool Enabled { get; set; } 18 | 19 | [Required] 20 | [Display(Name = "Cron Schedule")] 21 | [CronExpressionValidator] 22 | public string CronExpression { get; set; } = "0 */1 * * *"; 23 | 24 | [Display(Name = "Max days logs")] 25 | public int MaxDaysLogs { get; set; } = 30; 26 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/Persistence/VzDumpTrendDbContext.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Microsoft.EntityFrameworkCore; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.VzDumpTrend.Persistence; 8 | 9 | public class VzDumpTrendDbContext(DbContextOptions options) : DbContext(options) 10 | { 11 | public DbSet VzDumpTasks { get; set; } = default!; 12 | public DbSet VzDumpDetails { get; set; } = default!; 13 | 14 | protected override void OnModelCreating(ModelBuilder modelBuilder) 15 | { 16 | base.OnModelCreating(modelBuilder); 17 | 18 | modelBuilder.UseCollation("NOCASE"); 19 | 20 | modelBuilder.Entity() 21 | .HasMany(c => c.Details) 22 | .WithOne(a => a.Task) 23 | .OnDelete(DeleteBehavior.Cascade); 24 | 25 | modelBuilder.Entity().HasIndex(a => a.Storage); 26 | modelBuilder.Entity().HasIndex(a => a.Start); 27 | modelBuilder.Entity().HasIndex(a => a.End); 28 | modelBuilder.Entity().HasIndex(a => a.VmId); 29 | } 30 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/Repository/VzDumpTaskSpec.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Ardalis.Specification; 6 | 7 | namespace Corsinvest.ProxmoxVE.Admin.VzDumpTrend.Repository; 8 | 9 | internal class VzDumpTaskSpec(string clusterName) : ClusterByNameSpec(clusterName) 10 | { 11 | public VzDumpTaskSpec(string clusterName, string taskId) : this(clusterName) 12 | => Query.Where(a => a.TaskId == taskId); 13 | 14 | public VzDumpTaskSpec Over(DateTime date) 15 | { 16 | Query.Where(a => a.Start < date); 17 | return this; 18 | } 19 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/_Imports.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | global using Corsinvest.AppHero.Core.BaseUI.DataManager; 6 | global using Corsinvest.AppHero.Core.Extensions; 7 | global using Corsinvest.ProxmoxVE.Admin.Core.Helpers; 8 | global using Corsinvest.ProxmoxVE.Admin.Core.Repository; 9 | global using Corsinvest.ProxmoxVE.Admin.VzDumpTrend.Models; 10 | global using Microsoft.AspNetCore.Components; 11 | global using Microsoft.Extensions.DependencyInjection; 12 | global using Microsoft.Extensions.Options; 13 | global using MudBlazor; 14 | global using System.ComponentModel.DataAnnotations; 15 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin.VzDumpTrend/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using Corsinvest.AppHero.Core.UI; 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using MudBlazor 8 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Cluster 9 | @using Corsinvest.ProxmoxVE.Api.Shared.Models.Node 10 | @using Corsinvest.ProxmoxVE.Api.Shared.Utils 11 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Options; 12 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components; 13 | @using Corsinvest.AppHero.Core.BaseUI.Shared.Components; 14 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Components.DataGrid 15 | @using Corsinvest.AppHero.Core.MudBlazorUI.Extensions; 16 | @using Corsinvest.ProxmoxVE.Admin.Core.UI.Options 17 | @using Corsinvest.AppHero.Core.MudBlazorUI.Shared.Notification 18 | 19 | @inject IUINotifier UINotifier 20 | @inject IUIMessageBox UIMessageBox -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/Emailing/Templates/Layout.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{content}} 8 | 9 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/Emailing/Templates/Message.tpl: -------------------------------------------------------------------------------- 1 | {{model.message}} -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/Info.MD: -------------------------------------------------------------------------------- 1 | # EntityFramework 2 | 3 | Create Database 4 | 5 | ```powershell 6 | dotnet ef migrations add Initail -c ApplicationDbContext -v 7 | dotnet ef database update -c ApplicationDbContext -v 8 | ``` 9 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/Persistence/ApplicationDbContext.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | */ 5 | using Corsinvest.AppHero.Auditing.Persistence.Context; 6 | using Corsinvest.AppHero.Auditing.Persistence.Interceptors; 7 | using Corsinvest.AppHero.Core.Security.Identity; 8 | using Microsoft.EntityFrameworkCore; 9 | 10 | namespace Corsinvest.ProxmoxVE.Admin.Persistence; 11 | 12 | public class ApplicationDbContext(DbContextOptions options, 13 | AuditableEntitySaveChangesInterceptor auditableEntitySaveChangesInterceptor) : BaseApplicationDbContext(options, auditableEntitySaveChangesInterceptor) 14 | { 15 | protected override void OnModelCreating(ModelBuilder modelBuilder) 16 | { 17 | base.OnModelCreating(modelBuilder); 18 | 19 | modelBuilder.UseCollation("NOCASE"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "IIS Express": { 4 | "commandName": "IISExpress", 5 | "launchBrowser": true, 6 | "environmentVariables": { 7 | "ASPNETCORE_ENVIRONMENT": "Development" 8 | } 9 | }, 10 | "Corsinvest.ProxmoxVE.Admin": { 11 | "commandName": "Project", 12 | "launchBrowser": true, 13 | "environmentVariables": { 14 | "ASPNETCORE_ENVIRONMENT": "Development" 15 | }, 16 | "dotnetRunMessages": true, 17 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 18 | } 19 | }, 20 | "iisSettings": { 21 | "windowsAuthentication": false, 22 | "anonymousAuthentication": true, 23 | "iisExpress": { 24 | "applicationUrl": "http://localhost:61949", 25 | "sslPort": 44393 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/_Imports.razor: -------------------------------------------------------------------------------- 1 | @* 2 | * SPDX-FileCopyrightText: Copyright Corsinvest Srl 3 | * SPDX-License-Identifier: AGPL-3.0-only 4 | *@ 5 | @using System.Net.Http 6 | @using Microsoft.AspNetCore.Authorization 7 | @using Microsoft.AspNetCore.Components.Authorization 8 | @using Microsoft.AspNetCore.Components.Forms 9 | @using Microsoft.AspNetCore.Components.Routing 10 | @using Microsoft.AspNetCore.Components.Web 11 | @using Microsoft.AspNetCore.Components.Web.Virtualization 12 | @using Microsoft.JSInterop 13 | @using MudBlazor 14 | @using Corsinvest.ProxmoxVE.Admin 15 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/libman.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0", 3 | "defaultProvider": "cdnjs", 4 | "libraries": [ 5 | { 6 | "library": "font-awesome@6.2.1", 7 | "destination": "wwwroot/lib/font-awesome/" 8 | }, 9 | { 10 | "provider": "cdnjs", 11 | "library": "flag-icons@6.6.6", 12 | "destination": "wwwroot/lib/flag-icons/" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/android-chrome-192x192.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/android-chrome-512x512.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/apple-touch-icon.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/commands.adoc: -------------------------------------------------------------------------------- 1 | [[chapter_other_cmd]] 2 | = Commands 3 | 4 | When you have to specify what VM/CT insert inside a job you have these methods: 5 | 6 | * comma separated (__100,101,102,TestDebian,VMName__) 7 | * range (__100:107__) 8 | * poolname (__@pool-test__) 9 | * tagname (__@tag-test__) 10 | * nodename (__@node-nodename__) 11 | * every object of your host (__@all-nodename__) 12 | * every object of your cluster (__@all__) 13 | 14 | If you have to exclude some VMs or Containers just put the "-" sign in front of the ID/Name: 15 | 16 | * -vmid or -name (__-200,-TestUbuntu__) 17 | 18 | Mixed example: 19 | ---- 20 | 100,101,102,-103,104,vmtest,-containertest 21 | ---- -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/faq.adoc: -------------------------------------------------------------------------------- 1 | [[chapter_other_faq]] 2 | = Frequently Asked Questions 3 | :title: FAQ 4 | 5 | NOTE: New FAQs are appended to the bottom of this section. 6 | 7 | * Roadmap 8 | 9 | * Release notes 10 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/favicon.ico -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/login/loginadm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/login/loginadm.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/administration/modules-administration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/administration/modules-administration.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/in-errors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/in-errors.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/job-history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/job-history.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/job-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/job-status.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/modules-safe-autosnap-conf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/modules-safe-autosnap-conf.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/modules-safe-autosnap-hook-conf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/modules-safe-autosnap-hook-conf.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/modules-safe-autosnap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/modules-safe-autosnap.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/task-new-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/task-new-edit.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/tasks-status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/tasks-status.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/tasks.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/time-line.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/autosnap/time-line.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/botgram/modules-control-telegrambot-mobile-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/botgram/modules-control-telegrambot-mobile-ok.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/botgram/modules-control-telegrambot-ok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/botgram/modules-control-telegrambot-ok.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/cluster-usage/by-costs1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/cluster-usage/by-costs1.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/cluster-usage/by-costs2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/cluster-usage/by-costs2.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/cluster-usage/by-costs3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/cluster-usage/by-costs3.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/cluster-usage/by-storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/cluster-usage/by-storage.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/cluster-usage/by-vm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/cluster-usage/by-vm.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/cluster-usage/configurations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/cluster-usage/configurations.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/diagnostic/issues.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/diagnostic/issues.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/diagnostic/modules-health-diag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/diagnostic/modules-health-diag.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/diagnostic/results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/diagnostic/results.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/disks-status/disks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/disks-status/disks.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/disks-status/nodes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/disks-status/nodes.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/disks-status/smart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/disks-status/smart.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/home/home-computerscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/home/home-computerscreen.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/home/homepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/home/homepage.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/metrics-exporter/data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/metrics-exporter/data.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/node-free-memory/nodes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/node-free-memory/nodes.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/node-protect/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/node-protect/grid.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/qemu-monitor/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/qemu-monitor/grid.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/cluster-settings1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/cluster-settings1.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/cluster-settings2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/cluster-settings2.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/cluster-settings3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/cluster-settings3.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/clustermanagement-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/clustermanagement-options.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/global-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/global-settings.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/module-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/module-settings.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/options.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/service-general-cv4pve-admin-add-cluster1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/service-general-cv4pve-admin-add-cluster1.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/service-general-cv4pve-admin-add-cluster2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/service-general-cv4pve-admin-add-cluster2.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/service-general-cv4pve-admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/service-general-cv4pve-admin.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/service-general-localization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/service-general-localization.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/service-general-smtp-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/service-general-smtp-config.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/service-general-smtp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/settings/service-general-smtp.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/status/modules-health-clusterusage-object.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/status/modules-health-clusterusage-object.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/status/modules-health-clusterusage-tasks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/status/modules-health-clusterusage-tasks.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/status/modules-health-clusterusage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/status/modules-health-clusterusage.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/status/objects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/status/objects.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/status/summary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/status/summary.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/status/tasks_logs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/status/tasks_logs.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vm-unlock/vms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vm-unlock/vms.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/backups-inline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/backups-inline.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/disks_not_backupped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/disks_not_backupped.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/duration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/duration.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/job-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/job-detail.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/job.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/job.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/not-scheduled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/not-scheduled.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/range.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/scheduled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/scheduled.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/size.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/size.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/speed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/speed.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/storage.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/task-detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/task-detail.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/vm-ct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/modules/vzdump-trend/vm-ct.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/multicluster/multicluster-management.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/screenshot/multicluster/multicluster-management.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/social/docker-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/social/docker-24.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/social/domain-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/social/domain-24.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/social/github-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/social/github-24.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/social/youtube-play-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/images/social/youtube-play-24.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/index.adoc: -------------------------------------------------------------------------------- 1 | CV4PVE-ADMIN {app-version} Guide 2 | ================================= 3 | Powered by Corsinvest Srl 4 | :favicon: ./images/favicon.ico 5 | :doctype: book 6 | :title: CV4PVE-ADMIN {app-version} Guide 7 | :toc2: 8 | :numbered: 9 | :imagesdir: ./images 10 | :scriptsdir: ./js 11 | :icons: font 12 | :pve-name: Proxmox VE 13 | :app-name: cv4pve-admin 14 | :app-version: v1.3.0 15 | :app-url-site: https://www.corsinvest.it/cv4pve-admin 16 | :company-url: https://www.corsinvest.it 17 | :company-name: Corsinvest Srl 18 | 19 | :leveloffset: 1 20 | 21 | include::intro.adoc[] 22 | include::installation.adoc[] 23 | include::gui.adoc[] 24 | 25 | :leveloffset: 0 26 | 27 | Modules 28 | ------- 29 | 30 | :leveloffset: 2 31 | 32 | include::module-home.adoc[] 33 | include::module-administration.adoc[] 34 | include::module-control.adoc[] 35 | include::module-health.adoc[] 36 | include::module-safe.adoc[] 37 | include::module-utilities.adoc[] 38 | 39 | :leveloffset: 0 40 | 41 | Other 42 | ----- 43 | 44 | :leveloffset: 2 45 | 46 | include::cron.adoc[] 47 | include::commands.adoc[] 48 | include::faq.adoc[] 49 | 50 | :leveloffset: 0 51 | 52 | Support 53 | ------- 54 | 55 | :leveloffset: 2 56 | 57 | include::subscription.adoc[] 58 | 59 | :leveloffset: 0 60 | -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/module-administration.adoc: -------------------------------------------------------------------------------- 1 | [[chapter_module_administration]] 2 | // ################################################ CAPITOLO 4 ################################################ 3 | // ################################################ MODULI ################################################ 4 | // ################################################ ADMINISTRATION ################################################ 5 | 6 | = Administration 7 | 8 | Monitor jobs in the background with HangFire. Enable/Disable modules and keep track of sessions. 9 | 10 | [.thumb] 11 | image:screenshot/modules/administration/modules-administration.png[] -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/module-control.adoc: -------------------------------------------------------------------------------- 1 | [[chapter_module_control]] 2 | // ################################################ CAPITOLO 4 ################################################ 3 | // ################################################ MODULI ################################################ 4 | 5 | // ################################################ CONTROL ################################################ 6 | 7 | = Control 8 | 9 | // TELEGRAM BOT 10 | 11 | == Telegram Bot 12 | 13 | Full Control of your cluster directly by Telegram. Visit image:social/github-24.png[] https://github.com/Corsinvest/cv4pve-botgram[Telegram Bot Step By Step] to see how to set up your bot. 14 | 15 | [width="100%"] 16 | |======= 17 | | image:screenshot/modules/botgram/modules-control-telegrambot-ok.png[] | image:screenshot/modules/botgram/modules-control-telegrambot-mobile-ok.png[] 18 | |======= -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/module-home.adoc: -------------------------------------------------------------------------------- 1 | [[chapter_module_home]] 2 | // ################################################ CAPITOLO 4 ################################################ 3 | 4 | // ################################################ MODULI ################################################2 5 | 6 | // ################################################ HOME ################################################ 7 | 8 | = Home 9 | 10 | Summarize the situation of your cluster in a few boxes. Each section is clickable. 11 | 12 | [.thumb] 13 | image:screenshot/modules/home/homepage.png[] -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/doc/subscription.adoc: -------------------------------------------------------------------------------- 1 | = Subscription 2 | 3 | == Commercial Support 4 | 5 | {company-url}[{company-name}] offers enterprise support available as {app-url-site}[Subscription Service Plans]. 6 | All users with a subscription get access to the {app-name} Customer Portal. 7 | The customer portal provides help and support with guaranteed response times from the {app-name} developers. -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/favicon-16x16.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/favicon-32x32.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/favicon.ico -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/images/community.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/images/community.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/images/enterprise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/images/enterprise.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/images/logo.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/images/wallpaper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Corsinvest/cv4pve-admin/0c7fe76cdbc98f2cfc40d4df6a8728791a2bb0e4/src/Corsinvest.ProxmoxVE.Admin/wwwroot/images/wallpaper.png -------------------------------------------------------------------------------- /src/Corsinvest.ProxmoxVE.Admin/wwwroot/site.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} -------------------------------------------------------------------------------- /src/Docker/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/bin 15 | **/charts 16 | **/docker-compose* 17 | **/compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md 26 | data 27 | appsettings.json -------------------------------------------------------------------------------- /src/Docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright Corsinvest Srl 2 | # SPDX-License-Identifier: AGPL-3.0-only 3 | 4 | FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base 5 | WORKDIR /app 6 | VOLUME ["/app/data"] 7 | 8 | FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build 9 | WORKDIR /src 10 | COPY ["src/", "src/"] 11 | RUN dotnet restore "src/Corsinvest.ProxmoxVE.Admin/Corsinvest.ProxmoxVE.Admin.csproj" 12 | RUN dotnet build "src/Corsinvest.ProxmoxVE.Admin/Corsinvest.ProxmoxVE.Admin.csproj" -c Release -o /app/build 13 | 14 | FROM build AS publish 15 | RUN dotnet publish "src/Corsinvest.ProxmoxVE.Admin/Corsinvest.ProxmoxVE.Admin.csproj" -c Release -o /app/publish /p:UseAppHost=false 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app/publish . 20 | 21 | ENV ASPNETCORE_URLS=http://+:5000 22 | 23 | ENTRYPOINT ["dotnet", "Corsinvest.ProxmoxVE.Admin.dll"] -------------------------------------------------------------------------------- /src/Docker/Nginx/ReverseProxy/.env: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright Corsinvest Srl 2 | # SPDX-License-Identifier: AGPL-3.0-only 3 | 4 | DATA_STORE=d:/DockerData/cv4pve-admin/ 5 | VERSION=1.1.1 -------------------------------------------------------------------------------- /src/Docker/Nginx/ReverseProxy/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright Corsinvest Srl 2 | # SPDX-License-Identifier: AGPL-3.0-only 3 | 4 | version: "3.9" 5 | services: 6 | cv4pve-admin: 7 | image: corsinvest/cv4pve-admin:${VERSION} 8 | ports: 9 | - "5001:5000" 10 | environment: 11 | - TZ=Europe/Rome 12 | volumes: 13 | - ${DATA_STORE}/data:/app/data 14 | - ${DATA_STORE}/appsettings.json:/app/appsettings.json 15 | 16 | nginx: 17 | image: nginx:alpine 18 | volumes: 19 | - ./nginx.conf:/etc/nginx/nginx.conf:ro 20 | depends_on: 21 | - cv4pve-admin 22 | ports: 23 | - "4000:4000" -------------------------------------------------------------------------------- /src/Docker/Nginx/ReverseProxy/nginx.conf: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright Corsinvest Srl 2 | # SPDX-License-Identifier: AGPL-3.0-only 3 | 4 | events { 5 | worker_connections 1024; 6 | } 7 | 8 | http { 9 | 10 | proxy_buffer_size 128k; 11 | proxy_buffers 4 256k; 12 | proxy_busy_buffers_size 256k; 13 | large_client_header_buffers 4 16k; 14 | 15 | server { 16 | listen 4000; 17 | server_name _; 18 | large_client_header_buffers 4 32k; 19 | 20 | location / { 21 | proxy_pass http://cv4pve-admin:5000; 22 | #proxy_pass http://10.92.100.21:5271; 23 | proxy_http_version 1.1; 24 | proxy_set_header Upgrade $http_upgrade; 25 | proxy_set_header Connection "upgrade"; 26 | proxy_set_header Host $host:5000; 27 | proxy_cache_bypass $http_upgrade; 28 | 29 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 30 | proxy_set_header X-Forwarded-Proto $scheme; 31 | 32 | fastcgi_buffers 16 16k; 33 | fastcgi_buffer_size 32k; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Docker/README.md: -------------------------------------------------------------------------------- 1 | # Docker 2 | 3 | - Dokerfile (docker for cv4pve-admin) 4 | - Nginx 5 | - Reverse Proxy (doker-compose example reverse proxy use cv4pve-admin and Nginx redirect 5000 to 4000 6 | -------------------------------------------------------------------------------- /src/common.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | net8.0 4 | enable 5 | enable 6 | false 7 | 8 | latest 9 | 1.3.0 10 | $(NoWarn);CS1591 11 | 12 | 13 | Corsinvest Srl 14 | Corsinvest Srl 15 | Corsinvest Srl 16 | https://github.com/Corsinvest/cv4pve-admin 17 | git 18 | 19 | 20 | --------------------------------------------------------------------------------