From 9acbd3e1052d533c1395eb59de4274170baed67b Mon Sep 17 00:00:00 2001
From: Thrivikram Mudunuri <mthrivikram+opendev@gmail.com>
Date: Thu, 28 Oct 2021 18:05:03 -0400
Subject: [PATCH] Switch server image create to SDK

Switch the server image create command from novaclient to SDK. Use the
SDK versions of test fakes to support fake Server resources. Also,
fetch updated image *after* waiting. If a user requests that we wait
(--wait) for a server image to become active before returning, then we
should probably return the final image. If we don't then the image can
appear to be in a non-active state when it fact it's active. Correct
this by fetching the image after the wait call.

Change-Id: I83a403c035add9ab041ed6d59b5b29e42267f143
---
 openstackclient/compute/v2/server_image.py    | 18 ++++++-------
 .../unit/compute/v2/test_server_image.py      | 27 +++++++++----------
 ...-server-image-to-sdk-e3d8077ffe05bb3d.yaml |  4 +++
 3 files changed, 25 insertions(+), 24 deletions(-)
 create mode 100644 releasenotes/notes/migrate-create-server-image-to-sdk-e3d8077ffe05bb3d.yaml

diff --git a/openstackclient/compute/v2/server_image.py b/openstackclient/compute/v2/server_image.py
index 6c0e3b22cf..2021fae7c0 100644
--- a/openstackclient/compute/v2/server_image.py
+++ b/openstackclient/compute/v2/server_image.py
@@ -73,25 +73,23 @@ class CreateServerImage(command.ShowOne):
                 self.app.stdout.write('\rProgress: %s' % progress)
                 self.app.stdout.flush()
 
-        compute_client = self.app.client_manager.compute
+        compute_client = self.app.client_manager.sdk_connection.compute
+        image_client = self.app.client_manager.image
 
-        server = utils.find_resource(
-            compute_client.servers,
-            parsed_args.server,
+        server = compute_client.find_server(
+            parsed_args.server, ignore_missing=False,
         )
+
         if parsed_args.name:
             image_name = parsed_args.name
         else:
             image_name = server.name
 
-        image_id = compute_client.servers.create_image(
+        image_id = compute_client.create_server_image(
             server.id,
             image_name,
             parsed_args.properties,
-        )
-
-        image_client = self.app.client_manager.image
-        image = image_client.find_image(image_id)
+        ).id
 
         if parsed_args.wait:
             if utils.wait_for_status(
@@ -105,6 +103,8 @@ class CreateServerImage(command.ShowOne):
                     _('Error creating server image: %s'), parsed_args.server)
                 raise exceptions.CommandError
 
+        image = image_client.find_image(image_id, ignore_missing=False)
+
         if self.app.client_manager._api_version['image'] == '1':
             info = {}
             info.update(image._info)
diff --git a/openstackclient/tests/unit/compute/v2/test_server_image.py b/openstackclient/tests/unit/compute/v2/test_server_image.py
index 9b14428a27..b73cc763cb 100644
--- a/openstackclient/tests/unit/compute/v2/test_server_image.py
+++ b/openstackclient/tests/unit/compute/v2/test_server_image.py
@@ -27,8 +27,9 @@ class TestServerImage(compute_fakes.TestComputev2):
         super(TestServerImage, self).setUp()
 
         # Get a shortcut to the compute client ServerManager Mock
-        self.servers_mock = self.app.client_manager.compute.servers
-        self.servers_mock.reset_mock()
+        self.app.client_manager.sdk_connection = mock.Mock()
+        self.app.client_manager.sdk_connection.compute = mock.Mock()
+        self.sdk_client = self.app.client_manager.sdk_connection.compute
 
         # Get a shortcut to the image client ImageManager Mock
         self.images_mock = self.app.client_manager.image
@@ -41,14 +42,14 @@ class TestServerImage(compute_fakes.TestComputev2):
         self.methods = {}
 
     def setup_servers_mock(self, count):
-        servers = compute_fakes.FakeServer.create_servers(
+        servers = compute_fakes.FakeServer.create_sdk_servers(
             attrs=self.attrs,
             methods=self.methods,
             count=count,
         )
 
-        # This is the return value for utils.find_resource()
-        self.servers_mock.get = compute_fakes.FakeServer.get_servers(
+        # This is the return value for compute_client.find_server()
+        self.sdk_client.find_server = compute_fakes.FakeServer.get_servers(
             servers,
             0,
         )
@@ -104,8 +105,8 @@ class TestServerImageCreate(TestServerImage):
             )
 
         self.images_mock.find_image = mock.Mock(side_effect=images)
-        self.servers_mock.create_image = mock.Mock(
-            return_value=images[0].id,
+        self.sdk_client.create_server_image = mock.Mock(
+            return_value=images[0],
         )
         return images
 
@@ -126,8 +127,7 @@ class TestServerImageCreate(TestServerImage):
         # data to be shown.
         columns, data = self.cmd.take_action(parsed_args)
 
-        # ServerManager.create_image(server, image_name, metadata=)
-        self.servers_mock.create_image.assert_called_with(
+        self.sdk_client.create_server_image.assert_called_with(
             servers[0].id,
             servers[0].name,
             None,
@@ -157,8 +157,7 @@ class TestServerImageCreate(TestServerImage):
         # data to be shown.
         columns, data = self.cmd.take_action(parsed_args)
 
-        # ServerManager.create_image(server, image_name, metadata=)
-        self.servers_mock.create_image.assert_called_with(
+        self.sdk_client.create_server_image.assert_called_with(
             servers[0].id,
             'img-nam',
             {'key': 'value'},
@@ -188,8 +187,7 @@ class TestServerImageCreate(TestServerImage):
             parsed_args,
         )
 
-        # ServerManager.create_image(server, image_name, metadata=)
-        self.servers_mock.create_image.assert_called_with(
+        self.sdk_client.create_server_image.assert_called_with(
             servers[0].id,
             servers[0].name,
             None,
@@ -221,8 +219,7 @@ class TestServerImageCreate(TestServerImage):
         # data to be shown.
         columns, data = self.cmd.take_action(parsed_args)
 
-        # ServerManager.create_image(server, image_name, metadata=)
-        self.servers_mock.create_image.assert_called_with(
+        self.sdk_client.create_server_image.assert_called_with(
             servers[0].id,
             servers[0].name,
             None,
diff --git a/releasenotes/notes/migrate-create-server-image-to-sdk-e3d8077ffe05bb3d.yaml b/releasenotes/notes/migrate-create-server-image-to-sdk-e3d8077ffe05bb3d.yaml
new file mode 100644
index 0000000000..20f8d55018
--- /dev/null
+++ b/releasenotes/notes/migrate-create-server-image-to-sdk-e3d8077ffe05bb3d.yaml
@@ -0,0 +1,4 @@
+---
+features:
+  - |
+    Migrate openstack server image create from novaclient to sdk.