From eeb9bb122e50912c56275a3b907a00931b363061 Mon Sep 17 00:00:00 2001 From: Anderson Mesquita Date: Mon, 25 Aug 2014 10:44:46 -0700 Subject: [PATCH] Implement check for Rackspace resources Since stack-check has been accepted, this patch implements handle_check for all Rackspace resources. Implements: blueprint stack-check Change-Id: Ibdeded33a32ddef07df572ce7d44b5a51afc5df7 --- .../rackspace/resources/auto_scale.py | 3 ++ .../rackspace/resources/cloud_dns.py | 3 ++ .../rackspace/resources/cloud_loadbalancer.py | 6 ++++ .../rackspace/resources/cloudnetworks.py | 3 ++ .../rackspace/tests/test_auto_scale.py | 18 +++++++++++ .../tests/test_cloud_loadbalancer.py | 32 +++++++++++++++++-- .../rackspace/tests/test_cloudnetworks.py | 12 +++++++ .../rackspace/tests/test_rackspace_dns.py | 21 ++++++++++++ 8 files changed, 96 insertions(+), 2 deletions(-) diff --git a/contrib/rackspace/rackspace/resources/auto_scale.py b/contrib/rackspace/rackspace/resources/auto_scale.py index f218d536e..acbac0120 100644 --- a/contrib/rackspace/rackspace/resources/auto_scale.py +++ b/contrib/rackspace/rackspace/resources/auto_scale.py @@ -328,6 +328,9 @@ class Group(resource.Resource): group = asclient.create(**self._get_create_args()) self.resource_id_set(str(group.id)) + def handle_check(self): + self.auto_scale().get(self.resource_id) + def handle_update(self, json_snippet, tmpl_diff, prop_diff): """Update the group configuration and the launch configuration.""" asclient = self.auto_scale() diff --git a/contrib/rackspace/rackspace/resources/cloud_dns.py b/contrib/rackspace/rackspace/resources/cloud_dns.py index 8c60d5174..e09afa7c4 100644 --- a/contrib/rackspace/rackspace/resources/cloud_dns.py +++ b/contrib/rackspace/rackspace/resources/cloud_dns.py @@ -163,6 +163,9 @@ class CloudDns(resource.Resource): dom = self.cloud_dns().create(**args) self.resource_id_set(dom.id) + def handle_check(self): + self.cloud_dns().get(self.resource_id) + def handle_update(self, json_snippet, tmpl_diff, prop_diff): """Update a Rackspace CloudDns Instance.""" LOG.debug("CloudDns handle_update called.") diff --git a/contrib/rackspace/rackspace/resources/cloud_loadbalancer.py b/contrib/rackspace/rackspace/resources/cloud_loadbalancer.py index 3c3188a8d..25f420dac 100644 --- a/contrib/rackspace/rackspace/resources/cloud_loadbalancer.py +++ b/contrib/rackspace/rackspace/resources/cloud_loadbalancer.py @@ -532,6 +532,12 @@ class CloudLoadBalancer(resource.Resource): def check_create_complete(self, loadbalancer): return self._check_status(loadbalancer, ['ACTIVE']) + def handle_check(self): + loadbalancer = self.clb.get(self.resource_id) + if not self._check_status(loadbalancer, ['ACTIVE']): + raise exception.Error(_("Cloud LoadBalancer is not ACTIVE " + "(was: %s)") % loadbalancer.status) + def handle_update(self, json_snippet, tmpl_diff, prop_diff): """Add and remove nodes specified in the prop_diff.""" loadbalancer = self.clb.get(self.resource_id) diff --git a/contrib/rackspace/rackspace/resources/cloudnetworks.py b/contrib/rackspace/rackspace/resources/cloudnetworks.py index e86c991fc..8e8e46c37 100644 --- a/contrib/rackspace/rackspace/resources/cloudnetworks.py +++ b/contrib/rackspace/rackspace/resources/cloudnetworks.py @@ -105,6 +105,9 @@ class CloudNetwork(resource.Resource): cidr=self.properties[self.CIDR]) self.resource_id_set(cnw.id) + def handle_check(self): + self.cloud_networks().get(self.resource_id) + def handle_delete(self): net = self.network() if net: diff --git a/contrib/rackspace/rackspace/tests/test_auto_scale.py b/contrib/rackspace/rackspace/tests/test_auto_scale.py index 40b30bbe8..a0151e3c5 100644 --- a/contrib/rackspace/rackspace/tests/test_auto_scale.py +++ b/contrib/rackspace/rackspace/tests/test_auto_scale.py @@ -14,6 +14,8 @@ import copy import itertools +import mock + from heat.common import exception from heat.common import template_format from heat.engine import resource @@ -311,6 +313,22 @@ Resources: resource = self.stack['my_group'] self.assertEqual('0', resource.FnGetRefId()) + def test_check(self): + self._setup_test_stack() + resource = self.stack['my_group'] + mock_get = mock.Mock() + resource.auto_scale().get = mock_get + scheduler.TaskRunner(resource.check)() + self.assertEqual('CHECK', resource.action) + self.assertEqual('COMPLETE', resource.status) + + mock_get.side_effect = auto_scale.NotFound('boom') + exc = self.assertRaises(exception.ResourceFailure, + scheduler.TaskRunner(resource.check)) + self.assertEqual('CHECK', resource.action) + self.assertEqual('FAILED', resource.status) + self.assertIn('boom', str(exc)) + def test_update_group_config(self): """ Updating the groupConfiguration section in a template results in a diff --git a/contrib/rackspace/rackspace/tests/test_cloud_loadbalancer.py b/contrib/rackspace/rackspace/tests/test_cloud_loadbalancer.py index e04de3899..837deb21f 100644 --- a/contrib/rackspace/rackspace/tests/test_cloud_loadbalancer.py +++ b/contrib/rackspace/rackspace/tests/test_cloud_loadbalancer.py @@ -429,8 +429,7 @@ class LoadBalancerTest(common.HeatTestCase): self.lb_name, expected) - exc = self.assertRaises(exception.StackValidationFailed, - rsrc.validate) + exc = self.assertRaises(exception.StackValidationFailed, rsrc.validate) self.assertIn("Property certificate not assigned", six.text_type(exc)) ssl_termination['certificate'] = 'dfaewfwef' @@ -524,6 +523,35 @@ class LoadBalancerTest(common.HeatTestCase): scheduler.TaskRunner(rsrc.create)() self.m.VerifyAll() + def test_check(self): + stack = mock.Mock() + stack.db_resource_get.return_value = None + resdef = mock.Mock(spec=rsrc_defn.ResourceDefinition) + loadbalancer = lb.CloudLoadBalancer("test", resdef, stack) + loadbalancer._add_event = mock.Mock() + mock_cloud_lb = mock.Mock() + mock_get = mock.Mock(return_value=mock_cloud_lb) + loadbalancer.clb.get = mock_get + + mock_cloud_lb.status = 'ACTIVE' + scheduler.TaskRunner(loadbalancer.check)() + self.assertEqual('CHECK', loadbalancer.action) + self.assertEqual('COMPLETE', loadbalancer.status) + + mock_cloud_lb.status = 'FOOBAR' + exc = self.assertRaises(exception.ResourceFailure, + scheduler.TaskRunner(loadbalancer.check)) + self.assertEqual('CHECK', loadbalancer.action) + self.assertEqual('FAILED', loadbalancer.status) + self.assertIn('FOOBAR', str(exc)) + + mock_get.side_effect = lb.NotFound('boom') + exc = self.assertRaises(exception.ResourceFailure, + scheduler.TaskRunner(loadbalancer.check)) + self.assertEqual('CHECK', loadbalancer.action) + self.assertEqual('FAILED', loadbalancer.status) + self.assertIn('boom', str(exc)) + def test_update_add_node_by_address(self): expected_ip = '172.168.1.4' added_node = {'nodes': [ diff --git a/contrib/rackspace/rackspace/tests/test_cloudnetworks.py b/contrib/rackspace/rackspace/tests/test_cloudnetworks.py index 2a5efdee5..6dbf960a8 100644 --- a/contrib/rackspace/rackspace/tests/test_cloudnetworks.py +++ b/contrib/rackspace/rackspace/tests/test_cloudnetworks.py @@ -123,6 +123,18 @@ class CloudNetworkTest(common.HeatTestCase): self.stack.validate) self.assertIn("Invalid cidr", six.text_type(exc)) + def test_check(self, mock_client): + self._setup_stack(mock_client) + res = self.stack['cnw'] + scheduler.TaskRunner(res.check)() + self.assertEqual((res.CHECK, res.COMPLETE), res.state) + + self.fake_cnw.networks = [] + exc = self.assertRaises(exception.ResourceFailure, + scheduler.TaskRunner(res.check)) + self.assertEqual((res.CHECK, res.FAILED), res.state) + self.assertIn('No network', str(exc)) + def test_delete(self, mock_client): self._setup_stack(mock_client) res = self.stack['cnw'] diff --git a/contrib/rackspace/rackspace/tests/test_rackspace_dns.py b/contrib/rackspace/rackspace/tests/test_rackspace_dns.py index 261631209..aa8e664d5 100644 --- a/contrib/rackspace/rackspace/tests/test_rackspace_dns.py +++ b/contrib/rackspace/rackspace/tests/test_rackspace_dns.py @@ -13,6 +13,9 @@ import uuid +import mock + +from heat.common import exception from heat.common import template_format from heat.engine import environment from heat.engine import parser @@ -210,6 +213,24 @@ class RackspaceDnsTest(common.HeatTestCase): self.assertEqual((instance.CREATE, instance.COMPLETE), instance.state) self.m.VerifyAll() + def test_check(self): + t = template_format.parse(domain_only_template) + instance = self._setup_test_cloud_dns_instance('dnsinstance_create', t) + + mock_get = mock.Mock() + instance.cloud_dns = mock.Mock() + instance.cloud_dns.return_value.get = mock_get + scheduler.TaskRunner(instance.check)() + self.assertEqual('CHECK', instance.action) + self.assertEqual('COMPLETE', instance.status) + + mock_get.side_effect = cloud_dns.NotFound('boom') + exc = self.assertRaises(exception.ResourceFailure, + scheduler.TaskRunner(instance.check)) + self.assertEqual('CHECK', instance.action) + self.assertEqual('FAILED', instance.status) + self.assertIn('boom', str(exc)) + def test_update(self, updateRecords=None): """ Helper function for testing domain updates.