compute: Add Server.clear_password action
Change-Id: I5960605944fef2a300d6a3a9ff723a701e32cb64 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
parent
916f9af658
commit
67cd66688d
@ -851,6 +851,17 @@ class Proxy(proxy.Proxy):
|
|||||||
server = self._get_resource(_server.Server, server)
|
server = self._get_resource(_server.Server, server)
|
||||||
return server.get_password(self)
|
return server.get_password(self)
|
||||||
|
|
||||||
|
def clear_server_password(self, server):
|
||||||
|
"""Clear the administrator password
|
||||||
|
|
||||||
|
: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.clear_password(self)
|
||||||
|
|
||||||
def reset_server_state(self, server, state):
|
def reset_server_state(self, server, state):
|
||||||
"""Reset the state of server
|
"""Reset the state of server
|
||||||
|
|
||||||
|
@ -323,7 +323,7 @@ class Server(resource.Resource, metadata.MetadataMixin, tag.TagMixin):
|
|||||||
exceptions.raise_from_response(response)
|
exceptions.raise_from_response(response)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def change_password(self, session, password):
|
def change_password(self, session, password, *, microversion=None):
|
||||||
"""Change the administrator password to the given password.
|
"""Change the administrator password to the given password.
|
||||||
|
|
||||||
:param session: The session to use for making this request.
|
:param session: The session to use for making this request.
|
||||||
@ -331,22 +331,40 @@ class Server(resource.Resource, metadata.MetadataMixin, tag.TagMixin):
|
|||||||
:returns: None
|
:returns: None
|
||||||
"""
|
"""
|
||||||
body = {'changePassword': {'adminPass': password}}
|
body = {'changePassword': {'adminPass': password}}
|
||||||
self._action(session, body)
|
self._action(session, body, microversion=microversion)
|
||||||
|
|
||||||
def get_password(self, session):
|
def get_password(self, session, *, microversion=None):
|
||||||
"""Get the encrypted administrator password.
|
"""Get the encrypted administrator password.
|
||||||
|
|
||||||
:param session: The session to use for making this request.
|
:param session: The session to use for making this request.
|
||||||
:returns: The encrypted administrator password.
|
:returns: The encrypted administrator password.
|
||||||
"""
|
"""
|
||||||
url = utils.urljoin(Server.base_path, self.id, 'os-server-password')
|
url = utils.urljoin(Server.base_path, self.id, 'os-server-password')
|
||||||
|
if microversion is None:
|
||||||
|
microversion = self._get_microversion(session, action='commit')
|
||||||
|
|
||||||
response = session.get(url)
|
response = session.get(url, microversion=microversion)
|
||||||
exceptions.raise_from_response(response)
|
exceptions.raise_from_response(response)
|
||||||
|
|
||||||
data = response.json()
|
data = response.json()
|
||||||
return data.get('password')
|
return data.get('password')
|
||||||
|
|
||||||
|
def clear_password(self, session, *, microversion=None):
|
||||||
|
"""Clear the administrator password.
|
||||||
|
|
||||||
|
This removes the password from the database. It does not actually
|
||||||
|
change the server password.
|
||||||
|
|
||||||
|
:param session: The session to use for making this request.
|
||||||
|
:returns: None
|
||||||
|
"""
|
||||||
|
url = utils.urljoin(Server.base_path, self.id, 'os-server-password')
|
||||||
|
if microversion is None:
|
||||||
|
microversion = self._get_microversion(session, action='commit')
|
||||||
|
|
||||||
|
response = session.delete(url, microversion=microversion)
|
||||||
|
exceptions.raise_from_response(response)
|
||||||
|
|
||||||
def reboot(self, session, reboot_type):
|
def reboot(self, session, reboot_type):
|
||||||
"""Reboot server where reboot_type might be 'SOFT' or 'HARD'.
|
"""Reboot server where reboot_type might be 'SOFT' or 'HARD'.
|
||||||
|
|
||||||
|
@ -961,6 +961,30 @@ class TestCompute(TestComputeProxy):
|
|||||||
def test_server_update(self):
|
def test_server_update(self):
|
||||||
self.verify_update(self.proxy.update_server, server.Server)
|
self.verify_update(self.proxy.update_server, server.Server)
|
||||||
|
|
||||||
|
def test_server_change_password(self):
|
||||||
|
self._verify(
|
||||||
|
"openstack.compute.v2.server.Server.change_password",
|
||||||
|
self.proxy.change_server_password,
|
||||||
|
method_args=["value", "password"],
|
||||||
|
expected_args=[self.proxy, "password"],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_server_get_password(self):
|
||||||
|
self._verify(
|
||||||
|
"openstack.compute.v2.server.Server.get_password",
|
||||||
|
self.proxy.get_server_password,
|
||||||
|
method_args=["value"],
|
||||||
|
expected_args=[self.proxy],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_server_clear_password(self):
|
||||||
|
self._verify(
|
||||||
|
"openstack.compute.v2.server.Server.clear_password",
|
||||||
|
self.proxy.clear_server_password,
|
||||||
|
method_args=["value"],
|
||||||
|
expected_args=[self.proxy],
|
||||||
|
)
|
||||||
|
|
||||||
def test_server_wait_for(self):
|
def test_server_wait_for(self):
|
||||||
value = server.Server(id='1234')
|
value = server.Server(id='1234')
|
||||||
self.verify_wait_for_status(
|
self.verify_wait_for_status(
|
||||||
|
@ -10,12 +10,14 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import http
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from openstack.compute.v2 import flavor
|
from openstack.compute.v2 import flavor
|
||||||
from openstack.compute.v2 import server
|
from openstack.compute.v2 import server
|
||||||
from openstack.image.v2 import image
|
from openstack.image.v2 import image
|
||||||
from openstack.tests.unit import base
|
from openstack.tests.unit import base
|
||||||
|
from openstack.tests.unit import fakes
|
||||||
|
|
||||||
IDENTIFIER = 'IDENTIFIER'
|
IDENTIFIER = 'IDENTIFIER'
|
||||||
EXAMPLE = {
|
EXAMPLE = {
|
||||||
@ -317,6 +319,33 @@ class TestServer(base.TestCase):
|
|||||||
microversion=self.sess.default_microversion,
|
microversion=self.sess.default_microversion,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_get_password(self):
|
||||||
|
sot = server.Server(**EXAMPLE)
|
||||||
|
self.sess.get.return_value = fakes.FakeResponse(
|
||||||
|
data={'password': 'foo'}
|
||||||
|
)
|
||||||
|
|
||||||
|
result = sot.get_password(self.sess)
|
||||||
|
self.assertEqual('foo', result)
|
||||||
|
|
||||||
|
url = 'servers/IDENTIFIER/os-server-password'
|
||||||
|
self.sess.get.assert_called_with(
|
||||||
|
url, microversion=self.sess.default_microversion
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_clear_password(self):
|
||||||
|
sot = server.Server(**EXAMPLE)
|
||||||
|
self.sess.delete.return_value = fakes.FakeResponse(
|
||||||
|
status_code=http.HTTPStatus.NO_CONTENT,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertIsNone(sot.clear_password(self.sess))
|
||||||
|
|
||||||
|
url = 'servers/IDENTIFIER/os-server-password'
|
||||||
|
self.sess.delete.assert_called_with(
|
||||||
|
url, microversion=self.sess.default_microversion
|
||||||
|
)
|
||||||
|
|
||||||
def test_reboot(self):
|
def test_reboot(self):
|
||||||
sot = server.Server(**EXAMPLE)
|
sot = server.Server(**EXAMPLE)
|
||||||
|
|
||||||
|
@ -13,8 +13,11 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import json
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
class FakeTransport(mock.Mock):
|
class FakeTransport(mock.Mock):
|
||||||
RESPONSE = mock.Mock('200 OK')
|
RESPONSE = mock.Mock('200 OK')
|
||||||
@ -35,3 +38,19 @@ class FakeAuthenticator(mock.Mock):
|
|||||||
self.get_token.return_value = self.TOKEN
|
self.get_token.return_value = self.TOKEN
|
||||||
self.get_endpoint = mock.Mock()
|
self.get_endpoint = mock.Mock()
|
||||||
self.get_endpoint.return_value = self.ENDPOINT
|
self.get_endpoint.return_value = self.ENDPOINT
|
||||||
|
|
||||||
|
|
||||||
|
class FakeResponse(requests.Response):
|
||||||
|
def __init__(
|
||||||
|
self, headers=None, status_code=200, data=None, encoding=None
|
||||||
|
):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
headers = headers or {}
|
||||||
|
|
||||||
|
self.status_code = status_code
|
||||||
|
|
||||||
|
self.headers.update(headers)
|
||||||
|
self._content = json.dumps(data)
|
||||||
|
if not isinstance(self._content, bytes):
|
||||||
|
self._content = self._content.encode()
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
The ``Server.clear_password`` and equivalent ``clear_server_password``
|
||||||
|
proxy method have been added.
|
Loading…
x
Reference in New Issue
Block a user