Skip to content

Commit 1b66ad9

Browse files
committed
Fix 'project purge' deleting wrong project's servers and volumes
Project purge would delete the servers and volumes for the project the user is currently authenticated for, regardless of the --project flag. Note: This change means that no server at all will be deleted if the logged in user doesn't have the get_all_tenants permission set in the Nova policy (default: admin_api). This doesn't appear to be an issue with Cinder as the default rule appears to be admin_or_owner. Change-Id: If1c54e24e1482438b81c3c32fd5fc9fdd7a7be04 Story: 1747988 Task: 13854
1 parent 53c99a2 commit 1b66ad9

2 files changed

Lines changed: 20 additions & 14 deletions

File tree

openstackclient/common/project_purge.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def delete_resources(self, dry_run, project_id):
8585
# servers
8686
try:
8787
compute_client = self.app.client_manager.compute
88-
search_opts = {'tenant_id': project_id}
88+
search_opts = {'tenant_id': project_id, 'all_tenants': True}
8989
data = compute_client.servers.list(search_opts=search_opts)
9090
self.delete_objects(
9191
compute_client.servers.delete, data, 'server', dry_run)
@@ -110,7 +110,7 @@ def delete_resources(self, dry_run, project_id):
110110

111111
# volumes, snapshots, backups
112112
volume_client = self.app.client_manager.volume
113-
search_opts = {'project_id': project_id}
113+
search_opts = {'project_id': project_id, 'all_tenants': True}
114114
try:
115115
data = volume_client.volume_snapshots.list(search_opts=search_opts)
116116
self.delete_objects(

openstackclient/tests/unit/common/test_project_purge.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,11 @@ def test_project_purge_with_project(self):
117117
self.projects_mock.get.assert_called_once_with(self.project.id)
118118
self.projects_mock.delete.assert_called_once_with(self.project.id)
119119
self.servers_mock.list.assert_called_once_with(
120-
search_opts={'tenant_id': self.project.id})
120+
search_opts={'tenant_id': self.project.id, 'all_tenants': True})
121121
kwargs = {'filters': {'owner': self.project.id}}
122122
self.images_mock.list.assert_called_once_with(**kwargs)
123-
volume_search_opts = {'project_id': self.project.id}
123+
volume_search_opts = {'project_id': self.project.id,
124+
'all_tenants': True}
124125
self.volumes_mock.list.assert_called_once_with(
125126
search_opts=volume_search_opts)
126127
self.snapshots_mock.list.assert_called_once_with(
@@ -152,10 +153,11 @@ def test_project_purge_with_dry_run(self):
152153
self.projects_mock.get.assert_called_once_with(self.project.id)
153154
self.projects_mock.delete.assert_not_called()
154155
self.servers_mock.list.assert_called_once_with(
155-
search_opts={'tenant_id': self.project.id})
156+
search_opts={'tenant_id': self.project.id, 'all_tenants': True})
156157
kwargs = {'filters': {'owner': self.project.id}}
157158
self.images_mock.list.assert_called_once_with(**kwargs)
158-
volume_search_opts = {'project_id': self.project.id}
159+
volume_search_opts = {'project_id': self.project.id,
160+
'all_tenants': True}
159161
self.volumes_mock.list.assert_called_once_with(
160162
search_opts=volume_search_opts)
161163
self.snapshots_mock.list.assert_called_once_with(
@@ -187,10 +189,11 @@ def test_project_purge_with_keep_project(self):
187189
self.projects_mock.get.assert_called_once_with(self.project.id)
188190
self.projects_mock.delete.assert_not_called()
189191
self.servers_mock.list.assert_called_once_with(
190-
search_opts={'tenant_id': self.project.id})
192+
search_opts={'tenant_id': self.project.id, 'all_tenants': True})
191193
kwargs = {'filters': {'owner': self.project.id}}
192194
self.images_mock.list.assert_called_once_with(**kwargs)
193-
volume_search_opts = {'project_id': self.project.id}
195+
volume_search_opts = {'project_id': self.project.id,
196+
'all_tenants': True}
194197
self.volumes_mock.list.assert_called_once_with(
195198
search_opts=volume_search_opts)
196199
self.snapshots_mock.list.assert_called_once_with(
@@ -223,10 +226,11 @@ def test_project_purge_with_auth_project(self):
223226
self.projects_mock.get.assert_not_called()
224227
self.projects_mock.delete.assert_called_once_with(self.project.id)
225228
self.servers_mock.list.assert_called_once_with(
226-
search_opts={'tenant_id': self.project.id})
229+
search_opts={'tenant_id': self.project.id, 'all_tenants': True})
227230
kwargs = {'filters': {'owner': self.project.id}}
228231
self.images_mock.list.assert_called_once_with(**kwargs)
229-
volume_search_opts = {'project_id': self.project.id}
232+
volume_search_opts = {'project_id': self.project.id,
233+
'all_tenants': True}
230234
self.volumes_mock.list.assert_called_once_with(
231235
search_opts=volume_search_opts)
232236
self.snapshots_mock.list.assert_called_once_with(
@@ -259,10 +263,11 @@ def test_project_purge_with_exception(self, mock_error):
259263
self.projects_mock.get.assert_called_once_with(self.project.id)
260264
self.projects_mock.delete.assert_called_once_with(self.project.id)
261265
self.servers_mock.list.assert_called_once_with(
262-
search_opts={'tenant_id': self.project.id})
266+
search_opts={'tenant_id': self.project.id, 'all_tenants': True})
263267
kwargs = {'filters': {'owner': self.project.id}}
264268
self.images_mock.list.assert_called_once_with(**kwargs)
265-
volume_search_opts = {'project_id': self.project.id}
269+
volume_search_opts = {'project_id': self.project.id,
270+
'all_tenants': True}
266271
self.volumes_mock.list.assert_called_once_with(
267272
search_opts=volume_search_opts)
268273
self.snapshots_mock.list.assert_called_once_with(
@@ -295,10 +300,11 @@ def test_project_purge_with_force_delete_backup(self):
295300
self.projects_mock.get.assert_called_once_with(self.project.id)
296301
self.projects_mock.delete.assert_called_once_with(self.project.id)
297302
self.servers_mock.list.assert_called_once_with(
298-
search_opts={'tenant_id': self.project.id})
303+
search_opts={'tenant_id': self.project.id, 'all_tenants': True})
299304
kwargs = {'filters': {'owner': self.project.id}}
300305
self.images_mock.list.assert_called_once_with(**kwargs)
301-
volume_search_opts = {'project_id': self.project.id}
306+
volume_search_opts = {'project_id': self.project.id,
307+
'all_tenants': True}
302308
self.volumes_mock.list.assert_called_once_with(
303309
search_opts=volume_search_opts)
304310
self.snapshots_mock.list.assert_called_once_with(

0 commit comments

Comments
 (0)