mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-22 03:02:35 +00:00
- Host.ToFrontend: Remove redundant h.DisplayName check after struct initialization already set host.DisplayName = h.DisplayName Function now at 100% coverage.
726 lines
19 KiB
Go
726 lines
19 KiB
Go
package models
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// ToFrontend converts a State to StateFrontend
|
|
func (s *State) ToFrontend() StateFrontend {
|
|
return s.GetSnapshot().ToFrontend()
|
|
}
|
|
|
|
// ToFrontend converts a Node to NodeFrontend
|
|
func (n Node) ToFrontend() NodeFrontend {
|
|
nf := NodeFrontend{
|
|
ID: n.ID,
|
|
Node: n.Name,
|
|
Name: n.Name,
|
|
DisplayName: n.DisplayName,
|
|
Instance: n.Instance,
|
|
Host: n.Host,
|
|
Status: n.Status,
|
|
Type: n.Type,
|
|
CPU: n.CPU,
|
|
Mem: n.Memory.Used,
|
|
MaxMem: n.Memory.Total,
|
|
MaxDisk: n.Disk.Total,
|
|
Uptime: n.Uptime,
|
|
LoadAverage: n.LoadAverage,
|
|
KernelVersion: n.KernelVersion,
|
|
PVEVersion: n.PVEVersion,
|
|
CPUInfo: n.CPUInfo,
|
|
LastSeen: n.LastSeen.Unix() * 1000,
|
|
ConnectionHealth: n.ConnectionHealth,
|
|
IsClusterMember: n.IsClusterMember,
|
|
ClusterName: n.ClusterName,
|
|
TemperatureMonitoringEnabled: n.TemperatureMonitoringEnabled,
|
|
}
|
|
|
|
// Include full Memory object if it has data
|
|
if n.Memory.Total > 0 {
|
|
nf.Memory = &n.Memory
|
|
}
|
|
|
|
// Include full Disk object if it has data
|
|
if n.Disk.Total > 0 {
|
|
nf.Disk = &n.Disk
|
|
}
|
|
|
|
// Include temperature data if available
|
|
if n.Temperature != nil && n.Temperature.Available {
|
|
nf.Temperature = n.Temperature
|
|
}
|
|
|
|
if nf.DisplayName == "" {
|
|
nf.DisplayName = nf.Name
|
|
}
|
|
|
|
return nf
|
|
}
|
|
|
|
// ToFrontend converts a VM to VMFrontend
|
|
func (v VM) ToFrontend() VMFrontend {
|
|
vm := VMFrontend{
|
|
ID: v.ID,
|
|
VMID: v.VMID,
|
|
Name: v.Name,
|
|
Node: v.Node,
|
|
Instance: v.Instance,
|
|
Status: v.Status,
|
|
Type: v.Type,
|
|
CPU: v.CPU,
|
|
CPUs: v.CPUs,
|
|
Mem: v.Memory.Used,
|
|
MaxMem: v.Memory.Total,
|
|
NetIn: zeroIfNegative(v.NetworkIn),
|
|
NetOut: zeroIfNegative(v.NetworkOut),
|
|
DiskRead: zeroIfNegative(v.DiskRead),
|
|
DiskWrite: zeroIfNegative(v.DiskWrite),
|
|
Uptime: v.Uptime,
|
|
Template: v.Template,
|
|
Lock: v.Lock,
|
|
LastSeen: v.LastSeen.Unix() * 1000,
|
|
DiskStatusReason: v.DiskStatusReason,
|
|
}
|
|
|
|
// Convert tags array to string
|
|
if len(v.Tags) > 0 {
|
|
vm.Tags = strings.Join(v.Tags, ",")
|
|
}
|
|
|
|
// Convert last backup time if not zero
|
|
if !v.LastBackup.IsZero() {
|
|
vm.LastBackup = v.LastBackup.Unix() * 1000
|
|
}
|
|
|
|
// Include full Memory object if it has data
|
|
if v.Memory.Total > 0 {
|
|
vm.Memory = &v.Memory
|
|
}
|
|
|
|
// Include full Disk object if it has data
|
|
if v.Disk.Total > 0 {
|
|
vm.DiskObj = &v.Disk
|
|
}
|
|
|
|
// Include individual disks array if available
|
|
if len(v.Disks) > 0 {
|
|
vm.Disks = v.Disks
|
|
}
|
|
|
|
if len(v.IPAddresses) > 0 {
|
|
vm.IPAddresses = append([]string(nil), v.IPAddresses...)
|
|
}
|
|
|
|
if v.OSName != "" {
|
|
vm.OSName = v.OSName
|
|
}
|
|
|
|
if v.OSVersion != "" {
|
|
vm.OSVersion = v.OSVersion
|
|
}
|
|
|
|
if v.AgentVersion != "" {
|
|
vm.AgentVersion = v.AgentVersion
|
|
}
|
|
|
|
if len(v.NetworkInterfaces) > 0 {
|
|
vm.NetworkInterfaces = make([]GuestNetworkInterface, len(v.NetworkInterfaces))
|
|
copy(vm.NetworkInterfaces, v.NetworkInterfaces)
|
|
}
|
|
|
|
return vm
|
|
}
|
|
|
|
// ToFrontend converts a Container to ContainerFrontend
|
|
func (c Container) ToFrontend() ContainerFrontend {
|
|
ct := ContainerFrontend{
|
|
ID: c.ID,
|
|
VMID: c.VMID,
|
|
Name: c.Name,
|
|
Node: c.Node,
|
|
Instance: c.Instance,
|
|
Status: c.Status,
|
|
Type: c.Type,
|
|
CPU: c.CPU,
|
|
CPUs: c.CPUs,
|
|
Mem: c.Memory.Used,
|
|
MaxMem: c.Memory.Total,
|
|
NetIn: zeroIfNegative(c.NetworkIn),
|
|
NetOut: zeroIfNegative(c.NetworkOut),
|
|
DiskRead: zeroIfNegative(c.DiskRead),
|
|
DiskWrite: zeroIfNegative(c.DiskWrite),
|
|
Uptime: c.Uptime,
|
|
Template: c.Template,
|
|
Lock: c.Lock,
|
|
LastSeen: c.LastSeen.Unix() * 1000,
|
|
}
|
|
|
|
// Convert tags array to string
|
|
if len(c.Tags) > 0 {
|
|
ct.Tags = strings.Join(c.Tags, ",")
|
|
}
|
|
|
|
// Convert last backup time if not zero
|
|
if !c.LastBackup.IsZero() {
|
|
ct.LastBackup = c.LastBackup.Unix() * 1000
|
|
}
|
|
|
|
// Include full Memory object if it has data
|
|
if c.Memory.Total > 0 {
|
|
ct.Memory = &c.Memory
|
|
}
|
|
|
|
// Include full Disk object if it has data
|
|
if c.Disk.Total > 0 {
|
|
ct.DiskObj = &c.Disk
|
|
}
|
|
|
|
// Include individual disks array if available
|
|
if len(c.Disks) > 0 {
|
|
ct.Disks = c.Disks
|
|
}
|
|
|
|
if len(c.IPAddresses) > 0 {
|
|
ct.IPAddresses = append([]string(nil), c.IPAddresses...)
|
|
}
|
|
|
|
if len(c.NetworkInterfaces) > 0 {
|
|
ct.NetworkInterfaces = make([]GuestNetworkInterface, len(c.NetworkInterfaces))
|
|
copy(ct.NetworkInterfaces, c.NetworkInterfaces)
|
|
}
|
|
|
|
return ct
|
|
}
|
|
|
|
// ToFrontend converts a DockerHost to DockerHostFrontend
|
|
func (d DockerHost) ToFrontend() DockerHostFrontend {
|
|
h := DockerHostFrontend{
|
|
ID: d.ID,
|
|
AgentID: d.AgentID,
|
|
Hostname: d.Hostname,
|
|
DisplayName: d.DisplayName,
|
|
CustomDisplayName: d.CustomDisplayName,
|
|
MachineID: d.MachineID,
|
|
OS: d.OS,
|
|
KernelVersion: d.KernelVersion,
|
|
Architecture: d.Architecture,
|
|
Runtime: d.Runtime,
|
|
RuntimeVersion: d.RuntimeVersion,
|
|
DockerVersion: d.DockerVersion,
|
|
CPUs: d.CPUs,
|
|
TotalMemoryBytes: d.TotalMemoryBytes,
|
|
UptimeSeconds: d.UptimeSeconds,
|
|
CPUUsagePercent: d.CPUUsage,
|
|
Status: d.Status,
|
|
LastSeen: d.LastSeen.Unix() * 1000,
|
|
IntervalSeconds: d.IntervalSeconds,
|
|
AgentVersion: d.AgentVersion,
|
|
Containers: make([]DockerContainerFrontend, len(d.Containers)),
|
|
}
|
|
|
|
if h.DisplayName == "" {
|
|
h.DisplayName = h.Hostname
|
|
}
|
|
|
|
h.PendingUninstall = d.PendingUninstall
|
|
|
|
if d.TokenID != "" {
|
|
h.TokenID = d.TokenID
|
|
h.TokenName = d.TokenName
|
|
h.TokenHint = d.TokenHint
|
|
if d.TokenLastUsedAt != nil && !d.TokenLastUsedAt.IsZero() {
|
|
ts := d.TokenLastUsedAt.Unix() * 1000
|
|
h.TokenLastUsedAt = &ts
|
|
}
|
|
}
|
|
|
|
for i, ct := range d.Containers {
|
|
h.Containers[i] = ct.ToFrontend()
|
|
}
|
|
|
|
if len(d.Services) > 0 {
|
|
h.Services = make([]DockerServiceFrontend, len(d.Services))
|
|
for i, svc := range d.Services {
|
|
h.Services[i] = svc.ToFrontend()
|
|
}
|
|
}
|
|
|
|
if len(d.Tasks) > 0 {
|
|
h.Tasks = make([]DockerTaskFrontend, len(d.Tasks))
|
|
for i, task := range d.Tasks {
|
|
h.Tasks[i] = task.ToFrontend()
|
|
}
|
|
}
|
|
|
|
if d.Swarm != nil {
|
|
sw := d.Swarm.ToFrontend()
|
|
h.Swarm = &sw
|
|
}
|
|
|
|
if len(d.LoadAverage) > 0 {
|
|
h.LoadAverage = append([]float64(nil), d.LoadAverage...)
|
|
}
|
|
|
|
if (d.Memory != Memory{}) {
|
|
mem := d.Memory
|
|
h.Memory = &mem
|
|
}
|
|
|
|
if len(d.Disks) > 0 {
|
|
h.Disks = append([]Disk(nil), d.Disks...)
|
|
}
|
|
|
|
if len(d.NetworkInterfaces) > 0 {
|
|
h.NetworkInterfaces = make([]HostNetworkInterface, len(d.NetworkInterfaces))
|
|
copy(h.NetworkInterfaces, d.NetworkInterfaces)
|
|
}
|
|
|
|
if d.Command != nil {
|
|
h.Command = toDockerHostCommandFrontend(*d.Command)
|
|
}
|
|
|
|
return h
|
|
}
|
|
|
|
// ToFrontend converts a RemovedDockerHost to its frontend representation.
|
|
func (r RemovedDockerHost) ToFrontend() RemovedDockerHostFrontend {
|
|
return RemovedDockerHostFrontend{
|
|
ID: r.ID,
|
|
Hostname: r.Hostname,
|
|
DisplayName: r.DisplayName,
|
|
RemovedAt: r.RemovedAt.Unix() * 1000,
|
|
}
|
|
}
|
|
|
|
// ToFrontend converts a Host to HostFrontend.
|
|
func (h Host) ToFrontend() HostFrontend {
|
|
host := HostFrontend{
|
|
ID: h.ID,
|
|
Hostname: h.Hostname,
|
|
DisplayName: h.DisplayName,
|
|
Platform: h.Platform,
|
|
OSName: h.OSName,
|
|
OSVersion: h.OSVersion,
|
|
KernelVersion: h.KernelVersion,
|
|
Architecture: h.Architecture,
|
|
CPUCount: h.CPUCount,
|
|
CPUUsage: h.CPUUsage,
|
|
Status: h.Status,
|
|
UptimeSeconds: h.UptimeSeconds,
|
|
IntervalSeconds: h.IntervalSeconds,
|
|
AgentVersion: h.AgentVersion,
|
|
TokenID: h.TokenID,
|
|
TokenName: h.TokenName,
|
|
TokenHint: h.TokenHint,
|
|
Tags: append([]string(nil), h.Tags...),
|
|
LastSeen: h.LastSeen.Unix() * 1000,
|
|
}
|
|
|
|
// Fall back to Hostname if DisplayName is empty
|
|
if host.DisplayName == "" && h.Hostname != "" {
|
|
host.DisplayName = h.Hostname
|
|
}
|
|
|
|
if len(h.LoadAverage) > 0 {
|
|
host.LoadAverage = append([]float64(nil), h.LoadAverage...)
|
|
}
|
|
|
|
if (h.Memory != Memory{}) {
|
|
mem := h.Memory
|
|
host.Memory = &mem
|
|
}
|
|
|
|
if len(h.Disks) > 0 {
|
|
host.Disks = append([]Disk(nil), h.Disks...)
|
|
}
|
|
|
|
if len(h.NetworkInterfaces) > 0 {
|
|
host.NetworkInterfaces = make([]HostNetworkInterface, len(h.NetworkInterfaces))
|
|
copy(host.NetworkInterfaces, h.NetworkInterfaces)
|
|
}
|
|
|
|
if s := hostSensorSummaryToFrontend(h.Sensors); s != nil {
|
|
host.Sensors = s
|
|
}
|
|
|
|
if h.TokenLastUsedAt != nil && !h.TokenLastUsedAt.IsZero() {
|
|
ts := h.TokenLastUsedAt.Unix() * 1000
|
|
host.TokenLastUsedAt = &ts
|
|
}
|
|
|
|
return host
|
|
}
|
|
|
|
// ToFrontend converts a DockerContainer to DockerContainerFrontend
|
|
func (c DockerContainer) ToFrontend() DockerContainerFrontend {
|
|
container := DockerContainerFrontend{
|
|
ID: c.ID,
|
|
Name: c.Name,
|
|
Image: c.Image,
|
|
State: c.State,
|
|
Status: c.Status,
|
|
Health: c.Health,
|
|
CPUPercent: c.CPUPercent,
|
|
MemoryUsage: c.MemoryUsage,
|
|
MemoryLimit: c.MemoryLimit,
|
|
MemoryPercent: c.MemoryPercent,
|
|
UptimeSeconds: c.UptimeSeconds,
|
|
RestartCount: c.RestartCount,
|
|
ExitCode: c.ExitCode,
|
|
CreatedAt: c.CreatedAt.Unix() * 1000,
|
|
Labels: c.Labels,
|
|
WritableLayerBytes: c.WritableLayerBytes,
|
|
RootFilesystemBytes: c.RootFilesystemBytes,
|
|
}
|
|
|
|
if c.StartedAt != nil {
|
|
ms := c.StartedAt.Unix() * 1000
|
|
container.StartedAt = &ms
|
|
}
|
|
|
|
if c.FinishedAt != nil {
|
|
ms := c.FinishedAt.Unix() * 1000
|
|
container.FinishedAt = &ms
|
|
}
|
|
|
|
if len(c.Ports) > 0 {
|
|
ports := make([]DockerContainerPortFrontend, len(c.Ports))
|
|
for i, port := range c.Ports {
|
|
ports[i] = DockerContainerPortFrontend(port)
|
|
}
|
|
container.Ports = ports
|
|
}
|
|
|
|
if len(c.Networks) > 0 {
|
|
networks := make([]DockerContainerNetworkFrontend, len(c.Networks))
|
|
for i, net := range c.Networks {
|
|
networks[i] = DockerContainerNetworkFrontend(net)
|
|
}
|
|
container.Networks = networks
|
|
}
|
|
|
|
if c.BlockIO != nil {
|
|
container.BlockIO = &DockerContainerBlockIOFrontend{
|
|
ReadBytes: c.BlockIO.ReadBytes,
|
|
WriteBytes: c.BlockIO.WriteBytes,
|
|
ReadRateBytesPerSecond: c.BlockIO.ReadRateBytesPerSecond,
|
|
WriteRateBytesPerSecond: c.BlockIO.WriteRateBytesPerSecond,
|
|
}
|
|
}
|
|
|
|
if len(c.Mounts) > 0 {
|
|
mounts := make([]DockerContainerMountFrontend, len(c.Mounts))
|
|
for i, mount := range c.Mounts {
|
|
mounts[i] = DockerContainerMountFrontend(mount)
|
|
}
|
|
container.Mounts = mounts
|
|
}
|
|
|
|
if c.Podman != nil {
|
|
container.Podman = &DockerPodmanContainerFrontend{
|
|
PodName: c.Podman.PodName,
|
|
PodID: c.Podman.PodID,
|
|
Infra: c.Podman.Infra,
|
|
ComposeProject: c.Podman.ComposeProject,
|
|
ComposeService: c.Podman.ComposeService,
|
|
ComposeWorkdir: c.Podman.ComposeWorkdir,
|
|
ComposeConfigHash: c.Podman.ComposeConfigHash,
|
|
AutoUpdatePolicy: c.Podman.AutoUpdatePolicy,
|
|
AutoUpdateRestart: c.Podman.AutoUpdateRestart,
|
|
UserNamespace: c.Podman.UserNamespace,
|
|
}
|
|
}
|
|
|
|
return container
|
|
}
|
|
|
|
// ToFrontend converts a DockerService to DockerServiceFrontend.
|
|
func (s DockerService) ToFrontend() DockerServiceFrontend {
|
|
service := DockerServiceFrontend{
|
|
ID: s.ID,
|
|
Name: s.Name,
|
|
Stack: s.Stack,
|
|
Image: s.Image,
|
|
Mode: s.Mode,
|
|
DesiredTasks: s.DesiredTasks,
|
|
RunningTasks: s.RunningTasks,
|
|
CompletedTasks: s.CompletedTasks,
|
|
Labels: nil,
|
|
}
|
|
|
|
if len(s.Labels) > 0 {
|
|
service.Labels = make(map[string]string, len(s.Labels))
|
|
for k, v := range s.Labels {
|
|
service.Labels[k] = v
|
|
}
|
|
}
|
|
|
|
if len(s.EndpointPorts) > 0 {
|
|
service.EndpointPorts = make([]DockerServicePortFrontend, len(s.EndpointPorts))
|
|
for i, port := range s.EndpointPorts {
|
|
service.EndpointPorts[i] = port.ToFrontend()
|
|
}
|
|
}
|
|
|
|
if s.UpdateStatus != nil {
|
|
update := s.UpdateStatus.ToFrontend()
|
|
service.UpdateStatus = &update
|
|
}
|
|
|
|
if s.CreatedAt != nil && !s.CreatedAt.IsZero() {
|
|
ts := s.CreatedAt.Unix() * 1000
|
|
service.CreatedAt = &ts
|
|
}
|
|
if s.UpdatedAt != nil && !s.UpdatedAt.IsZero() {
|
|
ts := s.UpdatedAt.Unix() * 1000
|
|
service.UpdatedAt = &ts
|
|
}
|
|
|
|
return service
|
|
}
|
|
|
|
// ToFrontend converts a DockerServicePort to DockerServicePortFrontend.
|
|
func (p DockerServicePort) ToFrontend() DockerServicePortFrontend {
|
|
return DockerServicePortFrontend(p)
|
|
}
|
|
|
|
// ToFrontend converts a DockerServiceUpdate to DockerServiceUpdateFrontend.
|
|
func (u DockerServiceUpdate) ToFrontend() DockerServiceUpdateFrontend {
|
|
update := DockerServiceUpdateFrontend{
|
|
State: u.State,
|
|
Message: u.Message,
|
|
}
|
|
if u.CompletedAt != nil && !u.CompletedAt.IsZero() {
|
|
ts := u.CompletedAt.Unix() * 1000
|
|
update.CompletedAt = &ts
|
|
}
|
|
return update
|
|
}
|
|
|
|
// ToFrontend converts a DockerTask to DockerTaskFrontend.
|
|
func (t DockerTask) ToFrontend() DockerTaskFrontend {
|
|
task := DockerTaskFrontend{
|
|
ID: t.ID,
|
|
ServiceID: t.ServiceID,
|
|
ServiceName: t.ServiceName,
|
|
Slot: t.Slot,
|
|
NodeID: t.NodeID,
|
|
NodeName: t.NodeName,
|
|
DesiredState: t.DesiredState,
|
|
CurrentState: t.CurrentState,
|
|
Error: t.Error,
|
|
Message: t.Message,
|
|
ContainerID: t.ContainerID,
|
|
ContainerName: t.ContainerName,
|
|
}
|
|
|
|
if !t.CreatedAt.IsZero() {
|
|
ts := t.CreatedAt.Unix() * 1000
|
|
task.CreatedAt = &ts
|
|
}
|
|
if t.UpdatedAt != nil && !t.UpdatedAt.IsZero() {
|
|
ts := t.UpdatedAt.Unix() * 1000
|
|
task.UpdatedAt = &ts
|
|
}
|
|
if t.StartedAt != nil && !t.StartedAt.IsZero() {
|
|
ts := t.StartedAt.Unix() * 1000
|
|
task.StartedAt = &ts
|
|
}
|
|
if t.CompletedAt != nil && !t.CompletedAt.IsZero() {
|
|
ts := t.CompletedAt.Unix() * 1000
|
|
task.CompletedAt = &ts
|
|
}
|
|
|
|
return task
|
|
}
|
|
|
|
// ToFrontend converts DockerSwarmInfo to DockerSwarmFrontend.
|
|
func (s DockerSwarmInfo) ToFrontend() DockerSwarmFrontend {
|
|
return DockerSwarmFrontend(s)
|
|
}
|
|
|
|
func hostSensorSummaryToFrontend(src HostSensorSummary) *HostSensorSummaryFrontend {
|
|
if len(src.TemperatureCelsius) == 0 && len(src.FanRPM) == 0 && len(src.Additional) == 0 {
|
|
return nil
|
|
}
|
|
|
|
dest := &HostSensorSummaryFrontend{}
|
|
if len(src.TemperatureCelsius) > 0 {
|
|
dest.TemperatureCelsius = copyStringFloatMap(src.TemperatureCelsius)
|
|
}
|
|
if len(src.FanRPM) > 0 {
|
|
dest.FanRPM = copyStringFloatMap(src.FanRPM)
|
|
}
|
|
if len(src.Additional) > 0 {
|
|
dest.Additional = copyStringFloatMap(src.Additional)
|
|
}
|
|
return dest
|
|
}
|
|
|
|
func copyStringFloatMap(src map[string]float64) map[string]float64 {
|
|
if len(src) == 0 {
|
|
return nil
|
|
}
|
|
dest := make(map[string]float64, len(src))
|
|
for k, v := range src {
|
|
dest[k] = v
|
|
}
|
|
return dest
|
|
}
|
|
|
|
func toDockerHostCommandFrontend(cmd DockerHostCommandStatus) *DockerHostCommandFrontend {
|
|
result := &DockerHostCommandFrontend{
|
|
ID: cmd.ID,
|
|
Type: cmd.Type,
|
|
Status: cmd.Status,
|
|
Message: cmd.Message,
|
|
CreatedAt: cmd.CreatedAt.Unix() * 1000,
|
|
UpdatedAt: cmd.UpdatedAt.Unix() * 1000,
|
|
}
|
|
|
|
if cmd.DispatchedAt != nil {
|
|
ms := cmd.DispatchedAt.Unix() * 1000
|
|
result.DispatchedAt = &ms
|
|
}
|
|
if cmd.AcknowledgedAt != nil {
|
|
ms := cmd.AcknowledgedAt.Unix() * 1000
|
|
result.AcknowledgedAt = &ms
|
|
}
|
|
if cmd.CompletedAt != nil {
|
|
ms := cmd.CompletedAt.Unix() * 1000
|
|
result.CompletedAt = &ms
|
|
}
|
|
if cmd.FailedAt != nil {
|
|
ms := cmd.FailedAt.Unix() * 1000
|
|
result.FailedAt = &ms
|
|
}
|
|
if cmd.FailureReason != "" {
|
|
result.FailureReason = cmd.FailureReason
|
|
}
|
|
if cmd.ExpiresAt != nil {
|
|
ms := cmd.ExpiresAt.Unix() * 1000
|
|
result.ExpiresAt = &ms
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// ToFrontend converts Storage to StorageFrontend
|
|
func (s Storage) ToFrontend() StorageFrontend {
|
|
return StorageFrontend{
|
|
ID: s.ID,
|
|
Storage: s.Name,
|
|
Name: s.Name,
|
|
Node: s.Node,
|
|
Instance: s.Instance,
|
|
Nodes: s.Nodes,
|
|
NodeIDs: s.NodeIDs,
|
|
NodeCount: s.NodeCount,
|
|
Type: s.Type,
|
|
Status: s.Status,
|
|
Total: s.Total,
|
|
Used: s.Used,
|
|
Avail: s.Free,
|
|
Free: s.Free,
|
|
Usage: s.Usage,
|
|
Content: s.Content,
|
|
Shared: s.Shared,
|
|
Enabled: s.Enabled,
|
|
Active: s.Active,
|
|
}
|
|
}
|
|
|
|
// ToFrontend converts a CephCluster to CephClusterFrontend
|
|
func (c CephCluster) ToFrontend() CephClusterFrontend {
|
|
frontend := CephClusterFrontend{
|
|
ID: c.ID,
|
|
Instance: c.Instance,
|
|
Name: c.Name,
|
|
FSID: c.FSID,
|
|
Health: c.Health,
|
|
HealthMessage: c.HealthMessage,
|
|
TotalBytes: c.TotalBytes,
|
|
UsedBytes: c.UsedBytes,
|
|
AvailableBytes: c.AvailableBytes,
|
|
UsagePercent: c.UsagePercent,
|
|
NumMons: c.NumMons,
|
|
NumMgrs: c.NumMgrs,
|
|
NumOSDs: c.NumOSDs,
|
|
NumOSDsUp: c.NumOSDsUp,
|
|
NumOSDsIn: c.NumOSDsIn,
|
|
NumPGs: c.NumPGs,
|
|
LastUpdated: c.LastUpdated.Unix() * 1000,
|
|
}
|
|
|
|
if len(c.Pools) > 0 {
|
|
frontend.Pools = append([]CephPool(nil), c.Pools...)
|
|
}
|
|
|
|
if len(c.Services) > 0 {
|
|
frontend.Services = append([]CephServiceStatus(nil), c.Services...)
|
|
}
|
|
|
|
return frontend
|
|
}
|
|
|
|
// ToFrontend converts a replication job to a frontend representation.
|
|
func (r ReplicationJob) ToFrontend() ReplicationJobFrontend {
|
|
frontend := ReplicationJobFrontend{
|
|
ID: r.ID,
|
|
Instance: r.Instance,
|
|
JobID: r.JobID,
|
|
JobNumber: r.JobNumber,
|
|
Guest: r.Guest,
|
|
GuestID: r.GuestID,
|
|
GuestName: r.GuestName,
|
|
GuestType: r.GuestType,
|
|
GuestNode: r.GuestNode,
|
|
SourceNode: r.SourceNode,
|
|
SourceStorage: r.SourceStorage,
|
|
TargetNode: r.TargetNode,
|
|
TargetStorage: r.TargetStorage,
|
|
Schedule: r.Schedule,
|
|
Type: r.Type,
|
|
Enabled: r.Enabled,
|
|
State: r.State,
|
|
Status: r.Status,
|
|
LastSyncStatus: r.LastSyncStatus,
|
|
LastSyncUnix: r.LastSyncUnix,
|
|
LastSyncDurationSeconds: r.LastSyncDurationSeconds,
|
|
LastSyncDurationHuman: r.LastSyncDurationHuman,
|
|
NextSyncUnix: r.NextSyncUnix,
|
|
DurationSeconds: r.DurationSeconds,
|
|
DurationHuman: r.DurationHuman,
|
|
FailCount: r.FailCount,
|
|
Error: r.Error,
|
|
Comment: r.Comment,
|
|
RemoveJob: r.RemoveJob,
|
|
RateLimitMbps: r.RateLimitMbps,
|
|
}
|
|
|
|
if r.LastSyncTime != nil {
|
|
frontend.LastSyncTime = r.LastSyncTime.UnixMilli()
|
|
}
|
|
|
|
if r.NextSyncTime != nil {
|
|
frontend.NextSyncTime = r.NextSyncTime.UnixMilli()
|
|
}
|
|
|
|
polledAt := r.LastPolled
|
|
if polledAt.IsZero() {
|
|
polledAt = time.Now()
|
|
}
|
|
frontend.PolledAt = polledAt.UnixMilli()
|
|
|
|
return frontend
|
|
}
|
|
|
|
// zeroIfNegative returns 0 for negative values (used for I/O metrics)
|
|
func zeroIfNegative(val int64) int64 {
|
|
if val < 0 {
|
|
return 0
|
|
}
|
|
return val
|
|
}
|