Only clear out security groups if the parameter is set

Because security groups are associated with ports not servers, this is a tricky UX.

When creating a server, security groups are applied to any new ports created but not existing ports because they haven't been interrogated yet. When updating a server, the security groups for all attached ports are updated. Because we have an empty list as default, this means if you don't specify security groups on the server (because you're setting them on the port instead), then server creation will work fine, but update will clear out the groups from the port.

This patch changes the default groups for the server resource to be None, so that we can tell if the user doesn't specify any groups and if they don't, rely on the ports having them set instead. It improves idempotency.

Closes-Bug: #2137488
Change-Id: Iedcc9a34dc5ac847496eab19880189e4dc3c517a
Signed-off-by: James Hewitt <james.hewitt@uk.ibm.com>
This commit is contained in:
James Hewitt
2026-01-05 21:43:40 +00:00
parent 1dc367b566
commit b1e4d4b714

View File

@@ -195,10 +195,12 @@ options:
added. added.
- On server creation, if I(security_groups) is omitted, the API creates - On server creation, if I(security_groups) is omitted, the API creates
the server in the default security group. the server in the default security group.
- Requested security groups are not applied to pre-existing ports. - On server creation, requested security groups are not applied to
pre-existing ports.
- On update, if I(security_groups) is set, the security groups are
applied to all attached ports.
type: list type: list
elements: str elements: str
default: []
state: state:
description: description:
- Should the resource be C(present) or C(absent). - Should the resource be C(present) or C(absent).
@@ -830,7 +832,7 @@ class ServerModule(OpenStackModule):
nics=dict(default=[], type='list', elements='raw'), nics=dict(default=[], type='list', elements='raw'),
reuse_ips=dict(default=True, type='bool'), reuse_ips=dict(default=True, type='bool'),
scheduler_hints=dict(type='dict'), scheduler_hints=dict(type='dict'),
security_groups=dict(default=[], type='list', elements='str'), security_groups=dict(type='list', elements='str'),
state=dict(default='present', choices=['absent', 'present']), state=dict(default='present', choices=['absent', 'present']),
tags=dict(type='list', default=[], elements='str'), tags=dict(type='list', default=[], elements='str'),
terminate_volume=dict(default=False, type='bool'), terminate_volume=dict(default=False, type='bool'),
@@ -952,6 +954,9 @@ class ServerModule(OpenStackModule):
def _build_update_security_groups(self, server): def _build_update_security_groups(self, server):
update = {} update = {}
if self.params['security_groups'] is None:
return update
required_security_groups = dict( required_security_groups = dict(
(sg['id'], sg) for sg in [ (sg['id'], sg) for sg in [
self.conn.network.find_security_group( self.conn.network.find_security_group(