Merge "Implemented Scaling policies in heat translator"
This commit is contained in:
commit
cba5bc9ef5
@ -26,6 +26,8 @@ SECTIONS = (TYPE, PROPERTIES, MEDADATA, DEPENDS_ON, UPDATE_POLICY,
|
||||
DELETION_POLICY) = \
|
||||
('type', 'properties', 'metadata',
|
||||
'depends_on', 'update_policy', 'deletion_policy')
|
||||
|
||||
policy_type = ['tosca.policies.Placement', 'tosca.policies.Scaling']
|
||||
log = logging.getLogger('heat-translator')
|
||||
|
||||
|
||||
@ -400,7 +402,7 @@ class HotResource(object):
|
||||
def get_all_artifacts(nodetemplate):
|
||||
# workaround bug in the parser
|
||||
base_type = HotResource.get_base_type_str(nodetemplate.type_definition)
|
||||
if base_type == "tosca.policies.Placement":
|
||||
if base_type in policy_type:
|
||||
artifacts = {}
|
||||
else:
|
||||
artifacts = nodetemplate.type_definition.get_value('artifacts',
|
||||
@ -421,7 +423,7 @@ class HotResource(object):
|
||||
|
||||
# workaround bug in the parser
|
||||
base_type = HotResource.get_base_type_str(node.type_definition)
|
||||
if base_type == "tosca.policies.Placement":
|
||||
if base_type in policy_type:
|
||||
return operations
|
||||
|
||||
node_type = node.type_definition
|
||||
@ -441,7 +443,7 @@ class HotResource(object):
|
||||
def _get_interface_operations_from_type(node_type, node, lifecycle_name):
|
||||
operations = {}
|
||||
base_type = HotResource.get_base_type_str(node_type)
|
||||
if base_type == "tosca.policies.Placement":
|
||||
if base_type in policy_type:
|
||||
return operations
|
||||
if node_type.interfaces and lifecycle_name in node_type.interfaces:
|
||||
for name, elems in node_type.interfaces[lifecycle_name].items():
|
||||
|
95
translator/hot/tosca/tests/test_tosca_autoscaling.py
Normal file
95
translator/hot/tosca/tests/test_tosca_autoscaling.py
Normal file
@ -0,0 +1,95 @@
|
||||
# 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 toscaparser.nodetemplate import NodeTemplate
|
||||
from toscaparser.policy import Policy
|
||||
from toscaparser.tests.base import TestCase
|
||||
import toscaparser.utils.yamlparser
|
||||
from translator.hot.tosca.tosca_compute import ToscaCompute
|
||||
from translator.hot.tosca.tosca_policies_scaling import ToscaAutoscaling
|
||||
|
||||
|
||||
class AutoscalingTest(TestCase):
|
||||
|
||||
def _tosca_scaling_test(self, tpl_snippet, expectedprops):
|
||||
nodetemplates = (toscaparser.utils.yamlparser.
|
||||
simple_parse(tpl_snippet)['node_templates'])
|
||||
policies = (toscaparser.utils.yamlparser.
|
||||
simple_parse(tpl_snippet)['policies'])
|
||||
name = list(nodetemplates.keys())[0]
|
||||
policy_name = list(policies[0].keys())[0]
|
||||
for policy in policies:
|
||||
tpl = policy[policy_name]
|
||||
targets = tpl["targets"]
|
||||
properties = tpl["properties"]
|
||||
try:
|
||||
nodetemplate = NodeTemplate(name, nodetemplates)
|
||||
toscacompute = ToscaCompute(nodetemplate)
|
||||
toscacompute.handle_properties()
|
||||
policy = Policy(policy_name, tpl, targets,
|
||||
properties, "node_templates")
|
||||
toscascaling = ToscaAutoscaling(policy)
|
||||
parameters = toscascaling.handle_properties([toscacompute])
|
||||
self.assertEqual(parameters[0].properties, expectedprops)
|
||||
except Exception:
|
||||
raise
|
||||
|
||||
def test_compute_with_scaling(self):
|
||||
tpl_snippet = '''
|
||||
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]
|
||||
triggers:
|
||||
resize_compute:
|
||||
description: trigger
|
||||
condition:
|
||||
constraint: utilization greater_than 50%
|
||||
period: 60
|
||||
evaluations: 1
|
||||
method: average
|
||||
properties:
|
||||
min_instances: 2
|
||||
max_instances: 10
|
||||
default_instances: 3
|
||||
increment: 1
|
||||
'''
|
||||
|
||||
expectedprops = {'default_instances': 3,
|
||||
'max_size': 10,
|
||||
'min_size': 2,
|
||||
'resources': {'properties': {
|
||||
'flavor': 'm1.medium',
|
||||
'image': 'rhel-6.5-test-image',
|
||||
'user_data_format': 'SOFTWARE_CONFIG'},
|
||||
'type': 'OS::Nova::Server'}}
|
||||
|
||||
self._tosca_scaling_test(
|
||||
tpl_snippet,
|
||||
expectedprops)
|
74
translator/hot/tosca/tosca_policies_scaling.py
Normal file
74
translator/hot/tosca/tosca_policies_scaling.py
Normal file
@ -0,0 +1,74 @@
|
||||
#
|
||||
# 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 translator.hot.syntax.hot_resource import HotResource
|
||||
# Name used to dynamically load appropriate map class.
|
||||
TARGET_CLASS_NAME = 'ToscaAutoscaling'
|
||||
|
||||
|
||||
class ToscaAutoscaling(HotResource):
|
||||
'''Translate TOSCA node type tosca.policies.Scaling'''
|
||||
|
||||
toscatype = 'tosca.policies.Scaling'
|
||||
|
||||
def __init__(self, policy):
|
||||
hot_type = "OS::Heat::ScalingPolicy"
|
||||
super(ToscaAutoscaling, self).__init__(policy,
|
||||
type=hot_type)
|
||||
self.policy = policy
|
||||
|
||||
def handle_expansion(self):
|
||||
sample = self.policy.\
|
||||
entity_tpl["triggers"]["resize_compute"]["condition"]
|
||||
prop = {}
|
||||
prop["description"] = self.policy.entity_tpl['description']
|
||||
prop["meter_name"] = "cpu_util"
|
||||
prop["statistic"] = sample["method"]
|
||||
prop["period"] = sample["period"]
|
||||
prop["threshold"] = sample["evaluations"]
|
||||
prop["comparison_operator"] = "gt"
|
||||
ceilometer_resources = HotResource(self.nodetemplate,
|
||||
type='OS::Ceilometer::Alarm',
|
||||
name=self.name + '_alarm',
|
||||
properties=prop)
|
||||
hot_resources = [ceilometer_resources]
|
||||
return hot_resources
|
||||
|
||||
def handle_properties(self, resources):
|
||||
for node in self.policy.targets:
|
||||
self.properties = {}
|
||||
self.properties["auto_scaling_group_id"] = {'get_resource': node}
|
||||
self.properties["adjustment_type"] = "change_in_capacity "
|
||||
self.properties["scaling_adjustment"] = self.\
|
||||
policy.entity_tpl["properties"]["increment"]
|
||||
for index, resource in enumerate(resources):
|
||||
if resource.name in self.policy.targets and \
|
||||
resource.type != 'OS::Heat::AutoScalingGroup':
|
||||
temp = self.policy.entity_tpl["properties"]
|
||||
props = {}
|
||||
res = {}
|
||||
res["min_size"] = temp["min_instances"]
|
||||
res["max_size"] = temp["max_instances"]
|
||||
res["default_instances"] = temp["default_instances"]
|
||||
props['type'] = resource.type
|
||||
props['properties'] = resource.properties
|
||||
res['resources'] = props
|
||||
scaling_resources = \
|
||||
HotResource(resource,
|
||||
type='OS::Heat::AutoScalingGroup',
|
||||
name=resource.name,
|
||||
properties=res)
|
||||
resources.pop(index)
|
||||
resources.insert(index, scaling_resources)
|
||||
return resources
|
@ -169,11 +169,12 @@ class TranslateNodeTemplates(object):
|
||||
|
||||
if resource.type == "OS::Nova::ServerGroup":
|
||||
resource.handle_properties(self.hot_resources)
|
||||
elif resource.type == "OS::Heat::ScalingPolicy":
|
||||
self.hot_resources = resource.handle_properties(self.hot_resources)
|
||||
else:
|
||||
resource.handle_properties()
|
||||
|
||||
def _translate_nodetemplates(self):
|
||||
|
||||
log.debug(_('Translating the node templates.'))
|
||||
suffix = 0
|
||||
# Copy the TOSCA graph: nodetemplate
|
||||
@ -205,9 +206,8 @@ class TranslateNodeTemplates(object):
|
||||
break
|
||||
|
||||
suffix = suffix + 1
|
||||
attachment_node = self._get_attachment_node(node,
|
||||
suffix,
|
||||
volume_name)
|
||||
attachment_node = self._get_attachment_node(
|
||||
node, suffix, volume_name)
|
||||
if attachment_node:
|
||||
self.hot_resources.append(attachment_node)
|
||||
for i in self.tosca.inputs:
|
||||
@ -299,7 +299,8 @@ class TranslateNodeTemplates(object):
|
||||
# dependent nodes in correct order
|
||||
self.processed_resources = []
|
||||
for resource in self.hot_resources:
|
||||
self._recursive_handle_properties(resource)
|
||||
if resource.type != "OS::Heat::AutoScalingGroup":
|
||||
self._recursive_handle_properties(resource)
|
||||
|
||||
# handle resources that need to expand to more than one HOT resource
|
||||
expansion_resources = []
|
||||
|
36
translator/tests/data/hot_output/hot_autoscaling.yaml
Normal file
36
translator/tests/data/hot_output/hot_autoscaling.yaml
Normal file
@ -0,0 +1,36 @@
|
||||
heat_template_version: 2013-05-23
|
||||
|
||||
description: >
|
||||
Template for deploying servers based on policies.
|
||||
|
||||
parameters: {}
|
||||
resources:
|
||||
my_server_1:
|
||||
type: OS::Heat::AutoScalingGroup
|
||||
properties:
|
||||
min_size: 2
|
||||
default_instances: 3
|
||||
resources:
|
||||
type: OS::Nova::Server
|
||||
properties:
|
||||
flavor: m1.medium
|
||||
user_data_format: SOFTWARE_CONFIG
|
||||
image: rhel-6.5-test-image
|
||||
max_size: 10
|
||||
asg:
|
||||
type: OS::Heat::ScalingPolicy
|
||||
properties:
|
||||
auto_scaling_group_id:
|
||||
get_resource: my_server_1
|
||||
adjustment_type: change_in_capacity
|
||||
scaling_adjustment: 1
|
||||
asg_alarm:
|
||||
type: OS::Ceilometer::Alarm
|
||||
properties:
|
||||
meter_name: cpu_util
|
||||
description: Simple node autoscaling
|
||||
period: 60
|
||||
statistic: average
|
||||
threshold: 1
|
||||
comparison_operator: gt
|
||||
outputs: {}
|
40
translator/tests/data/tosca_autoscaling.yaml
Normal file
40
translator/tests/data/tosca_autoscaling.yaml
Normal file
@ -0,0 +1,40 @@
|
||||
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]
|
||||
triggers:
|
||||
resize_compute:
|
||||
description: trigger
|
||||
condition:
|
||||
constraint: utilization greater_than 50%
|
||||
period: 60
|
||||
evaluations: 1
|
||||
method: average
|
||||
properties:
|
||||
min_instances: 2
|
||||
max_instances: 10
|
||||
default_instances: 3
|
||||
increment: 1
|
@ -489,3 +489,9 @@ class ToscaHotTranslationTest(TestCase):
|
||||
hot_file = '../tests/data/hot_output/hot_exchange_public_ssh_key.yaml'
|
||||
params = {}
|
||||
self._test_successful_translation(tosca_file, hot_file, params)
|
||||
|
||||
def test_hot_translate_scaling_policy(self):
|
||||
tosca_file = '../tests/data/tosca_autoscaling.yaml'
|
||||
hot_file = '../tests/data/hot_output/hot_autoscaling.yaml'
|
||||
params = {}
|
||||
self._test_successful_translation(tosca_file, hot_file, params)
|
||||
|
Loading…
Reference in New Issue
Block a user