diff --git a/translator/hot/tosca/tests/test_tosca_autoscaling.py b/translator/hot/tosca/tests/test_tosca_autoscaling.py index a0fe16f9..ee44f316 100644 --- a/translator/hot/tosca/tests/test_tosca_autoscaling.py +++ b/translator/hot/tosca/tests/test_tosca_autoscaling.py @@ -10,17 +10,25 @@ # License for the specific language governing permissions and limitations # under the License. +import datetime +import yaml + from toscaparser.nodetemplate import NodeTemplate from toscaparser.policy import Policy from toscaparser.tests.base import TestCase import toscaparser.utils.yamlparser + +from translator.hot.syntax.hot_parameter import HotParameter from translator.hot.tosca.tosca_compute import ToscaCompute from translator.hot.tosca.tosca_policies_scaling import ToscaAutoscaling +HOT_TEMPLATE_VERSION = '2013-05-23' + class AutoscalingTest(TestCase): - def _tosca_scaling_test(self, tpl_snippet, expectedprops): + def _tosca_scaling_test(self, tpl_snippet, expectedprops, + hot_template_parameters=None): nodetemplates = (toscaparser.utils.yamlparser. simple_parse(tpl_snippet)['node_templates']) policies = (toscaparser.utils.yamlparser. @@ -37,9 +45,18 @@ class AutoscalingTest(TestCase): toscacompute.handle_properties() policy = Policy(policy_name, tpl, targets, properties, "node_templates") - toscascaling = ToscaAutoscaling(policy) + toscascaling = ToscaAutoscaling( + policy, hot_template_parameters=hot_template_parameters) parameters = toscascaling.handle_properties([toscacompute]) - self.assertEqual(parameters[0].properties, expectedprops) + if hot_template_parameters: + substack_template = toscascaling.extract_substack_templates( + "output.yaml", HOT_TEMPLATE_VERSION) + actual_nested_resource = yaml.load( + substack_template['SP1_res.yaml']) + self.assertEqual(expectedprops, + actual_nested_resource) + else: + self.assertEqual(parameters[0].properties, expectedprops) except Exception: raise @@ -93,3 +110,75 @@ class AutoscalingTest(TestCase): self._tosca_scaling_test( tpl_snippet, expectedprops) + + def test_scaling_nested_template_with_params(self): + tpl_snippet = ''' + node_templates: + VDU1: + type: tosca.nodes.Compute + properties: + image: { get_input: image_name } + flavor: { get_input: flavor } + mgmt_driver: noop + availability_zone: nova + metadata: {metering.server_group: SG1} + + policies: + - SP1: + type: tosca.policies.Scaling + targets: [VDU1] + properties: + increment: 1 + cooldown: 120 + min_instances: 1 + max_instances: 3 + default_instances: 1 + ''' + + expected_nested_resource = {'heat_template_version': + datetime.date(2013, 5, 23), + 'description': + 'Tacker Scaling template', + 'parameters': + {'flavor': + {'default': 'm1.tiny', + 'type': 'string', + 'description': + 'Flavor Information' + }, + 'image_name': + {'default': + 'cirros-0.3.5-x86_64-disk', + 'type': 'string', + 'description': 'Image Name' + } + }, + 'resources': + {'VDU1': + {'type': + 'OS::Nova::Server', + 'properties': + {'flavor': None, + 'user_data_format': + 'SOFTWARE_CONFIG' + } + } + } + } + + flavor = HotParameter('flavor', 'string', + label=None, + description='Flavor Information', + default='m1.tiny', + hidden=None, + constraints=[]) + image = HotParameter('image_name', 'string', + label=None, + description='Image Name', + default='cirros-0.3.5-x86_64-disk', + hidden=None, + constraints=[]) + hot_template_parameters = [flavor, image] + self._tosca_scaling_test(tpl_snippet, + expected_nested_resource, + hot_template_parameters) diff --git a/translator/hot/tosca/tosca_policies_scaling.py b/translator/hot/tosca/tosca_policies_scaling.py index b1430228..e8722d5a 100644 --- a/translator/hot/tosca/tosca_policies_scaling.py +++ b/translator/hot/tosca/tosca_policies_scaling.py @@ -34,12 +34,13 @@ class ToscaAutoscaling(HotResource): toscatype = 'tosca.policies.Scaling' - def __init__(self, policy, csar_dir=None): + def __init__(self, policy, csar_dir=None, hot_template_parameters=None): hot_type = "OS::Heat::ScalingPolicy" super(ToscaAutoscaling, self).__init__(policy, type=hot_type, csar_dir=csar_dir) self.policy = policy + self.hot_template_parameters = hot_template_parameters def handle_expansion(self): if self.policy.entity_tpl.get('triggers'): @@ -76,6 +77,12 @@ class ToscaAutoscaling(HotResource): def _handle_nested_template(self, scale_res): template_dict = yaml.safe_load(HEAT_TEMPLATE_BASE) template_dict['description'] = 'Tacker Scaling template' + if self.hot_template_parameters: + all_params = OrderedDict() + for parameter in self.hot_template_parameters: + all_params.update(parameter.get_dict_output()) + template_dict.update({'parameters': all_params}) + template_dict["resources"] = {} dict_res = OrderedDict() for res in scale_res: @@ -87,7 +94,7 @@ class ToscaAutoscaling(HotResource): yaml.add_representer(OrderedDict, self.represent_ordereddict) yaml.add_representer(dict, self.represent_ordereddict) yaml_string = yaml.dump(template_dict, default_flow_style=False) - yaml_string = yaml_string.replace('\'', '') .replace('\n\n', '\n') + yaml_string = yaml_string.replace('\'', '').replace('\n\n', '\n') self.nested_template = { self.policy.name + '_res.yaml': yaml_string } diff --git a/translator/hot/translate_node_templates.py b/translator/hot/translate_node_templates.py index adcca5d1..05d6973c 100644 --- a/translator/hot/translate_node_templates.py +++ b/translator/hot/translate_node_templates.py @@ -283,7 +283,13 @@ class TranslateNodeTemplates(object): raise UnsupportedTypeError(type=_('%s') % policy_type.type) elif policy_type.type == 'tosca.policies.Scaling.Cluster': self.hot_template_version = '2016-04-08' - policy_node = TOSCA_TO_HOT_TYPE[policy_type.type](policy) + if policy.is_derived_from('tosca.policies.Scaling') and \ + policy_type.type != 'tosca.policies.Scaling.Cluster': + policy_node = TOSCA_TO_HOT_TYPE[policy_type.type]( + policy, + hot_template_parameters=self.hot_template.parameters) + else: + policy_node = TOSCA_TO_HOT_TYPE[policy_type.type](policy) self.hot_resources.append(policy_node) # Handle life cycle operations: this may expand each node diff --git a/translator/tests/data/hot_output/nfv/SP_res.yaml b/translator/tests/data/hot_output/nfv/SP_res.yaml new file mode 100644 index 00000000..c993ffc5 --- /dev/null +++ b/translator/tests/data/hot_output/nfv/SP_res.yaml @@ -0,0 +1,29 @@ +heat_template_version: 2013-05-23 +description: Tacker Scaling template + +parameters: + flavor: {type: string, default: m1.tiny, description: Flavor Information} + image_name: {type: string, default: cirros-0.3.5-x86_64-disk, description: Image Name} + +resources: + VDU1: + type: OS::Nova::Server + properties: + user_data_format: SOFTWARE_CONFIG + availability_zone: nova + flavor: {get_param: flavor} + user_data_format: SOFTWARE_CONFIG + image: {get_param: image_name} + config_drive: False + networks: + - port: { get_resource: CP1 } + metadata: + metering.server_group: SG1 + CP1: + type: OS::Neutron::Port + properties: + anti_spoofing_protection: False + management: True + network: net_mgmt + VL1: + type: OS::Neutron::Net diff --git a/translator/tests/data/hot_output/nfv/hot_tosca_nfv_autoscaling_with_param.yaml b/translator/tests/data/hot_output/nfv/hot_tosca_nfv_autoscaling_with_param.yaml new file mode 100644 index 00000000..ad21affa --- /dev/null +++ b/translator/tests/data/hot_output/nfv/hot_tosca_nfv_autoscaling_with_param.yaml @@ -0,0 +1,66 @@ +heat_template_version: 2013-05-23 + +description: > + Demo example + +parameters: + flavor: + default: m1.tiny + type: string + description: Flavor Information + + image_name: + default: cirros-0.3.5-x86_64-disk + type: string + description: Image Name + +resources: + SP_group: + type: OS::Heat::AutoScalingGroup + properties: + min_size: 1 + desired_capacity: 1 + cooldown: 120 + resource: + type: SP_res.yaml + max_size: 3 + SP_scale_out: + type: OS::Heat::ScalingPolicy + properties: + auto_scaling_group_id: + get_resource: SP_group + adjustment_type: change_in_capacity + scaling_adjustment: 1 + cooldown: 120 + SP_scale_in: + type: OS::Heat::ScalingPolicy + properties: + auto_scaling_group_id: + get_resource: SP_group + adjustment_type: change_in_capacity + scaling_adjustment: -1 + cooldown: 120 + vdu_hcpu_usage_scaling_out: + type: OS::Aodh::GnocchiAggregationByResourcesAlarm + properties: + metric: cpu_util + description: utilization greater_than 80% + evaluation_periods: 1 + granularity: 60 + aggregation_method: mean + threshold: 80 + resource_type: instance + comparison_operator: gt + vdu_lcpu_usage_scaling_in: + type: OS::Aodh::GnocchiAggregationByResourcesAlarm + properties: + metric: cpu_util + description: utilization less_than 10% + evaluation_periods: 1 + granularity: 60 + aggregation_method: mean + threshold: 10 + resource_type: instance + comparison_operator: lt + +outputs: {} diff --git a/translator/tests/data/hot_output/reservation/SP_RSV_res.yaml b/translator/tests/data/hot_output/reservation/SP_RSV_res.yaml index 8394a8ef..5b1c9bac 100644 --- a/translator/tests/data/hot_output/reservation/SP_RSV_res.yaml +++ b/translator/tests/data/hot_output/reservation/SP_RSV_res.yaml @@ -2,6 +2,10 @@ heat_template_version: 2013-05-23 description: Tacker Scaling template +parameters: + flavor: {type: string, description: Flavor Information} + lease_id: {type: string, description: lease id} + resources: VDU1: type: OS::Nova::Server diff --git a/translator/tests/data/nfv/test_tosca_nfv_autoscaling_with_params.yaml b/translator/tests/data/nfv/test_tosca_nfv_autoscaling_with_params.yaml new file mode 100644 index 00000000..aee064b2 --- /dev/null +++ b/translator/tests/data/nfv/test_tosca_nfv_autoscaling_with_params.yaml @@ -0,0 +1,94 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: Demo example + +imports: + - tacker_defs.yaml + - tacker_nfv_defs.yaml + +metadata: + template_name: sample-tosca-vnfd + +topology_template: + inputs: + image_name: + type: string + description: Image Name + + flavor: + type: string + description: Flavor Information + + node_templates: + VDU1: + type: tosca.nodes.nfv.VDU.Tacker + properties: + image: { get_input: image_name } + flavor: { get_input: flavor } + mgmt_driver: noop + availability_zone: nova + metadata: {metering.server_group: SG1} + + CP1: + type: tosca.nodes.nfv.CP.Tacker + properties: + management: true + anti_spoofing_protection: false + requirements: + - virtualLink: + node: VL1 + - virtualBinding: + node: VDU1 + + VL1: + type: tosca.nodes.nfv.VL + properties: + network_name: net_mgmt + vendor: Tacker + + policies: + - SP: + type: tosca.policies.tacker.Scaling + targets: [VDU1] + properties: + increment: 1 + cooldown: 120 + min_instances: 1 + max_instances: 3 + default_instances: 1 + + - vdu_cpu_usage_monitoring_policy: + type: tosca.policies.tacker.Alarming + triggers: + vdu_hcpu_usage_scaling_out: + event_type: + type: tosca.events.resource.utilization + implementation: ceilometer + metric: cpu_util + condition: + threshold: 80 + constraint: utilization greater_than 80% + granularity: 60 + evaluations: 1 + aggregation_method: mean + resource_type: instance + comparison_operator: gt + metadata: SG1 + action: [SP] + + vdu_lcpu_usage_scaling_in: + event_type: + type: tosca.events.resource.utilization + implementation: ceilometer + metric: cpu_util + condition: + threshold: 10 + constraint: utilization less_than 10% + granularity: 60 + evaluations: 1 + aggregation_method: mean + resource_type: instance + comparison_operator: lt + metadata: SG1 + action: [SP] + diff --git a/translator/tests/test_tosca_hot_translation.py b/translator/tests/test_tosca_hot_translation.py index d0aee31d..21d9fd03 100644 --- a/translator/tests/test_tosca_hot_translation.py +++ b/translator/tests/test_tosca_hot_translation.py @@ -593,6 +593,18 @@ class ToscaHotTranslationTest(TestCase): params = {} self._test_successful_translation(tosca_file, hot_files, params) + def test_hot_translate_nfv_scaling_with_params(self): + tosca_file = '../tests/data/nfv/test_tosca_nfv_autoscaling_with_' \ + 'params.yaml' + hot_files = [ + '../tests/data/hot_output/nfv/hot_tosca_nfv_autoscaling_with_' + 'param.yaml', + '../tests/data/hot_output/nfv/SP_res.yaml', + ] + params = {'image_name': 'cirros-0.3.5-x86_64-disk', + 'flavor': 'm1.tiny'} + 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 = [