Implement monitoring policy in HT

Currently, monitoring policy have not been added to Heat
Translator yet. The current implementation of scaling policy
in Heat Translator showed the couple between scaling and
monitoring policies. But actually monitoring policy shows
that it could have other very good use cases so that it
can stand alone.
This patch will implement monitoring policy in HT.

Implements bp: #monitoring-policy

Change-Id: Ibc412c409846919a8edb581c7cf56e6dcd0cc01f
Depends-On: Idd5268b7ff0a19b57ea927f23c76db24220c462d
This commit is contained in:
doantungbk 2017-02-05 04:15:44 -08:00
parent cd664a5c4c
commit cb4883a551
7 changed files with 217 additions and 3 deletions

View File

@ -29,7 +29,8 @@ SECTIONS = (TYPE, PROPERTIES, MEDADATA, DEPENDS_ON, UPDATE_POLICY,
policy_type = ['tosca.policies.Placement',
'tosca.policies.Scaling',
'tosca.policies.Scaling.Cluster']
'tosca.policies.Scaling.Cluster',
'tosca.policies.Monitoring']
log = logging.getLogger('heat-translator')

View File

@ -0,0 +1,82 @@
#
# 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.
import logging
from toscaparser.common.exception import InvalidPropertyValueError
from translator.hot.syntax.hot_resource import HotResource
# Name used to dynamically load appropriate map class.
TARGET_CLASS_NAME = 'ToscaMonitoring'
log = logging.getLogger('heat-translator')
ALARM_STATISTIC = {'average': 'avg', 'summary': 'sum',
'maximum': 'max', 'minimum': 'min'}
class ToscaMonitoring(HotResource):
'''Translate TOSCA node type tosca.policies.Monitoring'''
toscatype = 'tosca.policies.Monitoring'
def __init__(self, policy, csar_dir=None):
hot_type = "OS::Aodh::Alarm"
super(ToscaMonitoring, self).__init__(policy,
type=hot_type,
csar_dir=csar_dir)
self.policy = policy
self.filter = list()
def handle_expansion(self):
'''handle monitoring resources in case of multiple triggers'''
extra_resources = list()
extra_triggers = self.policy.entity_tpl["triggers"]
for trigger_name, trigger_dict in extra_triggers.items():
if trigger_name not in self.filter:
self.filter.append(trigger_name)
prop = self._get_monitoring_prop(trigger_dict)
mon_resources = HotResource(self.nodetemplate,
type='OS::Aodh::Alarm',
name=trigger_name,
properties=prop)
extra_resources.append(mon_resources)
return extra_resources
def handle_properties(self):
self.properties = {}
if self.policy.entity_tpl.get('triggers'):
triggers = self.policy.entity_tpl["triggers"]
trigger_name, trigger_dict = list(triggers.items())[0]
self.filter.append(trigger_name)
self.properties = self._get_monitoring_prop(trigger_dict)
self.name = trigger_name
return self.properties
def _get_monitoring_prop(self, trigger):
sample = trigger.get('condition')
prop = dict()
prop["description"] = sample.get('constraint')
prop["meter_name"] = trigger.get('meter_name')
if sample.get('method') not in ALARM_STATISTIC:
msg = _('method should be one of given statistics')
log.error(msg)
raise InvalidPropertyValueError(what=msg)
prop["statistic"] = ALARM_STATISTIC[sample["method"]]
prop["period"] = sample.get("period")
prop["threshold"] = sample.get("threshold")
prop["comparison_operator"] = sample.get('comparison_operator')
prop['evaluation_periods'] = sample.get('evaluations')
return prop
def embed_substack_templates(self, hot_template_version):
pass

View File

@ -270,8 +270,12 @@ class TranslateNodeTemplates(object):
policy_type.type != 'tosca.policies.Scaling.Cluster':
TOSCA_TO_HOT_TYPE[policy_type.type] = \
TOSCA_TO_HOT_TYPE['tosca.policies.Scaling']
if not policy.is_derived_from('tosca.policies.Scaling') and \
policy_type.type not in TOSCA_TO_HOT_TYPE:
if policy.is_derived_from('tosca.policies.Monitoring'):
TOSCA_TO_HOT_TYPE[policy_type.type] = \
TOSCA_TO_HOT_TYPE['tosca.policies.Monitoring']
if not policy.is_derived_from('tosca.policies.Monitoring') and \
not policy.is_derived_from('tosca.policies.Scaling') and \
policy_type.type not in TOSCA_TO_HOT_TYPE:
raise UnsupportedTypeError(type=_('%s') % policy_type.type)
elif policy_type.type == 'tosca.policies.Scaling.Cluster':
self.hot_template_version = '2016-04-08'

View File

@ -0,0 +1,9 @@
heat_template_version: 2013-05-23
description: Tacker Scaling template
resources:
my_server_1:
type: OS::Nova::Server
properties:
flavor: m1.medium
user_data_format: SOFTWARE_CONFIG
image: rhel-6.5-test-image

View File

@ -0,0 +1,50 @@
heat_template_version: 2013-05-23
description: >
Template for deploying servers based on policies.
parameters: {}
resources:
asg_scale_out:
type: OS::Heat::ScalingPolicy
properties:
auto_scaling_group_id:
get_resource: asg_group
adjustment_type: change_in_capacity
scaling_adjustment: 1
low_cpu_usage:
type: OS::Aodh::Alarm
properties:
meter_name: cpu_util
description: utilization less_than 20%
evaluation_periods: 1
period: 600
statistic: avg
threshold: 20
comparison_operator: gt
asg_group:
type: OS::Heat::AutoScalingGroup
properties:
min_size: 2
desired_capacity: 3
resource:
type: asg_res.yaml
max_size: 10
asg_scale_in:
type: OS::Heat::ScalingPolicy
properties:
auto_scaling_group_id:
get_resource: asg_group
adjustment_type: change_in_capacity
scaling_adjustment: -1
high_cpu_usage:
type: OS::Aodh::Alarm
properties:
meter_name: cpu_util
description: utilization greater_than 60%
evaluation_periods: 1
period: 600
statistic: avg
threshold: 60
comparison_operator: gt
outputs: {}

View File

@ -0,0 +1,59 @@
tosca_definitions_version: tosca_simple_yaml_1_0
description: >
Template for deploying servers based on policies.
topology_template:
node_templates:
my_server_1:
type: tosca.nodes.Compute
capabilities:
host:
properties:
num_cpus: 2
disk_size: 10 GB
mem_size: 512 MB
os:
properties:
# host Operating System image properties
architecture: x86_64
type: Linux
distribution: RHEL
version: 6.5
policies:
- asg:
type: tosca.policies.Scaling
description: Simple node autoscaling
targets: [my_server_1]
properties:
min_instances: 2
max_instances: 10
default_instances: 3
increment: 1
- cpu_monitoring:
type: tosca.policies.Monitoring
description: Simple node monitoring
targets: [my_server_1]
triggers:
high_cpu_usage:
description: trigger
meter_name: cpu_util
condition:
constraint: utilization greater_than 60%
threshold: 60
period: 600
evaluations: 1
method: average
comparison_operator: gt
low_cpu_usage:
description: trigger
meter_name: cpu_util
condition:
constraint: utilization less_than 20%
threshold: 20
period: 600
evaluations: 1
method: average
comparison_operator: gt

View File

@ -555,3 +555,12 @@ class ToscaHotTranslationTest(TestCase):
]
params = {}
self._test_successful_translation(tosca_file, hot_files, params)
def test_hot_translate_mon_scaling_policy(self):
tosca_file = '../tests/data/monitoring/tosca_monitoring_scaling.yaml'
hot_files = [
'../tests/data/hot_output/monitoring/hot_monitoring_scaling.yaml',
'../tests/data/hot_output/monitoring/asg_res.yaml',
]
params = {}
self._test_successful_translation(tosca_file, hot_files, params)