From 33eb87b3e2d8da3ba11901c4762c19b0fc740dab Mon Sep 17 00:00:00 2001 From: Angus Salkeld Date: Thu, 25 Sep 2014 08:26:36 +1000 Subject: [PATCH] Add an option to disable cloud watch lite This also adds a deprecation warning. This also changes the default to use Ceilometer. Release message: Anyone deploying Heat should not be using OS::Heat::CWLiteAlarm, but OS::Ceilometer::Alarm. CWLiteAlarm should be explictly disabled in /etc/heat/heat.conf by setting "enable_cloud_watch_lite=false". This will stop Heat from running a period task check for alarms. DocImpact Change-Id: I2a10c14772bdafc001e211d7e94502ac1f6b32b1 Closes-bug: #1322128 --- bin/heat-engine | 7 ++++--- etc/heat/environment.d/default.yaml | 4 ++-- etc/heat/heat.conf.sample | 4 ++++ heat/common/config.py | 3 +++ heat/engine/environment.py | 7 +++++++ heat/engine/resources/cloud_watch.py | 18 +++++++++++++++--- heat/tests/common.py | 5 +++++ heat/tests/test_engine_service.py | 3 ++- heat/tests/test_provider_template.py | 11 +++++++++++ 9 files changed, 53 insertions(+), 9 deletions(-) diff --git a/bin/heat-engine b/bin/heat-engine index 2c4354c411..fbdcd1b380 100755 --- a/bin/heat-engine +++ b/bin/heat-engine @@ -55,7 +55,8 @@ if __name__ == '__main__': srv = engine.EngineService(cfg.CONF.host, rpc_api.ENGINE_TOPIC) launcher = service.launch(srv, workers=cfg.CONF.num_engine_workers) - # We create the periodic tasks here, which mean they are created - # only in the parent process when num_engine_workers>1 is specified - srv.create_periodic_tasks() + if cfg.CONF.enable_cloud_watch_lite: + # We create the periodic tasks here, which mean they are created + # only in the parent process when num_engine_workers>1 is specified + srv.create_periodic_tasks() launcher.wait() diff --git a/etc/heat/environment.d/default.yaml b/etc/heat/environment.d/default.yaml index dae1e37b21..143ee48c54 100644 --- a/etc/heat/environment.d/default.yaml +++ b/etc/heat/environment.d/default.yaml @@ -3,7 +3,7 @@ resource_registry: # allow older templates with Quantum in them. "OS::Quantum*": "OS::Neutron*" # Choose your implementation of AWS::CloudWatch::Alarm - #"AWS::CloudWatch::Alarm": "file:///etc/heat/templates/AWS_CloudWatch_Alarm.yaml" - "AWS::CloudWatch::Alarm": "OS::Heat::CWLiteAlarm" + "AWS::CloudWatch::Alarm": "file:///etc/heat/templates/AWS_CloudWatch_Alarm.yaml" + #"AWS::CloudWatch::Alarm": "OS::Heat::CWLiteAlarm" "OS::Metering::Alarm": "OS::Ceilometer::Alarm" "AWS::RDS::DBInstance": "file:///etc/heat/templates/AWS_RDS_DBInstance.yaml" diff --git a/etc/heat/heat.conf.sample b/etc/heat/heat.conf.sample index 0807f74c44..5443645c3e 100644 --- a/etc/heat/heat.conf.sample +++ b/etc/heat/heat.conf.sample @@ -70,6 +70,10 @@ # stack locking. (integer value) #engine_life_check_timeout=2 +# Enable the legacy OS::Heat::CWLiteAlarm resource. (boolean +# value) +#enable_cloud_watch_lite=true + # Deprecated. (string value) #onready= diff --git a/heat/common/config.py b/heat/common/config.py index 79bc66fa8c..1274faa0c7 100644 --- a/heat/common/config.py +++ b/heat/common/config.py @@ -137,6 +137,9 @@ engine_opts = [ default=2, help=_('RPC timeout for the engine liveness check that is used' ' for stack locking.')), + cfg.BoolOpt('enable_cloud_watch_lite', + default=True, + help=_('Enable the legacy OS::Heat::CWLiteAlarm resource.')), cfg.StrOpt('onready', help=_('Deprecated.'))] diff --git a/heat/engine/environment.py b/heat/engine/environment.py index 7fe4e4459c..383b6a38be 100644 --- a/heat/engine/environment.py +++ b/heat/engine/environment.py @@ -15,6 +15,7 @@ import copy import glob import itertools import os.path +import warnings from oslo.config import cfg import six @@ -22,6 +23,7 @@ import six from heat.common import environment_format as env_fmt from heat.common import exception from heat.common.i18n import _ +from heat.engine import support from heat.openstack.common import log @@ -215,6 +217,11 @@ class ResourceRegistry(object): LOG.info(_('Registering %(path)s -> %(value)s') % { 'path': descriptive_path, 'value': str(info.value)}) + + if isinstance(info, ClassResourceInfo): + if info.value.support_status.status != support.SUPPORTED: + warnings.warn(six.text_type(info.value.support_status.message)) + info.user_resource = (self.global_registry is not None) registry[name] = info diff --git a/heat/engine/resources/cloud_watch.py b/heat/engine/resources/cloud_watch.py index 7eb3b47f1f..ce7a95072f 100644 --- a/heat/engine/resources/cloud_watch.py +++ b/heat/engine/resources/cloud_watch.py @@ -11,10 +11,13 @@ # License for the specific language governing permissions and limitations # under the License. +from oslo.config import cfg + from heat.common import exception from heat.engine import constraints from heat.engine import properties from heat.engine import resource +from heat.engine import support from heat.engine import watchrule @@ -129,6 +132,11 @@ class CloudWatchAlarm(resource.Resource): strict_dependency = False + support_status = support.SupportStatus( + status=support.DEPRECATED, + message=_('OS::Heat::CWLiteAlarm is deprecated, ' + 'use OS::Ceilometer::Alarm instead.')) + def handle_create(self): wr = watchrule.WatchRule(context=self.context, watch_name=self.physical_resource_name(), @@ -176,6 +184,10 @@ class CloudWatchAlarm(resource.Resource): def resource_mapping(): - return { - 'OS::Heat::CWLiteAlarm': CloudWatchAlarm, - } + cfg.CONF.import_opt('enable_cloud_watch_lite', 'heat.common.config') + if cfg.CONF.enable_cloud_watch_lite: + return { + 'OS::Heat::CWLiteAlarm': CloudWatchAlarm, + } + else: + return {} diff --git a/heat/tests/common.py b/heat/tests/common.py index 6be951b148..c4b3ab3811 100644 --- a/heat/tests/common.py +++ b/heat/tests/common.py @@ -97,6 +97,11 @@ class HeatTestCase(testscenarios.WithScenarios, if templ_path not in cur_path: tri.template_name = cur_path.replace('/etc/heat/templates', templ_path) + + # use CWLiteAlarm for testing. + resources.global_env().registry.load( + {"AWS::CloudWatch::Alarm": "OS::Heat::CWLiteAlarm"}) + utils.setup_dummy_db() self.addCleanup(utils.reset_dummy_db) diff --git a/heat/tests/test_engine_service.py b/heat/tests/test_engine_service.py index a862b3e662..cdf2c46bc2 100644 --- a/heat/tests/test_engine_service.py +++ b/heat/tests/test_engine_service.py @@ -2142,7 +2142,8 @@ class StackServiceTest(HeatTestCase): def test_list_resource_types_deprecated(self): resources = self.eng.list_resource_types(self.ctx, "DEPRECATED") - self.assertEqual(['OS::Neutron::RouterGateway'], resources) + self.assertEqual(['OS::Neutron::RouterGateway', + 'OS::Heat::CWLiteAlarm'], resources) def test_list_resource_types_supported(self): resources = self.eng.list_resource_types(self.ctx, "SUPPORTED") diff --git a/heat/tests/test_provider_template.py b/heat/tests/test_provider_template.py index 03a3aa3482..13eb380edf 100644 --- a/heat/tests/test_provider_template.py +++ b/heat/tests/test_provider_template.py @@ -30,6 +30,7 @@ from heat.engine import resource from heat.engine import resources from heat.engine.resources import template_resource from heat.engine import rsrc_defn +from heat.engine import support from heat.tests.common import HeatTestCase from heat.tests import generic_resource as generic_rsrc from heat.tests import utils @@ -108,6 +109,8 @@ class ProviderTemplateTest(HeatTestCase): files = {'test_resource.template': json.dumps(provider)} class DummyResource(object): + support_status = support.SupportStatus() + attributes_schema = {"Foo": attributes.Schema("A test attribute")} properties_schema = { "Foo": {"Type": "String"}, @@ -186,6 +189,7 @@ class ProviderTemplateTest(HeatTestCase): files = {'test_resource.template': json.dumps(provider)} class DummyResource(object): + support_status = support.SupportStatus() properties_schema = {} attributes_schema = {"Foo": attributes.Schema("A test attribute")} @@ -214,6 +218,7 @@ class ProviderTemplateTest(HeatTestCase): files = {'test_resource.template': json.dumps(provider)} class DummyResource(object): + support_status = support.SupportStatus() properties_schema = {} attributes_schema = {"Foo": attributes.Schema("A test attribute")} @@ -244,6 +249,7 @@ class ProviderTemplateTest(HeatTestCase): files = {'test_resource.template': json.dumps(provider)} class DummyResource(object): + support_status = support.SupportStatus() properties_schema = {"Foo": properties.Schema(properties.Schema.STRING, required=True)} @@ -275,6 +281,7 @@ class ProviderTemplateTest(HeatTestCase): files = {'test_resource.template': json.dumps(provider)} class DummyResource(object): + support_status = support.SupportStatus() properties_schema = {"Foo": properties.Schema(properties.Schema.STRING, required=True)} @@ -306,6 +313,7 @@ class ProviderTemplateTest(HeatTestCase): files = {'test_resource.template': json.dumps(provider)} class DummyResource(object): + support_status = support.SupportStatus() properties_schema = {} attributes_schema = {} @@ -336,6 +344,7 @@ class ProviderTemplateTest(HeatTestCase): files = {'test_resource.template': json.dumps(provider)} class DummyResource(object): + support_status = support.SupportStatus() properties_schema = {"Foo": properties.Schema(properties.Schema.MAP)} attributes_schema = {} @@ -371,6 +380,7 @@ class ProviderTemplateTest(HeatTestCase): files = {'test_resource.template': json.dumps(provider)} class DummyResource(object): + support_status = support.SupportStatus() properties_schema = {"Length": properties.Schema(properties.Schema.INTEGER)} attributes_schema = {} @@ -402,6 +412,7 @@ class ProviderTemplateTest(HeatTestCase): files = {'test_resource.template': json.dumps(provider)} class DummyResource(object): + support_status = support.SupportStatus() properties_schema = {"Foo": properties.Schema(properties.Schema.BOOLEAN)} attributes_schema = {}