From 254dbf3294c0f1edc4a2a469f556b3c4b3123a00 Mon Sep 17 00:00:00 2001
From: lihaijing <lihaijing@fiberhome.com>
Date: Thu, 21 Sep 2017 14:55:17 +0800
Subject: [PATCH] Fix 'project purge' deletes ALL images problem

Closes-Bug: #1717130
Change-Id: I33c6fc7897dfee85d1c197a1267bde4abfa5bbd9
---
 openstackclient/common/project_purge.py       |  9 ++++++-
 .../tests/unit/common/test_project_purge.py   | 24 +++++++++----------
 openstackclient/tests/unit/image/v1/fakes.py  |  1 +
 openstackclient/tests/unit/image/v2/fakes.py  |  1 +
 .../notes/bug-1717130-029211b60f74b4c4.yaml   |  6 +++++
 5 files changed, 28 insertions(+), 13 deletions(-)
 create mode 100644 releasenotes/notes/bug-1717130-029211b60f74b4c4.yaml

diff --git a/openstackclient/common/project_purge.py b/openstackclient/common/project_purge.py
index dff954e725..5b1d007254 100644
--- a/openstackclient/common/project_purge.py
+++ b/openstackclient/common/project_purge.py
@@ -95,7 +95,14 @@ class ProjectPurge(command.Command):
         # images
         try:
             image_client = self.app.client_manager.image
-            data = image_client.images.list(owner=project_id)
+            api_version = int(image_client.version)
+            if api_version == 1:
+                data = image_client.images.list(owner=project_id)
+            elif api_version == 2:
+                kwargs = {'filters': {'owner': project_id}}
+                data = image_client.images.list(**kwargs)
+            else:
+                raise NotImplementedError
             self.delete_objects(
                 image_client.images.delete, data, 'image', dry_run)
         except Exception:
diff --git a/openstackclient/tests/unit/common/test_project_purge.py b/openstackclient/tests/unit/common/test_project_purge.py
index 05a8aa3e22..2385eae893 100644
--- a/openstackclient/tests/unit/common/test_project_purge.py
+++ b/openstackclient/tests/unit/common/test_project_purge.py
@@ -118,8 +118,8 @@ class TestProjectPurge(TestProjectPurgeInit):
         self.projects_mock.delete.assert_called_once_with(self.project.id)
         self.servers_mock.list.assert_called_once_with(
             search_opts={'tenant_id': self.project.id})
-        self.images_mock.list.assert_called_once_with(
-            owner=self.project.id)
+        kwargs = {'filters': {'owner': self.project.id}}
+        self.images_mock.list.assert_called_once_with(**kwargs)
         volume_search_opts = {'project_id': self.project.id}
         self.volumes_mock.list.assert_called_once_with(
             search_opts=volume_search_opts)
@@ -153,8 +153,8 @@ class TestProjectPurge(TestProjectPurgeInit):
         self.projects_mock.delete.assert_not_called()
         self.servers_mock.list.assert_called_once_with(
             search_opts={'tenant_id': self.project.id})
-        self.images_mock.list.assert_called_once_with(
-            owner=self.project.id)
+        kwargs = {'filters': {'owner': self.project.id}}
+        self.images_mock.list.assert_called_once_with(**kwargs)
         volume_search_opts = {'project_id': self.project.id}
         self.volumes_mock.list.assert_called_once_with(
             search_opts=volume_search_opts)
@@ -188,8 +188,8 @@ class TestProjectPurge(TestProjectPurgeInit):
         self.projects_mock.delete.assert_not_called()
         self.servers_mock.list.assert_called_once_with(
             search_opts={'tenant_id': self.project.id})
-        self.images_mock.list.assert_called_once_with(
-            owner=self.project.id)
+        kwargs = {'filters': {'owner': self.project.id}}
+        self.images_mock.list.assert_called_once_with(**kwargs)
         volume_search_opts = {'project_id': self.project.id}
         self.volumes_mock.list.assert_called_once_with(
             search_opts=volume_search_opts)
@@ -224,8 +224,8 @@ class TestProjectPurge(TestProjectPurgeInit):
         self.projects_mock.delete.assert_called_once_with(self.project.id)
         self.servers_mock.list.assert_called_once_with(
             search_opts={'tenant_id': self.project.id})
-        self.images_mock.list.assert_called_once_with(
-            owner=self.project.id)
+        kwargs = {'filters': {'owner': self.project.id}}
+        self.images_mock.list.assert_called_once_with(**kwargs)
         volume_search_opts = {'project_id': self.project.id}
         self.volumes_mock.list.assert_called_once_with(
             search_opts=volume_search_opts)
@@ -260,8 +260,8 @@ class TestProjectPurge(TestProjectPurgeInit):
         self.projects_mock.delete.assert_called_once_with(self.project.id)
         self.servers_mock.list.assert_called_once_with(
             search_opts={'tenant_id': self.project.id})
-        self.images_mock.list.assert_called_once_with(
-            owner=self.project.id)
+        kwargs = {'filters': {'owner': self.project.id}}
+        self.images_mock.list.assert_called_once_with(**kwargs)
         volume_search_opts = {'project_id': self.project.id}
         self.volumes_mock.list.assert_called_once_with(
             search_opts=volume_search_opts)
@@ -296,8 +296,8 @@ class TestProjectPurge(TestProjectPurgeInit):
         self.projects_mock.delete.assert_called_once_with(self.project.id)
         self.servers_mock.list.assert_called_once_with(
             search_opts={'tenant_id': self.project.id})
-        self.images_mock.list.assert_called_once_with(
-            owner=self.project.id)
+        kwargs = {'filters': {'owner': self.project.id}}
+        self.images_mock.list.assert_called_once_with(**kwargs)
         volume_search_opts = {'project_id': self.project.id}
         self.volumes_mock.list.assert_called_once_with(
             search_opts=volume_search_opts)
diff --git a/openstackclient/tests/unit/image/v1/fakes.py b/openstackclient/tests/unit/image/v1/fakes.py
index 8030625743..bbec00fc06 100644
--- a/openstackclient/tests/unit/image/v1/fakes.py
+++ b/openstackclient/tests/unit/image/v1/fakes.py
@@ -64,6 +64,7 @@ class FakeImagev1Client(object):
         self.images.resource_class = fakes.FakeResource(None, {})
         self.auth_token = kwargs['token']
         self.management_url = kwargs['endpoint']
+        self.version = 1.0
 
 
 class TestImagev1(utils.TestCommand):
diff --git a/openstackclient/tests/unit/image/v2/fakes.py b/openstackclient/tests/unit/image/v2/fakes.py
index eabc932573..d82d81146f 100644
--- a/openstackclient/tests/unit/image/v2/fakes.py
+++ b/openstackclient/tests/unit/image/v2/fakes.py
@@ -156,6 +156,7 @@ class FakeImagev2Client(object):
         self.image_tags.resource_class = fakes.FakeResource(None, {})
         self.auth_token = kwargs['token']
         self.management_url = kwargs['endpoint']
+        self.version = 2.0
 
 
 class TestImagev2(utils.TestCommand):
diff --git a/releasenotes/notes/bug-1717130-029211b60f74b4c4.yaml b/releasenotes/notes/bug-1717130-029211b60f74b4c4.yaml
new file mode 100644
index 0000000000..5e069e81be
--- /dev/null
+++ b/releasenotes/notes/bug-1717130-029211b60f74b4c4.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    Fix the ``project purge`` command to correctly delete only images owned by the
+    specified project ID when run by an administrative user.
+    [Bug `1717130 <https://bugs.launchpad.net/python-openstackclient/+bug/1717130>`_]