Skip to content

Commit 40b2256

Browse files
committed
WIP - move ports out of instance
1 parent a873934 commit 40b2256

18 files changed

+1015
-113
lines changed

api/v1alpha5/conversion.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,3 +437,14 @@ func Convert_v1alpha5_OpenStackClusterStatus_To_v1alpha7_OpenStackClusterStatus(
437437
func Convert_v1alpha7_OpenStackMachineSpec_To_v1alpha5_OpenStackMachineSpec(in *infrav1.OpenStackMachineSpec, out *OpenStackMachineSpec, s conversion.Scope) error {
438438
return autoConvert_v1alpha7_OpenStackMachineSpec_To_v1alpha5_OpenStackMachineSpec(in, out, s)
439439
}
440+
441+
func Convert_v1alpha7_OpenStackMachineStatus_To_v1alpha5_OpenStackMachineStatus(in *infrav1.OpenStackMachineStatus, out *OpenStackMachineStatus, s conversion.Scope) error {
442+
err := autoConvert_v1alpha7_OpenStackMachineStatus_To_v1alpha5_OpenStackMachineStatus(in, out, s)
443+
if err != nil {
444+
return err
445+
}
446+
447+
in.PortsStatus = nil
448+
449+
return nil
450+
}

api/v1alpha5/zz_generated.conversion.go

Lines changed: 1 addition & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha6/conversion.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,3 +659,14 @@ func Convert_v1alpha6_OpenStackClusterStatus_To_v1alpha7_OpenStackClusterStatus(
659659
func Convert_v1alpha7_OpenStackMachineSpec_To_v1alpha6_OpenStackMachineSpec(in *infrav1.OpenStackMachineSpec, out *OpenStackMachineSpec, s apiconversion.Scope) error {
660660
return autoConvert_v1alpha7_OpenStackMachineSpec_To_v1alpha6_OpenStackMachineSpec(in, out, s)
661661
}
662+
663+
func Convert_v1alpha7_OpenStackMachineStatus_To_v1alpha6_OpenStackMachineStatus(in *infrav1.OpenStackMachineStatus, out *OpenStackMachineStatus, s apiconversion.Scope) error {
664+
err := autoConvert_v1alpha7_OpenStackMachineStatus_To_v1alpha6_OpenStackMachineStatus(in, out, s)
665+
if err != nil {
666+
return err
667+
}
668+
669+
in.PortsStatus = nil
670+
671+
return nil
672+
}

api/v1alpha6/zz_generated.conversion.go

Lines changed: 1 addition & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1alpha7/conditions_consts.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ const (
2222
// InstanceReadyCondition reports on current status of the OpenStack instance. Ready indicates the instance is in a Running state.
2323
InstanceReadyCondition clusterv1.ConditionType = "InstanceReady"
2424

25+
// PortsReadyCondition reports on the current status of the ports. Ready indicates that all ports have been created
26+
// successfully and ready to be attached to the instance.
27+
PortsReadyCondition clusterv1.ConditionType = "PortsReady"
28+
2529
// WaitingForClusterInfrastructureReason used when machine is waiting for cluster infrastructure to be ready before proceeding.
2630
WaitingForClusterInfrastructureReason = "WaitingForClusterInfrastructure"
2731
// WaitingForBootstrapDataReason used when machine is waiting for bootstrap data to be ready before proceeding.
@@ -42,6 +46,8 @@ const (
4246
InstanceDeleteFailedReason = "InstanceDeleteFailed"
4347
// OpenstackErrorReason used when there is an error communicating with OpenStack.
4448
OpenStackErrorReason = "OpenStackError"
49+
// PortsCreateFailedReason used when creating the ports failed.
50+
PortsCreateFailedReason = "PortsCreateFailed"
4551
)
4652

4753
const (

api/v1alpha7/openstackmachine_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ type OpenStackMachineStatus struct {
113113

114114
FailureReason *errors.MachineStatusError `json:"failureReason,omitempty"`
115115

116+
// PortsStatus is the status of the ports associated with the machine.
117+
// +optional
118+
PortsStatus []PortStatus `json:"portsStatus,omitempty"`
119+
116120
// FailureMessage will be set in the event that there is a terminal problem
117121
// reconciling the Machine and will contain a more verbose string suitable
118122
// for logging and human consumption.

api/v1alpha7/types.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ type PortOpts struct {
128128
ValueSpecs []ValueSpec `json:"valueSpecs,omitempty"`
129129
}
130130

131+
type PortStatus struct {
132+
// ID is the unique identifier of the port.
133+
// +optional
134+
ID string `json:"id,omitempty"`
135+
}
136+
131137
type BindingProfile struct {
132138
// OVSHWOffload enables or disables the OVS hardware offload feature.
133139
OVSHWOffload bool `json:"ovsHWOffload,omitempty"`
@@ -149,12 +155,13 @@ type AddressPair struct {
149155
}
150156

151157
type BastionStatus struct {
152-
ID string `json:"id,omitempty"`
153-
Name string `json:"name,omitempty"`
154-
SSHKeyName string `json:"sshKeyName,omitempty"`
155-
State InstanceState `json:"state,omitempty"`
156-
IP string `json:"ip,omitempty"`
157-
FloatingIP string `json:"floatingIP,omitempty"`
158+
ID string `json:"id,omitempty"`
159+
Name string `json:"name,omitempty"`
160+
SSHKeyName string `json:"sshKeyName,omitempty"`
161+
State InstanceState `json:"state,omitempty"`
162+
PortsStatus PortStatus `json:"portsStatus,omitempty"`
163+
IP string `json:"ip,omitempty"`
164+
FloatingIP string `json:"floatingIP,omitempty"`
158165
}
159166

160167
type RootVolume struct {

api/v1alpha7/zz_generated.deepcopy.go

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

config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,6 +1603,16 @@ spec:
16031603
description: InstanceState is the state of the OpenStack instance
16041604
for this machine.
16051605
type: string
1606+
portsStatus:
1607+
description: PortsStatus is the status of the ports associated with
1608+
the machine.
1609+
items:
1610+
properties:
1611+
id:
1612+
description: ID is the unique identifier of the port.
1613+
type: string
1614+
type: object
1615+
type: array
16061616
ready:
16071617
description: Ready is true when the provider resource is ready.
16081618
type: boolean

controllers/openstackcluster_controller.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ func reconcileBastion(scope scope.Scope, cluster *clusterv1.Cluster, openStackCl
320320
return err
321321
}
322322

323+
// TODO(emilien) Create ports for bastion host
324+
323325
instanceSpec := bastionToInstanceSpec(openStackCluster, cluster.Name)
324326
bastionHash, err := compute.HashInstanceSpec(instanceSpec)
325327
if err != nil {
@@ -349,7 +351,7 @@ func reconcileBastion(scope scope.Scope, cluster *clusterv1.Cluster, openStackCl
349351
}
350352
}
351353

352-
instanceStatus, err = computeService.CreateInstance(openStackCluster, openStackCluster, instanceSpec, cluster.Name)
354+
instanceStatus, err = computeService.CreateInstance(openStackCluster, openStackCluster, instanceSpec, cluster.Name, []string{})
353355
if err != nil {
354356
return fmt.Errorf("failed to reconcile bastion: %w", err)
355357
}

controllers/openstackmachine_controller.go

Lines changed: 76 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,24 @@ func (r *OpenStackMachineReconciler) reconcileNormal(ctx context.Context, scope
328328
return ctrl.Result{}, err
329329
}
330330

331-
instanceStatus, err := r.getOrCreate(scope.Logger(), cluster, openStackCluster, machine, openStackMachine, computeService, userData)
331+
managedSecurityGroups := getManagedSecurityGroups(openStackCluster, machine, openStackMachine)
332+
instanceTags := getInstanceTags(openStackMachine, openStackCluster)
333+
portsStatus, err := r.getOrCreatePorts(scope.Logger(), clusterName, openStackCluster, openStackMachine.Spec.Ports, openStackMachine.Spec.Trunk, managedSecurityGroups, instanceTags, openStackMachine.Name, openStackMachine, networkingService)
332334
if err != nil {
333-
// Conditions set in getOrCreate
335+
// Conditions set in getOrCreatePorts
336+
return ctrl.Result{}, err
337+
}
338+
// TODO(emilien) do we want to deal with Ports Status like we do for the nova instance? Might be expensive...
339+
// In the meantime, we consider that ports are ready if they are created.
340+
conditions.MarkTrue(openStackMachine, infrav1.PortsReadyCondition)
341+
portIDs := make([]string, len(*portsStatus))
342+
for i, portStatus := range *portsStatus {
343+
portIDs[i] = portStatus.ID
344+
}
345+
346+
instanceStatus, err := r.getOrCreateInstance(scope.Logger(), cluster, openStackCluster, machine, openStackMachine, computeService, userData, portIDs)
347+
if err != nil {
348+
// Conditions set in getOrCreateInstance
334349
return ctrl.Result{}, err
335350
}
336351

@@ -430,7 +445,32 @@ func (r *OpenStackMachineReconciler) reconcileNormal(ctx context.Context, scope
430445
return ctrl.Result{}, nil
431446
}
432447

433-
func (r *OpenStackMachineReconciler) getOrCreate(logger logr.Logger, cluster *clusterv1.Cluster, openStackCluster *infrav1.OpenStackCluster, machine *clusterv1.Machine, openStackMachine *infrav1.OpenStackMachine, computeService *compute.Service, userData string) (*compute.InstanceStatus, error) {
448+
func (r *OpenStackMachineReconciler) getOrCreatePorts(logger logr.Logger, clusterName string, openStackCluster *infrav1.OpenStackCluster, machinePorts []infrav1.PortOpts, trunkEnabled bool, securityGroups []infrav1.SecurityGroupFilter, instanceTags []string, instanceName string, openStackMachine *infrav1.OpenStackMachine, networkingService *networking.Service) (*[]infrav1.PortStatus, error) {
449+
// TODO(emilien) implement portsStatus where we check if the machine has ports created and part of the OpenStackMachine.Status
450+
// Check `GetInstanceStatusByName` as it's done for instances. For each port found in Status, we might want get the port name and verify there is no duplicate.
451+
// If Status is empty, we create the ports and add them to the Status.
452+
// If Status is not empty, we try to adopt the existing ports by checking if the ports are still there and if not, we create them and add them to the Status.
453+
454+
// For now, we create the ports.
455+
var portsStatus *[]infrav1.PortStatus
456+
var err error
457+
458+
if openStackMachine.Status.PortsStatus == nil {
459+
logger.Info("Creating ports for OpenStackMachine", "name", openStackMachine.Name)
460+
portsStatus, err = networkingService.CreatePorts(openStackMachine, clusterName, openStackCluster, machinePorts, trunkEnabled, securityGroups, instanceTags, instanceName)
461+
if err != nil {
462+
// Add Conditions
463+
conditions.MarkFalse(openStackMachine, infrav1.PortsReadyCondition, infrav1.PortsCreateFailedReason, clusterv1.ConditionSeverityError, err.Error())
464+
return nil, fmt.Errorf("create ports: %w", err)
465+
}
466+
}
467+
468+
openStackMachine.Status.PortsStatus = *portsStatus
469+
470+
return portsStatus, nil
471+
}
472+
473+
func (r *OpenStackMachineReconciler) getOrCreateInstance(logger logr.Logger, cluster *clusterv1.Cluster, openStackCluster *infrav1.OpenStackCluster, machine *clusterv1.Machine, openStackMachine *infrav1.OpenStackMachine, computeService *compute.Service, userData string, portIDs []string) (*compute.InstanceStatus, error) {
434474
instanceStatus, err := computeService.GetInstanceStatusByName(openStackMachine, openStackMachine.Name)
435475
if err != nil {
436476
logger.Info("Unable to get OpenStack instance", "name", openStackMachine.Name)
@@ -441,7 +481,7 @@ func (r *OpenStackMachineReconciler) getOrCreate(logger logr.Logger, cluster *cl
441481
if instanceStatus == nil {
442482
instanceSpec := machineToInstanceSpec(openStackCluster, machine, openStackMachine, userData)
443483
logger.Info("Machine does not exist, creating Machine", "name", openStackMachine.Name)
444-
instanceStatus, err = computeService.CreateInstance(openStackMachine, openStackCluster, instanceSpec, cluster.Name)
484+
instanceStatus, err = computeService.CreateInstance(openStackMachine, openStackCluster, instanceSpec, cluster.Name, portIDs)
445485
if err != nil {
446486
conditions.MarkFalse(openStackMachine, infrav1.InstanceReadyCondition, infrav1.InstanceCreateFailedReason, clusterv1.ConditionSeverityError, err.Error())
447487
return nil, fmt.Errorf("create OpenStack instance: %w", err)
@@ -472,6 +512,19 @@ func machineToInstanceSpec(openStackCluster *infrav1.OpenStackCluster, machine *
472512
instanceSpec.FailureDomain = *machine.Spec.FailureDomain
473513
}
474514

515+
instanceSpec.Tags = getInstanceTags(openStackMachine, openStackCluster)
516+
517+
instanceSpec.SecurityGroups = getManagedSecurityGroups(openStackCluster, machine, openStackMachine)
518+
519+
instanceSpec.Ports = openStackMachine.Spec.Ports
520+
521+
return &instanceSpec
522+
}
523+
524+
// getInstanceTags returns the tags that should be applied to the instance.
525+
// The tags are a combination of the tags specified on the OpenStackMachine and
526+
// the ones specified on the OpenStackCluster.
527+
func getInstanceTags(openStackMachine *infrav1.OpenStackMachine, openStackCluster *infrav1.OpenStackCluster) []string {
475528
machineTags := []string{}
476529

477530
// Append machine specific tags
@@ -494,31 +547,31 @@ func machineToInstanceSpec(openStackCluster *infrav1.OpenStackCluster, machine *
494547
}
495548
machineTags = deduplicate(machineTags)
496549

497-
instanceSpec.Tags = machineTags
550+
return machineTags
551+
}
498552

499-
instanceSpec.SecurityGroups = openStackMachine.Spec.SecurityGroups
500-
if openStackCluster.Spec.ManagedSecurityGroups {
501-
var managedSecurityGroup string
502-
if util.IsControlPlaneMachine(machine) {
503-
if openStackCluster.Status.ControlPlaneSecurityGroup != nil {
504-
managedSecurityGroup = openStackCluster.Status.ControlPlaneSecurityGroup.ID
505-
}
506-
} else {
507-
if openStackCluster.Status.WorkerSecurityGroup != nil {
508-
managedSecurityGroup = openStackCluster.Status.WorkerSecurityGroup.ID
509-
}
553+
// getManagedSecurityGroups returns a combination of OpenStackMachine.Spec.SecurityGroups
554+
// and the security group managed by the OpenStackCluster whether it's a control plane or a worker machine.
555+
func getManagedSecurityGroups(openStackCluster *infrav1.OpenStackCluster, machine *clusterv1.Machine, openStackMachine *infrav1.OpenStackMachine) []infrav1.SecurityGroupFilter {
556+
machineSpecSecurityGroups := openStackMachine.Spec.SecurityGroups
557+
var managedSecurityGroup string
558+
if util.IsControlPlaneMachine(machine) {
559+
if openStackCluster.Status.ControlPlaneSecurityGroup != nil {
560+
managedSecurityGroup = openStackCluster.Status.ControlPlaneSecurityGroup.ID
510561
}
511-
512-
if managedSecurityGroup != "" {
513-
instanceSpec.SecurityGroups = append(instanceSpec.SecurityGroups, infrav1.SecurityGroupFilter{
514-
ID: managedSecurityGroup,
515-
})
562+
} else {
563+
if openStackCluster.Status.WorkerSecurityGroup != nil {
564+
managedSecurityGroup = openStackCluster.Status.WorkerSecurityGroup.ID
516565
}
517566
}
518567

519-
instanceSpec.Ports = openStackMachine.Spec.Ports
568+
if managedSecurityGroup != "" {
569+
machineSpecSecurityGroups = append(machineSpecSecurityGroups, infrav1.SecurityGroupFilter{
570+
ID: managedSecurityGroup,
571+
})
572+
}
520573

521-
return &instanceSpec
574+
return machineSpecSecurityGroups
522575
}
523576

524577
func (r *OpenStackMachineReconciler) reconcileLoadBalancerMember(scope scope.Scope, openStackCluster *infrav1.OpenStackCluster, openStackMachine *infrav1.OpenStackMachine, instanceNS *compute.InstanceNetworkStatus, clusterName string) error {

0 commit comments

Comments
 (0)