From 4c9cc001ba78f82411d693345cb406995d2ac702 Mon Sep 17 00:00:00 2001 From: Chris Yeoh <cyeoh@au1.ibm.com> Date: Mon, 16 Dec 2013 21:59:26 +1030 Subject: [PATCH] Adds aggregates support for Nova V3 API Adds support and tests for the os-aggregates extension for the Nova V3 API. Partially implements blueprint v3-api Change-Id: Ibe251f083ea444fb46aac9cc5cf08784b5826ad7 --- novaclient/tests/v1_1/test_aggregates.py | 99 +++++++++++++----------- novaclient/tests/v3/test_aggregates.py | 30 +++++++ novaclient/v3/aggregates.py | 26 +++++++ novaclient/v3/client.py | 2 + 4 files changed, 111 insertions(+), 46 deletions(-) create mode 100644 novaclient/tests/v3/test_aggregates.py create mode 100644 novaclient/v3/aggregates.py diff --git a/novaclient/tests/v1_1/test_aggregates.py b/novaclient/tests/v1_1/test_aggregates.py index 3367b9850..1e3247cfe 100644 --- a/novaclient/tests/v1_1/test_aggregates.py +++ b/novaclient/tests/v1_1/test_aggregates.py @@ -18,121 +18,128 @@ from novaclient.tests.v1_1 import fakes from novaclient.v1_1 import aggregates -cs = fakes.FakeClient() - - class AggregatesTest(utils.TestCase): + def setUp(self): + super(AggregatesTest, self).setUp() + self.cs = self._get_fake_client() + self.aggregate_type = self._get_aggregate_type() + + def _get_fake_client(self): + return fakes.FakeClient() + + def _get_aggregate_type(self): + return aggregates.Aggregate def test_list_aggregates(self): - result = cs.aggregates.list() - cs.assert_called('GET', '/os-aggregates') + result = self.cs.aggregates.list() + self.cs.assert_called('GET', '/os-aggregates') for aggregate in result: self.assertTrue(isinstance(aggregate, aggregates.Aggregate)) def test_create_aggregate(self): body = {"aggregate": {"name": "test", "availability_zone": "nova1"}} - aggregate = cs.aggregates.create("test", "nova1") - cs.assert_called('POST', '/os-aggregates', body) + aggregate = self.cs.aggregates.create("test", "nova1") + self.cs.assert_called('POST', '/os-aggregates', body) self.assertTrue(isinstance(aggregate, aggregates.Aggregate)) def test_get(self): - aggregate = cs.aggregates.get("1") - cs.assert_called('GET', '/os-aggregates/1') + aggregate = self.cs.aggregates.get("1") + self.cs.assert_called('GET', '/os-aggregates/1') self.assertTrue(isinstance(aggregate, aggregates.Aggregate)) - aggregate2 = cs.aggregates.get(aggregate) - cs.assert_called('GET', '/os-aggregates/1') + aggregate2 = self.cs.aggregates.get(aggregate) + self.cs.assert_called('GET', '/os-aggregates/1') self.assertTrue(isinstance(aggregate2, aggregates.Aggregate)) def test_get_details(self): - aggregate = cs.aggregates.get_details("1") - cs.assert_called('GET', '/os-aggregates/1') + aggregate = self.cs.aggregates.get_details("1") + self.cs.assert_called('GET', '/os-aggregates/1') self.assertTrue(isinstance(aggregate, aggregates.Aggregate)) - aggregate2 = cs.aggregates.get_details(aggregate) - cs.assert_called('GET', '/os-aggregates/1') + aggregate2 = self.cs.aggregates.get_details(aggregate) + self.cs.assert_called('GET', '/os-aggregates/1') self.assertTrue(isinstance(aggregate2, aggregates.Aggregate)) def test_update(self): - aggregate = cs.aggregates.get("1") + aggregate = self.cs.aggregates.get("1") values = {"name": "foo"} body = {"aggregate": values} result1 = aggregate.update(values) - cs.assert_called('PUT', '/os-aggregates/1', body) + self.cs.assert_called('PUT', '/os-aggregates/1', body) self.assertTrue(isinstance(result1, aggregates.Aggregate)) - result2 = cs.aggregates.update(2, values) - cs.assert_called('PUT', '/os-aggregates/2', body) + result2 = self.cs.aggregates.update(2, values) + self.cs.assert_called('PUT', '/os-aggregates/2', body) self.assertTrue(isinstance(result2, aggregates.Aggregate)) def test_update_with_availability_zone(self): - aggregate = cs.aggregates.get("1") + aggregate = self.cs.aggregates.get("1") values = {"name": "foo", "availability_zone": "new_zone"} body = {"aggregate": values} - result3 = cs.aggregates.update(aggregate, values) - cs.assert_called('PUT', '/os-aggregates/1', body) + result3 = self.cs.aggregates.update(aggregate, values) + self.cs.assert_called('PUT', '/os-aggregates/1', body) self.assertTrue(isinstance(result3, aggregates.Aggregate)) def test_add_host(self): - aggregate = cs.aggregates.get("1") + aggregate = self.cs.aggregates.get("1") host = "host1" body = {"add_host": {"host": "host1"}} result1 = aggregate.add_host(host) - cs.assert_called('POST', '/os-aggregates/1/action', body) + self.cs.assert_called('POST', '/os-aggregates/1/action', body) self.assertTrue(isinstance(result1, aggregates.Aggregate)) - result2 = cs.aggregates.add_host("2", host) - cs.assert_called('POST', '/os-aggregates/2/action', body) + result2 = self.cs.aggregates.add_host("2", host) + self.cs.assert_called('POST', '/os-aggregates/2/action', body) self.assertTrue(isinstance(result2, aggregates.Aggregate)) - result3 = cs.aggregates.add_host(aggregate, host) - cs.assert_called('POST', '/os-aggregates/1/action', body) + result3 = self.cs.aggregates.add_host(aggregate, host) + self.cs.assert_called('POST', '/os-aggregates/1/action', body) self.assertTrue(isinstance(result3, aggregates.Aggregate)) def test_remove_host(self): - aggregate = cs.aggregates.get("1") + aggregate = self.cs.aggregates.get("1") host = "host1" body = {"remove_host": {"host": "host1"}} result1 = aggregate.remove_host(host) - cs.assert_called('POST', '/os-aggregates/1/action', body) + self.cs.assert_called('POST', '/os-aggregates/1/action', body) self.assertTrue(isinstance(result1, aggregates.Aggregate)) - result2 = cs.aggregates.remove_host("2", host) - cs.assert_called('POST', '/os-aggregates/2/action', body) + result2 = self.cs.aggregates.remove_host("2", host) + self.cs.assert_called('POST', '/os-aggregates/2/action', body) self.assertTrue(isinstance(result2, aggregates.Aggregate)) - result3 = cs.aggregates.remove_host(aggregate, host) - cs.assert_called('POST', '/os-aggregates/1/action', body) + result3 = self.cs.aggregates.remove_host(aggregate, host) + self.cs.assert_called('POST', '/os-aggregates/1/action', body) self.assertTrue(isinstance(result3, aggregates.Aggregate)) def test_set_metadata(self): - aggregate = cs.aggregates.get("1") + aggregate = self.cs.aggregates.get("1") metadata = {"foo": "bar"} body = {"set_metadata": {"metadata": metadata}} result1 = aggregate.set_metadata(metadata) - cs.assert_called('POST', '/os-aggregates/1/action', body) + self.cs.assert_called('POST', '/os-aggregates/1/action', body) self.assertTrue(isinstance(result1, aggregates.Aggregate)) - result2 = cs.aggregates.set_metadata(2, metadata) - cs.assert_called('POST', '/os-aggregates/2/action', body) + result2 = self.cs.aggregates.set_metadata(2, metadata) + self.cs.assert_called('POST', '/os-aggregates/2/action', body) self.assertTrue(isinstance(result2, aggregates.Aggregate)) - result3 = cs.aggregates.set_metadata(aggregate, metadata) - cs.assert_called('POST', '/os-aggregates/1/action', body) + result3 = self.cs.aggregates.set_metadata(aggregate, metadata) + self.cs.assert_called('POST', '/os-aggregates/1/action', body) self.assertTrue(isinstance(result3, aggregates.Aggregate)) def test_delete_aggregate(self): - aggregate = cs.aggregates.list()[0] + aggregate = self.cs.aggregates.list()[0] aggregate.delete() - cs.assert_called('DELETE', '/os-aggregates/1') + self.cs.assert_called('DELETE', '/os-aggregates/1') - cs.aggregates.delete('1') - cs.assert_called('DELETE', '/os-aggregates/1') + self.cs.aggregates.delete('1') + self.cs.assert_called('DELETE', '/os-aggregates/1') - cs.aggregates.delete(aggregate) - cs.assert_called('DELETE', '/os-aggregates/1') + self.cs.aggregates.delete(aggregate) + self.cs.assert_called('DELETE', '/os-aggregates/1') diff --git a/novaclient/tests/v3/test_aggregates.py b/novaclient/tests/v3/test_aggregates.py new file mode 100644 index 000000000..f4ce8218a --- /dev/null +++ b/novaclient/tests/v3/test_aggregates.py @@ -0,0 +1,30 @@ +# Copyright 2013 IBM Corp. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from novaclient.tests.v1_1 import test_aggregates +from novaclient.tests.v3 import fakes +from novaclient.v3 import aggregates + + +class AggregatesTest(test_aggregates.AggregatesTest): + def setUp(self): + super(AggregatesTest, self).setUp() + self.cs = self._get_fake_client() + self.aggregate_type = self._get_aggregate_type() + + def _get_fake_client(self): + return fakes.FakeClient() + + def _get_aggregate_type(self): + return aggregates.Aggregate diff --git a/novaclient/v3/aggregates.py b/novaclient/v3/aggregates.py new file mode 100644 index 000000000..b2728d6d1 --- /dev/null +++ b/novaclient/v3/aggregates.py @@ -0,0 +1,26 @@ +# Copyright 2012 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Aggregate interface.""" + +from novaclient.v1_1 import aggregates + + +class Aggregate(aggregates.Aggregate): + pass + + +class AggregateManager(aggregates.AggregateManager): + resource_class = Aggregate diff --git a/novaclient/v3/client.py b/novaclient/v3/client.py index c28e0e8a4..5768617a4 100644 --- a/novaclient/v3/client.py +++ b/novaclient/v3/client.py @@ -16,6 +16,7 @@ from novaclient import client from novaclient.v3 import agents +from novaclient.v3 import aggregates from novaclient.v3 import availability_zones from novaclient.v3 import flavor_access from novaclient.v3 import flavors @@ -61,6 +62,7 @@ class Client(object): self.os_cache = os_cache or not no_cache #TODO(bnemec): Add back in v3 extensions self.agents = agents.AgentsManager(self) + self.aggregates = aggregates.AggregateManager(self) self.availability_zones = \ availability_zones.AvailabilityZoneManager(self) self.hosts = hosts.HostManager(self)