maksit-cluster-console/src/MaksIT.ClusterConsole.Client/Cluster/ClusterModels.cs

160 lines
4.2 KiB
C#

using System.Text.Json.Nodes;
namespace MaksIT.ClusterConsole.Client.Cluster;
public sealed record ClusterSummary(
string GitVersion,
string Platform,
int NodeCount,
int PodCount);
public sealed record ResourceSlice(
double Used,
double Requests,
double Limits,
double Allocatable,
double Capacity,
string Kind) {
public static ResourceSlice Empty(string kind) => new(0, 0, 0, 0, 0, kind);
public double Scale =>
Math.Max(1, new[] { Used, Requests, Limits, Allocatable, Capacity }.Max());
public double UsedPercent => Percent(Used);
public double RequestsPercent => Percent(Requests);
public double LimitsPercent => Percent(Limits);
public double AllocatablePercent => Percent(Allocatable);
public double CapacityPercent => Percent(Capacity);
public bool ShowRequestsAndLimits => Kind is "cpu" or "memory";
public bool LimitsExceedCapacity => ShowRequestsAndLimits && Limits > Capacity && Capacity > 0;
public string UsageLine => $"Usage: {Format(Used)}";
public string RequestsLine => $"Requests: {Format(Requests)}";
public string LimitsLine => $"Limits: {Format(Limits)}";
public string AllocatableLine => $"Allocatable Capacity: {Format(Allocatable)}";
public string CapacityLine => $"Capacity: {Format(Capacity)}";
public string LimitsWarning =>
LimitsExceedCapacity ? "Specified limits are higher than node capacity!" : "";
public string Caption => $"{Format(Used)} / {Format(Allocatable)}";
private double Percent(double value) =>
Math.Clamp(value / Scale * 100, 0, 100);
private string Format(double value) => Kind switch {
"cpu" => KubeQuantity.FormatCoresFixed(value),
"memory" => KubeQuantity.FormatBytesCompact((long)Math.Round(value)),
_ => value.ToString("0")
};
}
public sealed record ClusterUsage(
string GitVersion,
string Platform,
int NodeCount,
ResourceSlice Cpu,
ResourceSlice Memory,
ResourceSlice Pods,
IReadOnlyList<NodeUsage> Nodes,
IReadOnlyList<WorkloadContainerLimit> ContainerLimits,
bool MetricsAvailable,
string? MetricsMessage) {
public double CpuPercent => Percent(Cpu.Used, Cpu.Allocatable);
public double MemoryPercent => Percent(Memory.Used, Memory.Allocatable);
public double PodPercent => Percent(Pods.Used, Pods.Allocatable);
public string CpuCaption => Cpu.Caption;
public string MemoryCaption => Memory.Caption;
public string PodCaption => Pods.Caption;
private static double Percent(double used, double capacity) =>
capacity <= 0 ? 0 : Math.Clamp(used / capacity * 100, 0, 100);
}
public sealed record ResourceMetrics(
string Name,
string? Namespace,
string Cpu,
string Memory);
public sealed record ExecBytesResult(byte[] Stdout, string Stderr);
public sealed class ResourceListOptions {
public string? LabelSelector { get; init; }
public string? FieldSelector { get; init; }
public string? ResourceVersion { get; set; }
}
public sealed record ClusterWatchEvent(string Type, JsonObject? Object);
public sealed record HelmReleaseInfo(
string Name,
string Namespace,
string Status,
string Chart,
string AppVersion,
DateTimeOffset? Updated);
public sealed record PortForwardEndpoint(string PodName, string Namespace, int ContainerPort);
public sealed class PortForwardHandle : IDisposable {
private readonly IDisposable _inner;
private readonly Action? _onDispose;
public PortForwardHandle(
string podName,
string @namespace,
int containerPort,
int localPort,
IDisposable inner,
Action? onDispose = null,
int requestedPort = 0) {
PodName = podName;
Namespace = @namespace;
ContainerPort = containerPort;
LocalPort = localPort;
RequestedPort = requestedPort > 0 ? requestedPort : containerPort;
_inner = inner;
_onDispose = onDispose;
}
public string PodName { get; private set; }
public string Namespace { get; private set; }
public int ContainerPort { get; private set; }
public int RequestedPort { get; }
public int LocalPort { get; }
public void Retarget(string podName, string @namespace, int containerPort) {
PodName = podName;
Namespace = @namespace;
ContainerPort = containerPort;
}
public void Dispose() {
_onDispose?.Invoke();
_inner.Dispose();
}
}