diff --git a/doc/source/users/proxies/compute.rst b/doc/source/users/proxies/compute.rst index 5a5f25364..7c6573816 100644 --- a/doc/source/users/proxies/compute.rst +++ b/doc/source/users/proxies/compute.rst @@ -61,6 +61,7 @@ Starting, Stopping, etc. .. automethod:: openstack.compute.v2._proxy.Proxy.rescue_server .. automethod:: openstack.compute.v2._proxy.Proxy.unrescue_server .. automethod:: openstack.compute.v2._proxy.Proxy.evacuate_server + .. automethod:: openstack.compute.v2._proxy.Proxy.migrate_server Modifying a Server ****************** diff --git a/openstack/compute/v2/_proxy.py b/openstack/compute/v2/_proxy.py index 6d342d91a..dbdfa6822 100644 --- a/openstack/compute/v2/_proxy.py +++ b/openstack/compute/v2/_proxy.py @@ -1244,3 +1244,14 @@ class Proxy(proxy2.BaseProxy): server_id = resource2.Resource._get_id(server) return self._list(_volume_attachment.VolumeAttachment, paginated=False, server_id=server_id) + + def migrate_server(self, server): + """Migrate a server from one host to another + + :param server: Either the ID of a server or a + :class:`~openstack.compute.v2.server.Server` instance. + :returns: None + """ + + server = self._get_resource(_server.Server, server) + server.migrate(self._session) diff --git a/openstack/compute/v2/server.py b/openstack/compute/v2/server.py index 75c89a364..6618a0939 100644 --- a/openstack/compute/v2/server.py +++ b/openstack/compute/v2/server.py @@ -336,6 +336,10 @@ class Server(resource2.Resource, metadata.MetadataMixin): body = {"unshelve": None} self._action(session, body) + def migrate(self, session): + body = {"migrate": None} + self._action(session, body) + class ServerDetail(Server): base_path = '/servers/detail' diff --git a/openstack/tests/unit/compute/v2/test_server.py b/openstack/tests/unit/compute/v2/test_server.py index 0c5109e36..0e60d050d 100644 --- a/openstack/tests/unit/compute/v2/test_server.py +++ b/openstack/tests/unit/compute/v2/test_server.py @@ -606,3 +606,15 @@ class TestServer(testtools.TestCase): headers = {'Accept': ''} self.sess.post.assert_called_with( url, endpoint_filter=sot.service, json=body, headers=headers) + + def test_migrate(self): + sot = server.Server(**EXAMPLE) + + res = sot.migrate(self.sess) + + self.assertIsNone(res) + url = 'servers/IDENTIFIER/action' + body = {"migrate": None} + headers = {'Accept': ''} + self.sess.post.assert_called_with( + url, endpoint_filter=sot.service, json=body, headers=headers)