Skip to content
Merged
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
4 changes: 2 additions & 2 deletions api/v1alpha8/openstackcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ type OpenStackClusterSpec struct {
// Bastion is the OpenStack instance to login the nodes
//
// As a rolling update is not ideal during a bastion host session, we
// prevent changes to a running bastion configuration. Set `enabled: false` to
// make changes.
// prevent changes to a running bastion configuration. To make changes, it's required
// to first set `enabled: false` which will remove the bastion and then changes can be made.
//+optional
Bastion *Bastion `json:"bastion,omitempty"`

Expand Down
7 changes: 7 additions & 0 deletions api/v1alpha8/openstackcluster_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ func (r *OpenStackCluster) ValidateUpdate(oldRaw runtime.Object) (admission.Warn
r.Spec.APIServerPort = 0
}

// Allow to remove the bastion spec only if it was disabled before.
if r.Spec.Bastion == nil {
if old.Spec.Bastion != nil && old.Spec.Bastion.Enabled {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that I didn't add a guard to compare the old instance with the new one because there are complicated objects with filters. If we want to go down that path, let me know although I'm not sure it's desired.

Otherwise let me know if the doc content is enough.

allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "bastion"), "cannot be removed before disabling it"))
}
}

// Allow changes to the bastion spec.
old.Spec.Bastion = &Bastion{}
r.Spec.Bastion = &Bastion{}
Expand Down
36 changes: 36 additions & 0 deletions api/v1alpha8/openstackcluster_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,42 @@ func TestOpenStackCluster_ValidateUpdate(t *testing.T) {
},
wantErr: true,
},
{
name: "Removing OpenStackCluster.Spec.Bastion when it is enabled is not allowed",
oldTemplate: &OpenStackCluster{
Spec: OpenStackClusterSpec{
Bastion: &Bastion{
Enabled: true,
Instance: OpenStackMachineSpec{
Flavor: "m1.small",
Image: ImageFilter{Name: "ubuntu"},
},
},
},
},
newTemplate: &OpenStackCluster{
Spec: OpenStackClusterSpec{},
},
wantErr: true,
},
{
name: "Removing OpenStackCluster.Spec.Bastion when it is disabled is allowed",
oldTemplate: &OpenStackCluster{
Spec: OpenStackClusterSpec{
Bastion: &Bastion{
Enabled: false,
Instance: OpenStackMachineSpec{
Flavor: "m1.small",
Image: ImageFilter{Name: "ubuntu"},
},
},
},
},
newTemplate: &OpenStackCluster{
Spec: OpenStackClusterSpec{},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4899,8 +4899,8 @@ spec:
As a rolling update is not ideal during a bastion host session, we
prevent changes to a running bastion configuration. Set `enabled: false` to
make changes.
prevent changes to a running bastion configuration. To make changes, it's required
to first set `enabled: false` which will remove the bastion and then changes can be made.
properties:
availabilityZone:
type: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2324,8 +2324,8 @@ spec:


As a rolling update is not ideal during a bastion host session, we
prevent changes to a running bastion configuration. Set `enabled: false` to
make changes.
prevent changes to a running bastion configuration. To make changes, it's required
to first set `enabled: false` which will remove the bastion and then changes can be made.
properties:
availabilityZone:
type: string
Expand Down
22 changes: 18 additions & 4 deletions controllers/openstackcluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,10 @@ func deleteBastion(scope scope.Scope, cluster *clusterv1.Cluster, openStackClust
}
}

instanceSpec := bastionToInstanceSpec(openStackCluster, cluster.Name)
instanceSpec, err := bastionToInstanceSpec(openStackCluster, cluster.Name)
if err != nil {
return err
}
if err = computeService.DeleteInstance(openStackCluster, openStackCluster, instanceStatus, instanceSpec); err != nil {
handleUpdateOSCError(openStackCluster, fmt.Errorf("failed to delete bastion: %w", err))
return fmt.Errorf("failed to delete bastion: %w", err)
Expand Down Expand Up @@ -346,7 +349,10 @@ func reconcileBastion(scope scope.Scope, cluster *clusterv1.Cluster, openStackCl
return reconcile.Result{}, err
}

instanceSpec := bastionToInstanceSpec(openStackCluster, cluster.Name)
instanceSpec, err := bastionToInstanceSpec(openStackCluster, cluster.Name)
if err != nil {
return reconcile.Result{}, err
}
bastionHash, err := compute.HashInstanceSpec(instanceSpec)
if err != nil {
return reconcile.Result{}, fmt.Errorf("failed computing bastion hash from instance spec: %w", err)
Expand Down Expand Up @@ -437,7 +443,15 @@ func reconcileBastion(scope scope.Scope, cluster *clusterv1.Cluster, openStackCl
return ctrl.Result{}, nil
}

func bastionToInstanceSpec(openStackCluster *infrav1.OpenStackCluster, clusterName string) *compute.InstanceSpec {
func bastionToInstanceSpec(openStackCluster *infrav1.OpenStackCluster, clusterName string) (*compute.InstanceSpec, error) {
if openStackCluster.Spec.Bastion == nil {
return nil, fmt.Errorf("bastion spec is nil")
}

if openStackCluster.Status.Bastion == nil {
return nil, fmt.Errorf("bastion status is nil")
}

instanceSpec := &compute.InstanceSpec{
Name: bastionName(clusterName),
Flavor: openStackCluster.Spec.Bastion.Instance.Flavor,
Expand All @@ -458,7 +472,7 @@ func bastionToInstanceSpec(openStackCluster *infrav1.OpenStackCluster, clusterNa

instanceSpec.Ports = openStackCluster.Spec.Bastion.Instance.Ports

return instanceSpec
return instanceSpec, nil
}

func bastionName(clusterName string) string {
Expand Down
15 changes: 15 additions & 0 deletions docs/book/src/clusteropenstack/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
- [Custom pod network CIDR](#custom-pod-network-cidr)
- [Accessing nodes through the bastion host via SSH](#accessing-nodes-through-the-bastion-host-via-ssh)
- [Enabling the bastion host](#enabling-the-bastion-host)
- [Making changes to the bastion host](#making-changes-to-the-bastion-host)
- [Disabling the bastion](#disabling-the-bastion)
- [Obtain floating IP address of the bastion node](#obtain-floating-ip-address-of-the-bastion-node)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
Expand Down Expand Up @@ -654,6 +656,19 @@ spec:

If `managedSecurityGroups: true`, security group rule opening 22/tcp is added to security groups for bastion, controller, and worker nodes respectively. Otherwise, you have to add `securityGroups` to the `bastion` in `OpenStackCluster` spec and `OpenStackMachineTemplate` spec template respectively.

### Making changes to the bastion host

Changes can be made to the bastion instance, like for example changing the flavor.
First, you have to disable the bastion host by setting `enabled: false` in the `OpenStackCluster.Spec.Bastion` field.
The bastion will be deleted, you can check the status of the bastion host by running `kubectl get openstackcluster` and looking at the `Bastion` field in status.
Once it's gone, you can re-enable the bastion host by setting `enabled: true` and then making changes to the bastion instance spec by modifying the `OpenStackCluster.Spec.Bastion.Instance` field.
The bastion host will be re-created with the new instance spec.

### Disabling the bastion

To disable the bastion host, set `enabled: false` in the `OpenStackCluster.Spec.Bastion` field. The bastion host will be deleted, you can check the status of the bastion host by running `kubectl get openstackcluster` and looking at the `Bastion` field in status.
Once it's gone, you can now remove the `OpenStackCluster.Spec.Bastion` field from the `OpenStackCluster` spec.

### Obtain floating IP address of the bastion node

Once the workload cluster is up and running after being configured for an SSH bastion host, you can use the kubectl get openstackcluster command to look up the floating IP address of the bastion host (make sure the kubectl context is set to the management cluster). The output will look something like this:
Expand Down