From 5a1983a42f2e53a2342de5cb58529f11d9964c45 Mon Sep 17 00:00:00 2001 From: Yuval Shalev Date: Mon, 3 Dec 2018 22:33:53 +0200 Subject: [PATCH] Add host aggregate missing functions Added add and remove host from aggregate. Also added set metadata to aggregate Change-Id: I8a6c082a200abefeb1f64e06b75763a866d1b895 --- openstack/compute/v2/_proxy.py | 41 +++++++++++++++++ openstack/compute/v2/aggregate.py | 26 +++++++++++ .../tests/unit/compute/v2/test_aggregate.py | 44 +++++++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/openstack/compute/v2/_proxy.py b/openstack/compute/v2/_proxy.py index db3b35efa..7d4a9fbab 100644 --- a/openstack/compute/v2/_proxy.py +++ b/openstack/compute/v2/_proxy.py @@ -187,6 +187,47 @@ class Proxy(proxy.Proxy): self._delete(_aggregate.Aggregate, aggregate, ignore_missing=ignore_missing) + def add_host_to_aggregate(self, aggregate, host): + """Adds a host to an aggregate + + :param aggregate: Either the ID of a aggregate or a + :class:`~openstack.compute.v2.aggregate.Aggregate` + instance. + :param str host: The host to add to the aggregate + + :returns: One :class:`~openstack.compute.v2.aggregate.Aggregate` + """ + aggregate = self._get_resource(_aggregate.Aggregate, aggregate) + return aggregate.add_host(self, host) + + def remove_host_from_aggregate(self, aggregate, host): + """Removes a host from an aggregate + + :param aggregate: Either the ID of a aggregate or a + :class:`~openstack.compute.v2.aggregate.Aggregate` + instance. + :param str host: The host to remove from the aggregate + + :returns: One :class:`~openstack.compute.v2.aggregate.Aggregate` + """ + aggregate = self._get_resource(_aggregate.Aggregate, aggregate) + return aggregate.remove_host(self, host) + + def set_aggregate_metadata(self, aggregate, metadata): + """Creates or replaces metadata for an aggregate + + :param aggregate: Either the ID of a aggregate or a + :class:`~openstack.compute.v2.aggregate.Aggregate` + instance. + :param dict metadata: Metadata key and value pairs. The maximum + size for each metadata key and value pair + is 255 bytes. + + :returns: One :class:`~openstack.compute.v2.aggregate.Aggregate` + """ + aggregate = self._get_resource(_aggregate.Aggregate, aggregate) + return aggregate.set_metadata(self, metadata) + def delete_image(self, image, ignore_missing=True): """Delete an image diff --git a/openstack/compute/v2/aggregate.py b/openstack/compute/v2/aggregate.py index 3a9b0c7d9..0de479492 100644 --- a/openstack/compute/v2/aggregate.py +++ b/openstack/compute/v2/aggregate.py @@ -12,6 +12,7 @@ from openstack import resource +from openstack import utils class Aggregate(resource.Resource): @@ -36,3 +37,28 @@ class Aggregate(resource.Resource): hosts = resource.Body('hosts') #: Metadata metadata = resource.Body('metadata') + + def _action(self, session, body, microversion=None): + """Preform aggregate actions given the message body.""" + url = utils.urljoin(self.base_path, self.id, 'action') + headers = {'Accept': ''} + response = session.post( + url, json=body, headers=headers, microversion=microversion) + aggregate = Aggregate() + aggregate._translate_response(response=response) + return aggregate + + def add_host(self, session, host): + """Adds a host to an aggregate.""" + body = {'add_host': {'host': host}} + return self._action(session, body) + + def remove_host(self, session, host): + """Removes a host from an aggregate.""" + body = {'remove_host': {'host': host}} + return self._action(session, body) + + def set_metadata(self, session, metadata): + """Creates or replaces metadata for an aggregate.""" + body = {'set_metadata': {'metadata': metadata}} + return self._action(session, body) diff --git a/openstack/tests/unit/compute/v2/test_aggregate.py b/openstack/tests/unit/compute/v2/test_aggregate.py index 76ff19bd8..e2ad9aa1b 100644 --- a/openstack/tests/unit/compute/v2/test_aggregate.py +++ b/openstack/tests/unit/compute/v2/test_aggregate.py @@ -10,6 +10,7 @@ # License for the specific language governing permissions and limitations # under the License. +import mock from openstack.tests.unit import base from openstack.compute.v2 import aggregate @@ -29,6 +30,16 @@ EXAMPLE = { class TestAggregate(base.TestCase): + def setUp(self): + super(TestAggregate, self).setUp() + self.resp = mock.Mock() + self.resp.body = EXAMPLE.copy() + self.resp.json = mock.Mock(return_value=self.resp.body) + self.resp.status_code = 200 + self.resp.headers = {'Accept': ''} + self.sess = mock.Mock() + self.sess.post = mock.Mock(return_value=self.resp) + def test_basic(self): sot = aggregate.Aggregate() self.assertEqual('aggregate', sot.resource_key) @@ -48,3 +59,36 @@ class TestAggregate(base.TestCase): self.assertEqual(EXAMPLE['hosts'], sot.hosts) self.assertEqual(EXAMPLE['id'], sot.id) self.assertDictEqual(EXAMPLE['metadata'], sot.metadata) + + def test_add_host(self): + sot = aggregate.Aggregate(**EXAMPLE) + + sot.add_host(self.sess, 'host1') + + url = 'os-aggregates/4/action' + body = {"add_host": {"host": "host1"}} + headers = {'Accept': ''} + self.sess.post.assert_called_with( + url, json=body, headers=headers, microversion=None) + + def test_remove_host(self): + sot = aggregate.Aggregate(**EXAMPLE) + + sot.remove_host(self.sess, 'host1') + + url = 'os-aggregates/4/action' + body = {"remove_host": {"host": "host1"}} + headers = {'Accept': ''} + self.sess.post.assert_called_with( + url, json=body, headers=headers, microversion=None) + + def test_set_metadata(self): + sot = aggregate.Aggregate(**EXAMPLE) + + sot.set_metadata(self.sess, {"key: value"}) + + url = 'os-aggregates/4/action' + body = {"set_metadata": {"metadata": {"key: value"}}} + headers = {'Accept': ''} + self.sess.post.assert_called_with( + url, json=body, headers=headers, microversion=None)