1 package utils
2
3 import (
4 "fmt"
5 "regexp"
6
7 "k8s.io/apimachinery/pkg/api/resource"
8
9 "edge-infra.dev/pkg/edge/api/graph/model"
10 )
11
12 func CreateVirtualMachineModel(virtualMachineID string, namespace string, clusterEdgeID string, clusterName string, hostname string, targetPowerState bool, cpus int, memory string, machineType model.MachineType) model.VirtualMachine {
13 return model.VirtualMachine{
14 VirtualMachineID: virtualMachineID,
15 Namespace: namespace,
16 ClusterEdgeID: clusterEdgeID,
17 ClusterName: clusterName,
18 Hostname: hostname,
19 TargetPowerState: targetPowerState,
20 Cpus: cpus,
21 Memory: memory,
22 MachineType: machineType,
23 }
24 }
25
26 func CreateVirtualMachineDiskModel(diskID string, virtualMachineID string, diskType model.DiskType, bus model.BusType, bootOrder int, size string, containerImageURL string) model.VirtualMachineDisk {
27 return model.VirtualMachineDisk{
28 DiskID: diskID,
29 VirtualMachineID: virtualMachineID,
30 Type: diskType,
31 Bus: bus,
32 BootOrder: bootOrder,
33 Size: size,
34 ContainerImageURL: containerImageURL,
35 }
36 }
37
38
39 func ValidateVirtualMachine(virtualMachine *model.VirtualMachine) error {
40 if !virtualMachine.MachineType.IsValid() {
41 return fmt.Errorf("invalid VirtualMachine machine type: %s", virtualMachine.MachineType.String())
42 }
43 if !validateVirtualMachineMemory(virtualMachine.Memory) {
44 return fmt.Errorf("invalid memory format (SI notation (K,M,G,T,P,E) and Binary notation (Ki,Mi,Gi,Ti,Pi,Ei) are accepted): %s", virtualMachine.Memory)
45 }
46 return nil
47 }
48
49 func validateVirtualMachineMemory(memory string) bool {
50 _, err := resource.ParseQuantity(memory)
51 return err == nil
52 }
53
54 func ValidateVirtualMachineDisk(disk *model.VirtualMachineDisk) error {
55 if !disk.Type.IsValid() {
56 return fmt.Errorf("invalid VirtualMachineDisk disk type: %s", disk.Type.String())
57 }
58 if !disk.Bus.IsValid() {
59 return fmt.Errorf("invalid VirtualMachineDisk bus type: %s", disk.Bus.String())
60 }
61 if !validateVirtualMachineContainerImageURL(disk.ContainerImageURL) {
62 return fmt.Errorf("invalid container image url format: %s", disk.ContainerImageURL)
63 }
64 if !validateVirtualMachineMemory(disk.Size) {
65 return fmt.Errorf("invalid size format (SI notation (K,M,G,T,P,E) and Binary notation (Ki,Mi,Gi,Ti,Pi,Ei) are accepted): %s", disk.Size)
66 }
67 return nil
68 }
69
70 func HasDuplicateDiskBootOrders(disks []*model.VirtualMachineDisk) bool {
71 visited := make(map[int]bool, 0)
72 for _, disk := range disks {
73 bootOrder := disk.BootOrder
74 if visited[bootOrder] {
75 return true
76 }
77 visited[bootOrder] = true
78 }
79 return false
80 }
81
82 func validateVirtualMachineContainerImageURL(containerImageURL string) bool {
83 if containerImageURL == "" {
84 return true
85 }
86 const pattern = `^docker://us-east1-docker.pkg.dev/ret-edge-pltf-infra/workloads/([^:]+):([^:]+)$|^docker://us-east1-docker.pkg.dev/ret-edge-pltf-infra/thirdparty/quay.io/kubevirt/virtio-container-disk([^:]+):([^:]+)$`
87 re := regexp.MustCompile(pattern)
88 return re.MatchString(containerImageURL)
89 }
90
91
92 func UpdateVirtualMachine(currentVM *model.VirtualMachine, updateVM *model.VirtualMachineIDInput) *model.VirtualMachine {
93 currentVM.TargetPowerState = *AssignNotNil[bool](¤tVM.TargetPowerState, updateVM.VirtualMachineValues.TargetPowerState)
94 currentVM.Memory = *AssignNotNil[string](¤tVM.Memory, updateVM.VirtualMachineValues.Memory)
95 currentVM.MachineType = *AssignNotNil[model.MachineType](¤tVM.MachineType, updateVM.VirtualMachineValues.MachineType)
96 currentVM.Cpus = *AssignNotNil[int](¤tVM.Cpus, updateVM.VirtualMachineValues.Cpus)
97 return currentVM
98 }
99
100 func UpdateVirtualMachineDisk(currentDisk *model.VirtualMachineDisk, updateDisk *model.VirtualMachineDiskUpdateInput) *model.VirtualMachineDisk {
101 currentDisk.Type = *AssignNotNil[model.DiskType](¤tDisk.Type, updateDisk.Type)
102 currentDisk.Bus = *AssignNotNil[model.BusType](¤tDisk.Bus, updateDisk.Bus)
103 currentDisk.BootOrder = *AssignNotNil[int](¤tDisk.BootOrder, updateDisk.BootOrder)
104 currentDisk.Size = *AssignNotNil[string](¤tDisk.Size, updateDisk.Size)
105 currentDisk.ContainerImageURL = *AssignNotNil[string](¤tDisk.ContainerImageURL, updateDisk.ContainerImageURL)
106 return currentDisk
107 }
108
109 func AssignNotNil[T any](currentValue, newValue *T) *T {
110 if newValue != nil {
111 return newValue
112 }
113 return currentValue
114 }
115
View as plain text