From 30f4d2ff8371bb7a33d2790ca5df77de951965ee Mon Sep 17 00:00:00 2001 From: nirajsingh Date: Fri, 10 Aug 2018 13:17:38 +0900 Subject: [PATCH] Support reservation policy in heat-translator Implementation of reservation policy in heat-translator Tacker Blueprint: https://blueprints.launchpad.net/tacker/+spec/reservation-vnfm Tacker Spec: https://review.openstack.org/#/c/561840/ Depends-On: Ic5d790df938b40d75bc50252e1e688e9c09eb568 Change-Id: I2b989a49ac3447995a82ddb7193bf478bb847b73 --- lower-constraints.txt | 2 +- requirements.txt | 2 +- translator/hot/syntax/hot_resource.py | 3 +- .../hot/tosca/tosca_policies_reservation.py | 64 +++++++++++++++++++ .../hot/tosca/tosca_policies_scaling.py | 3 +- translator/hot/translate_node_templates.py | 3 + .../hot_output/reservation/SP_RSV_res.yaml | 23 +++++++ .../reservation/hot_reservation_scaling.yaml | 44 +++++++++++++ translator/tests/data/nfv/tacker_defs.yaml | 23 +++++++ .../tosca-vnfd-reservation-id.yaml | 60 +++++++++++++++++ .../tests/test_tosca_hot_translation.py | 9 +++ 11 files changed, 232 insertions(+), 4 deletions(-) create mode 100644 translator/hot/tosca/tosca_policies_reservation.py create mode 100644 translator/tests/data/hot_output/reservation/SP_RSV_res.yaml create mode 100644 translator/tests/data/hot_output/reservation/hot_reservation_scaling.yaml create mode 100644 translator/tests/data/reservation/tosca-vnfd-reservation-id.yaml diff --git a/lower-constraints.txt b/lower-constraints.txt index 6cae1499..f7a6fb1a 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -75,7 +75,7 @@ stevedore==1.20.0 testrepository==0.0.18 testscenarios==0.4 testtools==2.2.0 -tosca-parser==1.0.0 +tosca-parser==1.4.0 traceback2==1.4.0 unittest2==1.1.0 warlock==1.2.0 diff --git a/requirements.txt b/requirements.txt index 24744928..e5f5c477 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ cliff!=2.9.0,>=2.8.0 # Apache-2.0 PyYAML>=3.12 # MIT python-dateutil>=2.5.3 # BSD six>=1.10.0 # MIT -tosca-parser>=1.0.0 # Apache-2.0 +tosca-parser>=1.4.0 # Apache-2.0 keystoneauth1>=3.4.0 # Apache-2.0 python-novaclient>=9.1.0 # Apache-2.0 python-heatclient>=1.10.0 # Apache-2.0 diff --git a/translator/hot/syntax/hot_resource.py b/translator/hot/syntax/hot_resource.py index 6ddc9790..ee9634d8 100644 --- a/translator/hot/syntax/hot_resource.py +++ b/translator/hot/syntax/hot_resource.py @@ -30,7 +30,8 @@ SECTIONS = (TYPE, PROPERTIES, MEDADATA, DEPENDS_ON, UPDATE_POLICY, policy_type = ['tosca.policies.Placement', 'tosca.policies.Scaling', 'tosca.policies.Scaling.Cluster', - 'tosca.policies.Monitoring'] + 'tosca.policies.Monitoring', + 'tosca.policies.Reservation'] log = logging.getLogger('heat-translator') diff --git a/translator/hot/tosca/tosca_policies_reservation.py b/translator/hot/tosca/tosca_policies_reservation.py new file mode 100644 index 00000000..72960065 --- /dev/null +++ b/translator/hot/tosca/tosca_policies_reservation.py @@ -0,0 +1,64 @@ +# Copyright (C) 2018 NTT DATA +# All Rights Reserved. +# +# 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 translator.hot.syntax.hot_resource import HotResource + +# Name used to dynamically load appropriate map class. +TARGET_CLASS_NAME = 'ToscaReservation' + +log = logging.getLogger('heat-translator') + + +class ToscaReservation(HotResource): + '''Translate TOSCA node type tosca.policies.Reservation''' + + toscatype = 'tosca.policies.Reservation' + + def __init__(self, policy, csar_dir=None): + hot_type = "OS::Aodh::EventAlarm" + super(ToscaReservation, self).__init__(policy, + type=hot_type, + csar_dir=csar_dir) + self.policy = policy + self.filter = list() + + def handle_expansion(self): + extra_resources = list() + hot_type = 'OS::Aodh::EventAlarm' + for action_name in self.filter: + prop = self._get_event_type(action_name) + resrv_resources = HotResource(self.nodetemplate, + type=hot_type, + name=action_name, + properties=prop) + extra_resources.append(resrv_resources) + return extra_resources + + def handle_properties(self): + if self.policy.entity_tpl.get('reservation'): + reservation_prop = self.policy.entity_tpl["reservation"].items() + for action_name, action_dict in reservation_prop: + if action_name != 'properties': + self.filter.append(action_name) + self.name = self.filter[0] + + def _get_event_type(self, action): + if action == 'start_actions': + return {'event_type': 'lease.event.start_lease'} + if action == 'before_end_actions': + return {'event_type': 'lease.event.before_end_lease'} + if action == 'end_actions': + return {'event_type': 'lease.event.end_lease'} diff --git a/translator/hot/tosca/tosca_policies_scaling.py b/translator/hot/tosca/tosca_policies_scaling.py index 333754f7..b1430228 100644 --- a/translator/hot/tosca/tosca_policies_scaling.py +++ b/translator/hot/tosca/tosca_policies_scaling.py @@ -25,7 +25,8 @@ ALARM_STATISTIC = {'mean': 'mean', 'median': 'median', 'summary': 'sum', 'maximum': 'max', 'minimum': 'min', 'last': 'last', 'std': 'std', 'first': 'first', 'count': 'count'} SCALING_RESOURCES = ["OS::Heat::ScalingPolicy", "OS::Heat::AutoScalingGroup", - "OS::Aodh::GnocchiAggregationByResourcesAlarm"] + "OS::Aodh::GnocchiAggregationByResourcesAlarm", + "OS::Aodh::EventAlarm"] class ToscaAutoscaling(HotResource): diff --git a/translator/hot/translate_node_templates.py b/translator/hot/translate_node_templates.py index 1275deef..ba185482 100644 --- a/translator/hot/translate_node_templates.py +++ b/translator/hot/translate_node_templates.py @@ -276,6 +276,9 @@ class TranslateNodeTemplates(object): if policy.is_derived_from('tosca.policies.Placement'): TOSCA_TO_HOT_TYPE[policy_type.type] = \ TOSCA_TO_HOT_TYPE['tosca.policies.Placement'] + if policy.is_derived_from('tosca.policies.Reservation'): + TOSCA_TO_HOT_TYPE[policy_type.type] = \ + TOSCA_TO_HOT_TYPE['tosca.policies.Reservation'] if policy_type.type not in TOSCA_TO_HOT_TYPE: raise UnsupportedTypeError(type=_('%s') % policy_type.type) elif policy_type.type == 'tosca.policies.Scaling.Cluster': diff --git a/translator/tests/data/hot_output/reservation/SP_RSV_res.yaml b/translator/tests/data/hot_output/reservation/SP_RSV_res.yaml new file mode 100644 index 00000000..8394a8ef --- /dev/null +++ b/translator/tests/data/hot_output/reservation/SP_RSV_res.yaml @@ -0,0 +1,23 @@ +heat_template_version: 2013-05-23 + +description: Tacker Scaling template + +resources: + VDU1: + type: OS::Nova::Server + properties: + user_data_format: SOFTWARE_CONFIG + image: cirros-0.4.0-x86_64-disk + flavor: + get_param: flavor + networks: + - port: { get_resource: CP1 } + config_drive: false + 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/reservation/hot_reservation_scaling.yaml b/translator/tests/data/hot_output/reservation/hot_reservation_scaling.yaml new file mode 100644 index 00000000..baa7b6b4 --- /dev/null +++ b/translator/tests/data/hot_output/reservation/hot_reservation_scaling.yaml @@ -0,0 +1,44 @@ +heat_template_version: 2013-05-23 + +description: > + VNF TOSCA template with reservation_id input parameters. + +parameters: + flavor: {type: string, description: Flavor Information} + lease_id: {type: string, description: lease id} +resources: + start_actions: + type: OS::Aodh::EventAlarm + properties: + event_type: lease.event.start_lease + SP_RSV_scale_out: + type: OS::Heat::ScalingPolicy + properties: + auto_scaling_group_id: {get_resource: SP_RSV_group} + adjustment_type: change_in_capacity + scaling_adjustment: 2 + cooldown: 120 + SP_RSV_group: + type: OS::Heat::AutoScalingGroup + properties: + min_size: 0 + desired_capacity: 0 + cooldown: 120 + resource: {type: SP_RSV_res.yaml} + max_size: 3 + SP_RSV_scale_in: + type: OS::Heat::ScalingPolicy + properties: + auto_scaling_group_id: {get_resource: SP_RSV_group} + adjustment_type: change_in_capacity + scaling_adjustment: -2 + cooldown: 120 + before_end_actions: + type: OS::Aodh::EventAlarm + properties: + event_type: lease.event.before_end_lease + end_actions: + type: OS::Aodh::EventAlarm + properties: + event_type: lease.event.end_lease +outputs: {} \ No newline at end of file diff --git a/translator/tests/data/nfv/tacker_defs.yaml b/translator/tests/data/nfv/tacker_defs.yaml index 60c04302..bd6d3b89 100644 --- a/translator/tests/data/nfv/tacker_defs.yaml +++ b/translator/tests/data/nfv/tacker_defs.yaml @@ -198,3 +198,26 @@ policy_types: required: false default: 120 description: Wait time (in seconds) between consecutive scaling operations. During the cooldown period... + + tosca.policies.tacker.Reservation: + derived_from: tosca.policies.Reservation + reservation: + start_actions: + type: list + entry_schema: + type: string + required: True + before_end_actions: + type: list + entry_schema: + type: string + required: True + end_actions: + type: list + entry_schema: + type: string + required: True + properties: + lease_id: + type: string + required: True diff --git a/translator/tests/data/reservation/tosca-vnfd-reservation-id.yaml b/translator/tests/data/reservation/tosca-vnfd-reservation-id.yaml new file mode 100644 index 00000000..97d2ddf4 --- /dev/null +++ b/translator/tests/data/reservation/tosca-vnfd-reservation-id.yaml @@ -0,0 +1,60 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 + +description: VNF TOSCA template with reservation_id input parameters. + +imports: + - translator/tests/data/nfv/tacker_defs.yaml + - translator/tests/data/nfv/tacker_nfv_defs.yaml + +topology_template: + inputs: + flavor: + type: string + description: Flavor Information + + lease_id: + type: string + description: lease id + + node_templates: + VDU1: + type: tosca.nodes.nfv.VDU.Tacker + properties: + image: cirros-0.4.0-x86_64-disk + flavor: { get_input: flavor } + + CP1: + type: tosca.nodes.nfv.CP.Tacker + properties: + management: true + order: 0 + 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: + - RSV: + type: tosca.policies.tacker.Reservation + reservation: + start_actions: [SP_RSV] + before_end_actions: [SP_RSV] + end_actions: [noop] + properties: + lease_id: { get_input: lease_id } + - SP_RSV: + type: tosca.policies.tacker.Scaling + properties: + increment: 2 + cooldown: 120 + min_instances: 0 + max_instances: 3 + default_instances: 0 + targets: [VDU1] diff --git a/translator/tests/test_tosca_hot_translation.py b/translator/tests/test_tosca_hot_translation.py index b03d73f4..d0aee31d 100644 --- a/translator/tests/test_tosca_hot_translation.py +++ b/translator/tests/test_tosca_hot_translation.py @@ -601,3 +601,12 @@ class ToscaHotTranslationTest(TestCase): ] params = {} self._test_successful_translation(tosca_file, hot_files, params) + + def test_hot_translate_reservation_policy(self): + tosca_file = '../tests/data/reservation/tosca-vnfd-reservation-id.yaml' + hot_files = [ + '../tests/data/hot_output/reservation/' + 'hot_reservation_scaling.yaml', + '../tests/data/hot_output/reservation/SP_RSV_res.yaml', + ] + self._test_successful_translation(tosca_file, hot_files, params={})