Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions api/v1alpha1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,14 @@ func Convert_v1alpha2_ProxmoxMachineTemplateResource_To_v1alpha1_ProxmoxMachineT
return Convert_v1alpha2_ProxmoxMachineSpec_To_v1alpha1_ProxmoxMachineSpec(&in.Spec, &out.Spec, s)
}

// Convert_v1alpha2_ProxmoxMachineSpec_To_v1alpha1_ProxmoxMachineSpec handles
// the lossy conversion of ProxmoxMachineSpec from v1alpha2 to v1alpha1.
// The FailureDomain field is intentionally dropped (it does not exist in v1alpha1
// and is restored from annotation on ConvertTo).
func Convert_v1alpha2_ProxmoxMachineSpec_To_v1alpha1_ProxmoxMachineSpec(in *v1alpha2.ProxmoxMachineSpec, out *ProxmoxMachineSpec, s conversion.Scope) error {
return autoConvert_v1alpha2_ProxmoxMachineSpec_To_v1alpha1_ProxmoxMachineSpec(in, out, s)
}

func Convert_v1beta1_ObjectMeta_To_v1beta2_ObjectMeta(in *clusterv1beta1.ObjectMeta, out *clusterv1beta2.ObjectMeta, s conversion.Scope) error {
if err := clusterv1beta1.Convert_v1beta1_ObjectMeta_To_v1beta2_ObjectMeta(in, out, s); err != nil {
return err
Expand Down
1 change: 1 addition & 0 deletions api/v1alpha1/proxmoxcluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func (src *ProxmoxCluster) ConvertTo(dstRaw conversion.Hub) error {
// Restore lossy fields
dst.Spec.ZoneConfigs = restored.Spec.ZoneConfigs
dst.Status.InClusterZoneRef = restored.Status.InClusterZoneRef
dst.Status.FailureDomains = restored.Status.FailureDomains

clusterv1.Convert_bool_To_Pointer_bool(src.Spec.ExternalManagedControlPlane, ok, restored.Spec.ExternalManagedControlPlane, &dst.Spec.ExternalManagedControlPlane)

Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha1/proxmoxmachine_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ func restoreProxmoxMachineSpec(src *ProxmoxMachineSpec, dst *v1alpha2.ProxmoxMac
clusterv1.Convert_int32_To_Pointer_int32(src.NumSockets, ok, restored.NumSockets, &dst.NumSockets)
clusterv1.Convert_int32_To_Pointer_int32(src.MemoryMiB, ok, restored.MemoryMiB, &dst.MemoryMiB)

// Restore FailureDomain (v1alpha2-only field, set by CAPI machine controller).
if ok {
dst.FailureDomain = restored.FailureDomain
}

// Turn ProxmoxMachineSpec.Target into allowedNodes. in v1alpha1, target will
// ignore AllowedNodes, so we can literally overwrite these.
if src.Target != nil {
Expand Down
17 changes: 7 additions & 10 deletions api/v1alpha1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions api/v1alpha2/conditions_consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ const (
// documents a ProxmoxMachine assigning host addresses for Cluster API.
ProxmoxMachineVirtualMachineProvisionedWaitingForClusterAPIMachineAddressesReason = "WaitingForClusterAPIMachineAddresses"

// ProxmoxMachineVirtualMachineProvisionedFailureDomainNotReadyReason documents
// a ProxmoxMachine waiting for its failure domain (zone) to be configured
// in the ProxmoxCluster. This is a transient condition that resolves when
// the zone is added to spec.zoneConfig.
ProxmoxMachineVirtualMachineProvisionedFailureDomainNotReadyReason = "FailureDomainNotReady"

// ProxmoxMachineVirtualMachineProvisionedVMProvisionFailedReason documents a failure
// during virtual machine provisioning.
ProxmoxMachineVirtualMachineProvisionedVMProvisionFailedReason = "VMProvisionFailed"
Expand Down
33 changes: 33 additions & 0 deletions api/v1alpha2/proxmoxcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
clusterv1 "sigs.k8s.io/cluster-api/api/core/v1beta2"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -148,6 +149,18 @@ type ZoneConfigSpec struct {
// +listType=set
// +kubebuilder:validation:MinItems=1
DNSServers []string `json:"dnsServers,omitempty"`

// nodes specifies the Proxmox nodes that belong to this zone.
// When set, machines assigned to this failure domain will only
// be placed on these nodes.
// +optional
// +listType=set
Nodes []string `json:"nodes,omitempty"`

// controlPlane indicates whether this zone is eligible for control plane machines.
// Defaults to true when not set.
// +optional
ControlPlane *bool `json:"controlPlane,omitempty"`
}

// IPConfigSpec contains information about available IP config.
Expand Down Expand Up @@ -232,6 +245,14 @@ type ProxmoxClusterStatus struct {
// for different machines.
// +optional
NodeLocations *NodeLocations `json:"nodeLocations,omitempty"`

// failureDomains is a slice of failure domains synced from zone configurations.
// This field is part of the Cluster API contract and is used by KubeadmControlPlane
// to distribute control plane machines across zones.
// +optional
// +listType=map
// +listMapKey=name
FailureDomains []clusterv1.FailureDomain `json:"failureDomains,omitempty"`
}

// ProxmoxClusterInitializationStatus provides observations of the ProxmoxCluster initialization process.
Expand Down Expand Up @@ -523,6 +544,18 @@ func (c *ProxmoxCluster) addNodeLocation(loc NodeLocation, isControlPlane bool)
c.Status.NodeLocations.Workers = append(c.Status.NodeLocations.Workers, loc)
}

// GetZoneNodes returns the Proxmox node names for a given zone name.
// Returns nil if the zone is not found or has no explicit nodes configured.
func (c *ProxmoxCluster) GetZoneNodes(zoneName string) []string {
for _, zc := range c.Spec.ZoneConfigs {
if ptr.Deref(zc.Zone, "") == zoneName {
return zc.Nodes
}
}

return nil
}

func init() {
objectTypes = append(objectTypes, &ProxmoxCluster{}, &ProxmoxClusterList{})
}
34 changes: 34 additions & 0 deletions api/v1alpha2/proxmoxcluster_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,40 @@ func TestRemoveNodeLocation(t *testing.T) {
require.Len(t, cl.Status.NodeLocations.ControlPlane, 0)
}

func TestGetZoneNodes(t *testing.T) {
cl := &ProxmoxCluster{
Spec: ProxmoxClusterSpec{
ZoneConfigs: []ZoneConfigSpec{
{
Zone: ptr.To("zone-a"),
Nodes: []string{"pve1", "pve2"},
},
{
Zone: ptr.To("zone-b"),
// No nodes explicitly set.
},
},
},
}

// Zone found with nodes.
nodes := cl.GetZoneNodes("zone-a")
require.Equal(t, []string{"pve1", "pve2"}, nodes)

// Zone found without nodes.
nodes = cl.GetZoneNodes("zone-b")
require.Nil(t, nodes)

// Zone not found.
nodes = cl.GetZoneNodes("zone-c")
require.Nil(t, nodes)

// Empty ZoneConfigs.
empty := &ProxmoxCluster{}
nodes = empty.GetZoneNodes("anything")
require.Nil(t, nodes)
}

func TestSetInClusterIPPoolRef(t *testing.T) {
cl := defaultCluster()

Expand Down
6 changes: 6 additions & 0 deletions api/v1alpha2/proxmoxmachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ type ProxmoxMachineChecks struct {
type ProxmoxMachineSpec struct {
VirtualMachineCloneSpec `json:",inline"`

// failureDomain is the failure domain the machine is placed in.
// This field is part of the Cluster API InfrastructureMachine contract
// and is set by the CAPI machine controller.
// +optional
FailureDomain *string `json:"failureDomain,omitempty"`

// providerID is the virtual machine BIOS UUID formatted as
// proxmox://6c3fa683-bef9-4425-b413-eaa45a9d6191
// +optional
Expand Down
22 changes: 22 additions & 0 deletions api/v1alpha2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,11 @@ spec:
description: ZoneConfigSpec is the Network Configuration for further
deployment zones.
properties:
controlPlane:
description: |-
controlPlane indicates whether this zone is eligible for control plane machines.
Defaults to true when not set.
type: boolean
dnsServers:
description: dnsServers contains information about nameservers
used by the machines in this zone.
Expand Down Expand Up @@ -1328,6 +1333,15 @@ spec:
x-kubernetes-validations:
- message: IPv6Config addresses must be provided
rule: self.addresses.size() > 0
nodes:
description: |-
nodes specifies the Proxmox nodes that belong to this zone.
When set, machines assigned to this failure domain will only
be placed on these nodes.
items:
type: string
type: array
x-kubernetes-list-type: set
zone:
description: zone is the name of your deployment zone.
pattern: ^[a-z0-9A-Z](?:[a-z0-9A-Z-_.]{0,61}[a-z0-9A-Z])?$
Expand Down Expand Up @@ -1412,6 +1426,38 @@ spec:
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
failureDomains:
description: |-
failureDomains is a slice of failure domains synced from zone configurations.
This field is part of the Cluster API contract and is used by KubeadmControlPlane
to distribute control plane machines across zones.
items:
description: |-
FailureDomain is the Schema for Cluster API failure domains.
It allows controllers to understand how many failure domains a cluster can optionally span across.
properties:
attributes:
additionalProperties:
type: string
description: attributes is a free form map of attributes an
infrastructure provider might use or require.
type: object
controlPlane:
description: controlPlane determines if this failure domain
is suitable for use by control plane machines.
type: boolean
name:
description: name is the name of the failure domain.
maxLength: 256
minLength: 1
type: string
required:
- name
type: object
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
inClusterIPPoolRef:
description: inClusterIPPoolRef is the reference to the created in-cluster
IP pool.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,11 @@ spec:
description: ZoneConfigSpec is the Network Configuration
for further deployment zones.
properties:
controlPlane:
description: |-
controlPlane indicates whether this zone is eligible for control plane machines.
Defaults to true when not set.
type: boolean
dnsServers:
description: dnsServers contains information about nameservers
used by the machines in this zone.
Expand Down Expand Up @@ -1214,6 +1219,15 @@ spec:
x-kubernetes-validations:
- message: IPv6Config addresses must be provided
rule: self.addresses.size() > 0
nodes:
description: |-
nodes specifies the Proxmox nodes that belong to this zone.
When set, machines assigned to this failure domain will only
be placed on these nodes.
items:
type: string
type: array
x-kubernetes-list-type: set
zone:
description: zone is the name of your deployment zone.
pattern: ^[a-z0-9A-Z](?:[a-z0-9A-Z-_.]{0,61}[a-z0-9A-Z])?$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,12 @@ spec:
- message: Value is immutable
rule: self == oldSelf
type: object
failureDomain:
description: |-
failureDomain is the failure domain the machine is placed in.
This field is part of the Cluster API InfrastructureMachine contract
and is set by the CAPI machine controller.
type: string
format:
description: format for file storage. Only valid for full clone.
enum:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,12 @@ spec:
- message: Value is immutable
rule: self == oldSelf
type: object
failureDomain:
description: |-
failureDomain is the failure domain the machine is placed in.
This field is part of the Cluster API InfrastructureMachine contract
and is set by the CAPI machine controller.
type: string
format:
description: format for file storage. Only valid for full
clone.
Expand Down
Loading
Loading