Skip to content

Commit aa4527e

Browse files
author
Michael Johnson
committed
chore(RHINENG-24199): Allow grouped hosts to move to other groups
Currently, HBI API returns HTTP 400 when trying to add grouped hosts to a different group. The response has this detail: "The following subset of hosts are already associated with another group: [<id>]." This should now be allowed; the host should be removed from its old group and added to the specified one.
1 parent 1de8012 commit aa4527e

File tree

3 files changed

+40
-49
lines changed

3 files changed

+40
-49
lines changed

lib/group_repository.py

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -114,19 +114,6 @@ def validate_add_host_list_to_group_for_group_create(host_id_list: list[str], gr
114114
title="Invalid request", detail=f"Could not find existing host(s) with ID {nonexistent_hosts}."
115115
)
116116

117-
# Check if the hosts are already associated with another (ungrouped) group
118-
if assoc_query := (
119-
HostGroupAssoc.query.join(Group)
120-
.filter(HostGroupAssoc.host_id.in_(host_id_list), Group.ungrouped.is_(False))
121-
.all()
122-
):
123-
taken_hosts = [str(assoc.host_id) for assoc in assoc_query]
124-
log_host_group_add_failed(logger, host_id_list, group_name)
125-
raise InventoryException(
126-
title="Invalid request",
127-
detail=f"The following subset of hosts are already associated with another group: {taken_hosts}.",
128-
)
129-
130117

131118
def validate_add_host_list_to_group(host_id_list: list[str], group_id: str, org_id: str):
132119
# Check if the hosts exist in Inventory and have correct org_id
@@ -139,22 +126,6 @@ def validate_add_host_list_to_group(host_id_list: list[str], group_id: str, org_
139126
title="Invalid request", detail=f"Could not find existing host(s) with ID {nonexistent_hosts}."
140127
)
141128

142-
# Check if the hosts are already associated with another (ungrouped) group
143-
if assoc_query := (
144-
db.session.query(HostGroupAssoc)
145-
.join(Group)
146-
.filter(
147-
HostGroupAssoc.host_id.in_(host_id_list), HostGroupAssoc.group_id != group_id, Group.ungrouped.is_(False)
148-
)
149-
.all()
150-
):
151-
taken_hosts = [str(assoc.host_id) for assoc in assoc_query]
152-
log_host_group_add_failed(logger, host_id_list, group_id)
153-
raise InventoryException(
154-
title="Invalid request",
155-
detail=f"The following subset of hosts are already associated with another group: {taken_hosts}.",
156-
)
157-
158129

159130
def _add_hosts_to_group(group_id: str, host_id_list: list[str], org_id: str):
160131
# Validate that the hosts exist and can be added to the group

tests/test_api_groups_update.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -145,23 +145,29 @@ def test_patch_group_existing_name_different_org(
145145
def test_patch_group_hosts_from_different_group(
146146
db_create_group_with_hosts, api_patch_group, db_get_hosts_for_group, event_producer, mocker
147147
):
148+
"""Patching a group's host_ids to include a host from another group should move that host (200)."""
148149
mocker.patch.object(event_producer, "write_event")
149-
# Create 2 groups
150+
# Create 2 groups: existing_group has 3 hosts, new_group has 1 host
150151
group_id = db_create_group_with_hosts("existing_group", 3).id
151152
host_to_move_id = str(db_get_hosts_for_group(group_id)[0].id)
152153
new_id = db_create_group_with_hosts("new_group", 1).id
153154

154155
patch_doc = {"host_ids": [host_to_move_id]}
155156

156-
response_status, response_body = api_patch_group(new_id, patch_doc)
157+
response_status, _ = api_patch_group(new_id, patch_doc)
157158

158-
# There's already a group with that name, so we should get an HTTP 400.
159-
# Make sure the host ID at fault is mentioned in the response.
160-
assert_response_status(response_status, 400)
161-
assert str(host_to_move_id) in response_body["detail"]
159+
# Moving a host between groups is now allowed; expect 200.
160+
assert_response_status(response_status, 200)
162161

163-
# Make sure no events got produced
164-
assert event_producer.write_event.call_count == 0
162+
# Host should now be in new_group only; existing_group should have the other 2
163+
new_group_host_ids = [str(h.id) for h in db_get_hosts_for_group(new_id)]
164+
existing_group_host_ids = [str(h.id) for h in db_get_hosts_for_group(group_id)]
165+
assert new_group_host_ids == [host_to_move_id]
166+
assert host_to_move_id not in existing_group_host_ids
167+
assert len(existing_group_host_ids) == 2
168+
169+
# Events for the host moved into new_group and for the host removed from new_group (to ungrouped)
170+
assert event_producer.write_event.call_count == 2
165171

166172

167173
@pytest.mark.usefixtures("enable_rbac", "event_producer")

tests/test_api_host_group.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
import uuid
23
from collections.abc import Callable
34
from datetime import UTC
@@ -170,30 +171,43 @@ def test_add_associated_host_to_different_group(
170171
event_producer,
171172
mocker,
172173
):
174+
"""Adding hosts that are in other groups should move them to the target group (no longer 400)."""
173175
mocker.patch.object(event_producer, "write_event")
174176

175-
# Create a group and 3 hosts
177+
# Create two groups and 3 hosts
176178
group1_id = db_create_group("test_group").id
177179
group2_id = db_create_group("test_group2").id
178180
host_id_list = [str(db_create_host().id) for _ in range(3)]
179181

180-
# Add the second 2 hosts to a group
182+
# Host 1 in group1, host 2 in group2, host 0 in no group (or ungrouped)
181183
db_create_host_group_assoc(host_id_list[1], group1_id)
182184
db_create_host_group_assoc(host_id_list[2], group2_id)
183185

184-
# Confirm that the association exists
185-
hosts_before = db_get_hosts_for_group(group1_id)
186-
assert len(hosts_before) == 1
187-
hosts_before = db_get_hosts_for_group(group2_id)
188-
assert len(hosts_before) == 1
186+
# Confirm initial state
187+
assert len(db_get_hosts_for_group(group1_id)) == 1
188+
assert len(db_get_hosts_for_group(group2_id)) == 1
189189

190-
# Confirm that the API does not allow these hosts to be added to the group
190+
# Add all 3 hosts to group1; hosts should be moved from their previous groups
191191
response_status, _ = api_add_hosts_to_group(group1_id, host_id_list)
192-
assert response_status == 400
192+
assert response_status == 200
193193

194-
# Make sure that everything was rolled back and no events were produced
195-
assert len(db_get_hosts_for_group(group1_id)) == 1
196-
assert event_producer.write_event.call_count == 0
194+
# Verify host-group associations: exact host IDs in each group, old group empty
195+
group1_hosts = db_get_hosts_for_group(group1_id)
196+
group2_hosts = db_get_hosts_for_group(group2_id)
197+
assert sorted(str(h.id) for h in group1_hosts) == sorted(host_id_list)
198+
assert group2_hosts == []
199+
200+
# Update events should have been produced for the moved/added hosts
201+
calls = event_producer.write_event.call_args_list
202+
assert len(calls) == 3
203+
# Each emitted event should correspond to one of the affected hosts (event is 1st positional arg, JSON string)
204+
emitted_host_ids = {str(json.loads(call.args[0])["host"]["id"]) for call in calls}
205+
assert emitted_host_ids == set(host_id_list)
206+
# Each event should be a successful update (not a failure)
207+
for call in calls:
208+
event = json.loads(call.args[0])
209+
assert event["type"] == "updated"
210+
assert event.get("status") != "failure"
197211

198212

199213
def test_add_host_in_ungrouped_group_to_new_group(

0 commit comments

Comments
 (0)