Skip to content

Commit 13e016c

Browse files
committed
Add operating system and architecture information to VSphereMachineTemplate status
1 parent bfa90fa commit 13e016c

13 files changed

+793
-11
lines changed

apis/vmware/v1beta1/conversion.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,3 +368,12 @@ func Convert_v1beta1_APIEndpoint_To_v1beta2_APIEndpoint(in *clusterv1beta1.APIEn
368368
out.Port = in.Port
369369
return nil
370370
}
371+
372+
// Convert_v1beta2_VSphereMachineTemplateStatus_To_v1beta1_VSphereMachineTemplateStatus converts v1beta2 VSphereMachineTemplateStatus to v1beta1.
373+
// This is a manual conversion function that handles the NodeInfo field which doesn't exist in v1beta1.
374+
// The NodeInfo field is intentionally dropped during this conversion as v1beta1 doesn't support it.
375+
func Convert_v1beta2_VSphereMachineTemplateStatus_To_v1beta1_VSphereMachineTemplateStatus(in *vmwarev1.VSphereMachineTemplateStatus, out *VSphereMachineTemplateStatus, s apimachineryconversion.Scope) error {
376+
// Call the auto-generated conversion function which handles the Capacity field
377+
// Note: The NodeInfo field from v1beta2 is intentionally dropped as it doesn't exist in v1beta1
378+
return autoConvert_v1beta2_VSphereMachineTemplateStatus_To_v1beta1_VSphereMachineTemplateStatus(in, out, s)
379+
}

apis/vmware/v1beta1/conversion_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ func VSphereMachineTemplateFuzzFuncs(_ runtimeserializer.CodecFactory) []interfa
186186
return []interface{}{
187187
hubVSphereMachineTemplateResource,
188188
spokeVSphereMachineSpec,
189+
hubVSphereMachineTemplateStatus,
189190
}
190191
}
191192

@@ -195,6 +196,13 @@ func hubVSphereMachineTemplateResource(in *vmwarev1.VSphereMachineTemplateResour
195196
in.ObjectMeta = clusterv1.ObjectMeta{} // Field does not exist in v1beta1.
196197
}
197198

199+
func hubVSphereMachineTemplateStatus(in *vmwarev1.VSphereMachineTemplate, c randfill.Continue) {
200+
c.FillNoCustom(in)
201+
// NodeInfo doesn't exist in v1beta1, so it will be lost during hub-spoke-hub conversion.
202+
// Clear it in the hub object before comparison.
203+
in.Status.NodeInfo = vmwarev1.NodeInfo{}
204+
}
205+
198206
func ProviderServiceAccountFuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} {
199207
return []interface{}{}
200208
}

apis/vmware/v1beta1/zz_generated.conversion.go

Lines changed: 6 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apis/vmware/v1beta2/vspheremachinetemplate_types.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,45 @@ const (
3030
VSphereResourceMemory corev1.ResourceName = "memory"
3131
)
3232

33+
// Architecture represents the CPU architecture of the node.
34+
// Its underlying type is a string and its value can be any of amd64, arm64, s390x, ppc64le.
35+
// +kubebuilder:validation:Enum=amd64;arm64;s390x;ppc64le
36+
// +enum
37+
type Architecture string
38+
39+
const (
40+
// ArchitectureAmd64 is the AMD64 architecture.
41+
ArchitectureAmd64 Architecture = "amd64"
42+
// ArchitectureArm64 is the ARM64 architecture.
43+
ArchitectureArm64 Architecture = "arm64"
44+
// ArchitectureS390x is the S390X architecture.
45+
ArchitectureS390x Architecture = "s390x"
46+
// ArchitecturePpc64le is the PPC64LE architecture.
47+
ArchitecturePpc64le Architecture = "ppc64le"
48+
)
49+
50+
const (
51+
// VMwareSystemOSArchPropertyKey is the key for the architecture property in the
52+
// ClusterVirtualMachineImage's vmwareSystemProperties. This is defined by VM Operator.
53+
VMwareSystemOSArchPropertyKey = "vmware-system.tkr.os-arch"
54+
// VMwareSystemOSTypePropertyKey is the key for the operating system type property in the
55+
// ClusterVirtualMachineImage's vmwareSystemProperties. This is defined by VM Operator.
56+
VMwareSystemOSTypePropertyKey = "vmware-system.tkr.os-type"
57+
)
58+
59+
// OperatingSystem represents the operating system of the node.
60+
// Its underlying type is a string and its value can be any of linux, windows.
61+
// +kubebuilder:validation:Enum=linux;windows
62+
// +enum
63+
type OperatingSystem string
64+
65+
const (
66+
// OperatingSystemLinux is the Linux operating system.
67+
OperatingSystemLinux OperatingSystem = "linux"
68+
// OperatingSystemWindows is the Windows operating system.
69+
OperatingSystemWindows OperatingSystem = "windows"
70+
)
71+
3372
// VSphereMachineTemplateSpec defines the desired state of VSphereMachineTemplate.
3473
type VSphereMachineTemplateSpec struct {
3574
// template defines the desired state of VSphereMachineTemplate.
@@ -45,6 +84,11 @@ type VSphereMachineTemplateStatus struct {
4584
// https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20210310-opt-in-autoscaling-from-zero.md
4685
// +optional
4786
Capacity corev1.ResourceList `json:"capacity,omitempty,omitzero"`
87+
// nodeInfo defines the node's architecture and operating system.
88+
// This value is used for autoscaling from zero operations as defined in:
89+
// https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20210310-opt-in-autoscaling-from-zero.md#implementation-detailsnotesconstraints
90+
// +optional
91+
NodeInfo NodeInfo `json:"nodeInfo,omitempty,omitzero"`
4892
}
4993

5094
// +kubebuilder:object:root=true
@@ -69,6 +113,19 @@ type VSphereMachineTemplate struct {
69113
Status VSphereMachineTemplateStatus `json:"status,omitempty,omitzero"`
70114
}
71115

116+
// NodeInfo contains information about the node's architecture and operating system.
117+
// +kubebuilder:validation:MinProperties=1
118+
type NodeInfo struct {
119+
// architecture is the CPU architecture of the node.
120+
// Its underlying type is a string and its value can be any of amd64, arm64, s390x, ppc64le.
121+
// +optional
122+
Architecture Architecture `json:"architecture,omitempty"`
123+
// operatingSystem is a string representing the operating system of the node.
124+
// This may be a string like 'linux' or 'windows'.
125+
// +optional
126+
OperatingSystem OperatingSystem `json:"operatingSystem,omitempty"`
127+
}
128+
72129
// +kubebuilder:object:root=true
73130

74131
// VSphereMachineTemplateList contains a list of VSphereMachineTemplate.

apis/vmware/v1beta2/zz_generated.deepcopy.go

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/rbac/role.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ rules:
241241
- apiGroups:
242242
- vmoperator.vmware.com
243243
resources:
244+
- clustervirtualmachineimages
244245
- virtualmachineclasses
245246
verbs:
246247
- get

config/supervisor/crd/bases/vmware.infrastructure.cluster.x-k8s.io_vspheremachinetemplates.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,32 @@ spec:
790790
This value is used for autoscaling from zero operations as defined in:
791791
https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20210310-opt-in-autoscaling-from-zero.md
792792
type: object
793+
nodeInfo:
794+
description: |-
795+
nodeInfo defines the node's architecture and operating system.
796+
This value is used for autoscaling from zero operations as defined in:
797+
https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20210310-opt-in-autoscaling-from-zero.md#implementation-detailsnotesconstraints
798+
minProperties: 1
799+
properties:
800+
architecture:
801+
description: |-
802+
architecture is the CPU architecture of the node.
803+
Its underlying type is a string and its value can be any of amd64, arm64, s390x, ppc64le.
804+
enum:
805+
- amd64
806+
- arm64
807+
- s390x
808+
- ppc64le
809+
type: string
810+
operatingSystem:
811+
description: |-
812+
operatingSystem is a string representing the operating system of the node.
813+
This may be a string like 'linux' or 'windows'.
814+
enum:
815+
- linux
816+
- windows
817+
type: string
818+
type: object
793819
type: object
794820
type: object
795821
served: true

controllers/vmware/vspheremachinetemplate_controller.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
// +kubebuilder:rbac:groups=vmware.infrastructure.cluster.x-k8s.io,resources=vspheremachinetemplates,verbs=get;list;watch;create;update;patch;delete
4242
// +kubebuilder:rbac:groups=vmware.infrastructure.cluster.x-k8s.io,resources=vspheremachinetemplates/status,verbs=get;update;patch
4343
// +kubebuilder:rbac:groups=vmoperator.vmware.com,resources=virtualmachineclasses,verbs=get;list;watch
44+
// +kubebuilder:rbac:groups=vmoperator.vmware.com,resources=clustervirtualmachineimages,verbs=get;list;watch
4445

4546
// AddVSphereMachineTemplateControllerToManager adds the machine template controller to the provided
4647
// manager.
@@ -107,9 +108,73 @@ func (r *vSphereMachineTemplateReconciler) Reconcile(ctx context.Context, req ct
107108
vSphereMachineTemplate.Status.Capacity[vmwarev1.VSphereResourceMemory] = vmClass.Spec.Hardware.Memory
108109
}
109110

111+
// retrieve the os and arch info from the ClusterVirtualMachineImage
112+
os, arch := getOSAndArchFromClusterVirtualMachineImage(ctx, r.Client, vSphereMachineTemplate.Spec.Template.Spec.ImageName)
113+
114+
if validOS := normalizeOperatingSystem(os); validOS != "" {
115+
vSphereMachineTemplate.Status.NodeInfo.OperatingSystem = validOS
116+
}
117+
if validArch := normalizeArchitecture(arch); validArch != "" {
118+
vSphereMachineTemplate.Status.NodeInfo.Architecture = validArch
119+
}
120+
110121
return reconcile.Result{}, patchHelper.Patch(ctx, vSphereMachineTemplate)
111122
}
112123

124+
// normalizeOperatingSystem converts the OS string from CVMI to a valid OperatingSystem constant.
125+
// Returns empty string if the value is not recognized.
126+
func normalizeOperatingSystem(os string) vmwarev1.OperatingSystem {
127+
switch os {
128+
case "linux":
129+
return vmwarev1.OperatingSystemLinux
130+
case "windows":
131+
return vmwarev1.OperatingSystemWindows
132+
default:
133+
return ""
134+
}
135+
}
136+
137+
// normalizeArchitecture converts the architecture string from CVMI to a valid Architecture constant.
138+
// Returns empty string if the value is not recognized.
139+
func normalizeArchitecture(arch string) vmwarev1.Architecture {
140+
switch arch {
141+
case "amd64":
142+
return vmwarev1.ArchitectureAmd64
143+
case "arm64":
144+
return vmwarev1.ArchitectureArm64
145+
case "s390x":
146+
return vmwarev1.ArchitectureS390x
147+
case "ppc64le":
148+
return vmwarev1.ArchitecturePpc64le
149+
default:
150+
return ""
151+
}
152+
}
153+
154+
func getOSAndArchFromClusterVirtualMachineImage(ctx context.Context, c client.Client, imageName string) (string, string) {
155+
if imageName == "" {
156+
return "", ""
157+
}
158+
// Try to fetch the ClusterVirtualMachineImage with the given name
159+
cvmi := &vmoprvhub.ClusterVirtualMachineImage{}
160+
if err := c.Get(ctx, client.ObjectKey{Name: imageName}, cvmi); err != nil {
161+
return "", ""
162+
}
163+
164+
// Extract OS type and architecture from vmwareSystemProperties
165+
var osType, osArch string
166+
for _, prop := range cvmi.Status.VMwareSystemProperties {
167+
switch prop.Key {
168+
case vmwarev1.VMwareSystemOSTypePropertyKey:
169+
osType = prop.Value
170+
case vmwarev1.VMwareSystemOSArchPropertyKey:
171+
osArch = prop.Value
172+
}
173+
}
174+
175+
return osType, osArch
176+
}
177+
113178
// enqueueVirtualMachineClassToVSphereMachineTemplateRequests returns a list of VSphereMachineTemplate reconcile requests
114179
// that use a specific VirtualMachineClass.
115180
func (r *vSphereMachineTemplateReconciler) enqueueVirtualMachineClassToVSphereMachineTemplateRequests(ctx context.Context, virtualMachineClass client.Object) []reconcile.Request {

0 commit comments

Comments
 (0)