From 801896e976a8432baea69ac1e3def08a135ca09c Mon Sep 17 00:00:00 2001 From: Sripriya Date: Fri, 15 Apr 2016 00:15:18 -0700 Subject: [PATCH] Support port_security_enabled for Heat Kilo ver This fix supports port_security_enabled attr for Heat Kilo version. Also adds the new attr to tosca templates. Change-Id: I6c1e93e00dce0a6a7aa6d2a1f09970d3564524be Closes-Bug: #1566003 Closes-Bug: #1547284 --- .../samples/sample-tosca-vnfd-flavor.yaml | 1 + .../sample-tosca-vnfd-http-monitor.yaml | 5 ++ devstack/samples/sample-tosca-vnfd-image.yaml | 5 ++ .../samples/sample-tosca-vnfd-monitor.yaml | 5 ++ .../samples/sample-tosca-vnfd-multi-vdu.yaml | 5 ++ devstack/samples/sample-tosca-vnfd.yaml | 5 ++ devstack/samples/tosca_openwrt.yaml | 5 ++ .../sample-tosca-vnfd-http-monitor.yaml | 5 ++ .../samples/sample-tosca-vnfd-monitor.yaml | 5 ++ .../samples/sample-tosca-vnfd-multi-vdu.yaml | 15 ++++++ .../tests/etc/samples/sample-tosca-vnfd.yaml | 7 ++- .../heat/data/hot_tosca_openwrt.yaml | 1 + .../heat/data/hot_tosca_openwrt_kilo.yaml | 25 ++++++++++ .../heat/data/test_tosca_openwrt.yaml | 1 + tacker/tests/unit/vm/test_toscautils.py | 12 ++++- tacker/vm/infra_drivers/heat/heat.py | 50 +++++++++++++++---- tacker/vm/tosca/utils.py | 27 +++++++++- 17 files changed, 165 insertions(+), 14 deletions(-) create mode 100644 tacker/tests/unit/vm/infra_drivers/heat/data/hot_tosca_openwrt_kilo.yaml diff --git a/devstack/samples/sample-tosca-vnfd-flavor.yaml b/devstack/samples/sample-tosca-vnfd-flavor.yaml index 6f1e07d1c..bd0a84cc3 100644 --- a/devstack/samples/sample-tosca-vnfd-flavor.yaml +++ b/devstack/samples/sample-tosca-vnfd-flavor.yaml @@ -24,6 +24,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 diff --git a/devstack/samples/sample-tosca-vnfd-http-monitor.yaml b/devstack/samples/sample-tosca-vnfd-http-monitor.yaml index 7618e594f..0a622ce23 100644 --- a/devstack/samples/sample-tosca-vnfd-http-monitor.yaml +++ b/devstack/samples/sample-tosca-vnfd-http-monitor.yaml @@ -30,6 +30,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 @@ -38,6 +39,8 @@ topology_template: CP2: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL2 @@ -46,6 +49,8 @@ topology_template: CP3: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL3 diff --git a/devstack/samples/sample-tosca-vnfd-image.yaml b/devstack/samples/sample-tosca-vnfd-image.yaml index 31edd7067..202701a1e 100644 --- a/devstack/samples/sample-tosca-vnfd-image.yaml +++ b/devstack/samples/sample-tosca-vnfd-image.yaml @@ -25,6 +25,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 @@ -33,6 +34,8 @@ topology_template: CP2: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL2 @@ -41,6 +44,8 @@ topology_template: CP3: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL3 diff --git a/devstack/samples/sample-tosca-vnfd-monitor.yaml b/devstack/samples/sample-tosca-vnfd-monitor.yaml index 4cf814a5a..9815d1194 100644 --- a/devstack/samples/sample-tosca-vnfd-monitor.yaml +++ b/devstack/samples/sample-tosca-vnfd-monitor.yaml @@ -31,6 +31,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 @@ -39,6 +40,8 @@ topology_template: CP2: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL2 @@ -47,6 +50,8 @@ topology_template: CP3: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL3 diff --git a/devstack/samples/sample-tosca-vnfd-multi-vdu.yaml b/devstack/samples/sample-tosca-vnfd-multi-vdu.yaml index e5b6f4c0a..6e86730f1 100644 --- a/devstack/samples/sample-tosca-vnfd-multi-vdu.yaml +++ b/devstack/samples/sample-tosca-vnfd-multi-vdu.yaml @@ -22,6 +22,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 @@ -30,6 +31,8 @@ topology_template: CP12: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL2 @@ -38,6 +41,8 @@ topology_template: CP13: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL3 diff --git a/devstack/samples/sample-tosca-vnfd.yaml b/devstack/samples/sample-tosca-vnfd.yaml index f4eb17489..18be4c5a4 100644 --- a/devstack/samples/sample-tosca-vnfd.yaml +++ b/devstack/samples/sample-tosca-vnfd.yaml @@ -22,6 +22,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 @@ -30,6 +31,8 @@ topology_template: CP2: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL2 @@ -38,6 +41,8 @@ topology_template: CP3: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL3 diff --git a/devstack/samples/tosca_openwrt.yaml b/devstack/samples/tosca_openwrt.yaml index 3932b8bda..9ff275fbc 100644 --- a/devstack/samples/tosca_openwrt.yaml +++ b/devstack/samples/tosca_openwrt.yaml @@ -29,6 +29,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 @@ -37,6 +38,8 @@ topology_template: CP2: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL2 @@ -45,6 +48,8 @@ topology_template: CP3: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL3 diff --git a/tacker/tests/etc/samples/sample-tosca-vnfd-http-monitor.yaml b/tacker/tests/etc/samples/sample-tosca-vnfd-http-monitor.yaml index 7296c871a..b0a80d26a 100644 --- a/tacker/tests/etc/samples/sample-tosca-vnfd-http-monitor.yaml +++ b/tacker/tests/etc/samples/sample-tosca-vnfd-http-monitor.yaml @@ -31,6 +31,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 @@ -39,6 +40,8 @@ topology_template: CP2: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL2 @@ -47,6 +50,8 @@ topology_template: CP3: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL3 diff --git a/tacker/tests/etc/samples/sample-tosca-vnfd-monitor.yaml b/tacker/tests/etc/samples/sample-tosca-vnfd-monitor.yaml index 509299a70..e8585231a 100644 --- a/tacker/tests/etc/samples/sample-tosca-vnfd-monitor.yaml +++ b/tacker/tests/etc/samples/sample-tosca-vnfd-monitor.yaml @@ -32,6 +32,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 @@ -40,6 +41,8 @@ topology_template: CP2: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL2 @@ -48,6 +51,8 @@ topology_template: CP3: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL3 diff --git a/tacker/tests/etc/samples/sample-tosca-vnfd-multi-vdu.yaml b/tacker/tests/etc/samples/sample-tosca-vnfd-multi-vdu.yaml index e5b6f4c0a..3d42ffa08 100644 --- a/tacker/tests/etc/samples/sample-tosca-vnfd-multi-vdu.yaml +++ b/tacker/tests/etc/samples/sample-tosca-vnfd-multi-vdu.yaml @@ -22,6 +22,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 @@ -30,6 +31,8 @@ topology_template: CP12: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL2 @@ -38,6 +41,8 @@ topology_template: CP13: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL3 @@ -59,6 +64,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 @@ -67,6 +73,8 @@ topology_template: CP22: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL2 @@ -75,6 +83,8 @@ topology_template: CP23: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL3 @@ -96,6 +106,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 @@ -104,6 +115,8 @@ topology_template: CP32: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL2 @@ -112,6 +125,8 @@ topology_template: CP33: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL3 diff --git a/tacker/tests/etc/samples/sample-tosca-vnfd.yaml b/tacker/tests/etc/samples/sample-tosca-vnfd.yaml index fa09fb3f4..18be4c5a4 100644 --- a/tacker/tests/etc/samples/sample-tosca-vnfd.yaml +++ b/tacker/tests/etc/samples/sample-tosca-vnfd.yaml @@ -13,7 +13,7 @@ topology_template: image: cirros-0.3.4-x86_64-uec flavor: m1.tiny availability_zone: nova - mgmt_driver: noop + mgmt_driver: noop config: | param0: key1 param1: key2 @@ -22,6 +22,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 @@ -30,6 +31,8 @@ topology_template: CP2: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL2 @@ -38,6 +41,8 @@ topology_template: CP3: type: tosca.nodes.nfv.CP.Tacker + properties: + anti_spoofing_protection: false requirements: - virtualLink: node: VL3 diff --git a/tacker/tests/unit/vm/infra_drivers/heat/data/hot_tosca_openwrt.yaml b/tacker/tests/unit/vm/infra_drivers/heat/data/hot_tosca_openwrt.yaml index 27e751a9c..75dbdb037 100644 --- a/tacker/tests/unit/vm/infra_drivers/heat/data/hot_tosca_openwrt.yaml +++ b/tacker/tests/unit/vm/infra_drivers/heat/data/hot_tosca_openwrt.yaml @@ -18,6 +18,7 @@ resources: type: OS::Neutron::Port properties: network: existing_network_1 + port_security_enabled: false outputs: mgmt_ip-VDU1: value: diff --git a/tacker/tests/unit/vm/infra_drivers/heat/data/hot_tosca_openwrt_kilo.yaml b/tacker/tests/unit/vm/infra_drivers/heat/data/hot_tosca_openwrt_kilo.yaml new file mode 100644 index 000000000..7d42cfa12 --- /dev/null +++ b/tacker/tests/unit/vm/infra_drivers/heat/data/hot_tosca_openwrt_kilo.yaml @@ -0,0 +1,25 @@ +heat_template_version: 2013-05-23 +description: 'OpenWRT with services + + ' +parameters: {} +resources: + VDU1: + type: OS::Nova::Server + properties: + config_drive: false + flavor: m1.tiny + image: OpenWRT + networks: + - port: + get_resource: CP1 + user_data_format: SOFTWARE_CONFIG + CP1: + type: OS::Neutron::Port + properties: + network: existing_network_1 + value_specs: {port_security_enabled: false} +outputs: + mgmt_ip-VDU1: + value: + get_attr: [CP1, fixed_ips, 0, ip_address] diff --git a/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_openwrt.yaml b/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_openwrt.yaml index eb1568661..70ec23e86 100644 --- a/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_openwrt.yaml +++ b/tacker/tests/unit/vm/infra_drivers/heat/data/test_tosca_openwrt.yaml @@ -29,6 +29,7 @@ topology_template: type: tosca.nodes.nfv.CP.Tacker properties: management: true + anti_spoofing_protection: false requirements: - virtualLink: node: VL1 diff --git a/tacker/tests/unit/vm/test_toscautils.py b/tacker/tests/unit/vm/test_toscautils.py index 3c4c60f29..5ba346d31 100644 --- a/tacker/tests/unit/vm/test_toscautils.py +++ b/tacker/tests/unit/vm/test_toscautils.py @@ -107,7 +107,7 @@ class TestToscaUtils(testtools.TestCase): expected_heat_tpl = _get_template('hot_tosca_openwrt.yaml') mgmt_ports = toscautils.get_mgmt_ports(self.tosca) heat_tpl = toscautils.post_process_heat_template( - heat_template_yaml, mgmt_ports, {}) + heat_template_yaml, mgmt_ports, {}, {}) heatdict = yaml.load(heat_tpl) expecteddict = yaml.load(expected_heat_tpl) @@ -214,3 +214,13 @@ class TestToscaUtils(testtools.TestCase): } toscautils.add_resources_tpl(dummy_heat_dict, dummy_heat_res) self.assertEqual(dummy_heat_dict, expected_dict) + + def test_convert_unsupported_res_prop_kilo_ver(self): + unsupported_res_prop_dict = {'OS::Neutron::Port': { + 'port_security_enabled': 'value_specs', }, } + dummy_heat_dict = yaml.load(_get_template('hot_tosca_openwrt.yaml')) + expected_heat_dict = yaml.load(_get_template( + 'hot_tosca_openwrt_kilo.yaml')) + toscautils.convert_unsupported_res_prop(dummy_heat_dict, + unsupported_res_prop_dict) + self.assertEqual(dummy_heat_dict, expected_heat_dict) diff --git a/tacker/vm/infra_drivers/heat/heat.py b/tacker/vm/infra_drivers/heat/heat.py index bad57e7c6..5205b2dc9 100644 --- a/tacker/vm/infra_drivers/heat/heat.py +++ b/tacker/vm/infra_drivers/heat/heat.py @@ -53,6 +53,16 @@ STACK_RETRIES = cfg.CONF.tacker_heat.stack_retries STACK_RETRY_WAIT = cfg.CONF.tacker_heat.stack_retry_wait STACK_FLAVOR_EXTRA = cfg.CONF.tacker_heat.flavor_extra_specs +# Global map of individual resource type and +# incompatible properties, alternate properties pair for +# upgrade/downgrade across all Heat template versions (starting Kilo) +# +# Maintains a dictionary of {"resource type": {dict of "incompatible +# property": "alternate_prop"}} + +HEAT_VERSION_INCOMPATIBILITY_MAP = {'OS::Neutron::Port': { + 'port_security_enabled': 'value_specs', }, } + HEAT_TEMPLATE_BASE = """ heat_template_version: 2013-05-23 """ @@ -171,15 +181,14 @@ class DeviceHeat(abstract_driver.DeviceAbstractDriver): @log.log def _process_vdu_network_interfaces(self, vdu_id, vdu_dict, properties, - template_dict): + template_dict, + unsupported_res_prop=None): def make_port_dict(): - port_dict = { - 'type': 'OS::Neutron::Port', - 'properties': { - 'port_security_enabled': False - } - } + port_dict = {'type': 'OS::Neutron::Port'} + port_dict['properties'] = {'value_specs': { + 'port_security_enabled': False}} if unsupported_res_prop \ + else {'port_security_enabled': False} port_dict['properties'].setdefault('fixed_ips', []) return port_dict @@ -227,6 +236,18 @@ class DeviceHeat(abstract_driver.DeviceAbstractDriver): } networks_list.append(dict(network_param)) + def fetch_unsupported_resource_prop(self, heat_client): + unsupported_resource_prop = {} + + for res, prop_dict in HEAT_VERSION_INCOMPATIBILITY_MAP.iteritems(): + unsupported_prop = {} + for prop, val in prop_dict.iteritems(): + if not heat_client.resource_attr_support(res, prop): + unsupported_prop.update(prop_dict) + if unsupported_prop: + unsupported_resource_prop[res] = unsupported_prop + return unsupported_resource_prop + @log.log def create(self, plugin, context, device, auth_attr): LOG.debug(_('device %s'), device) @@ -251,6 +272,8 @@ class DeviceHeat(abstract_driver.DeviceAbstractDriver): region_name = device.get('placement_attr', {}).get('region_name', None) heatclient_ = HeatClient(auth_attr, region_name) + unsupported_res_prop = self.fetch_unsupported_resource_prop( + heatclient_) LOG.debug('vnfd_yaml %s', vnfd_yaml) if vnfd_yaml is not None: @@ -284,7 +307,8 @@ class DeviceHeat(abstract_driver.DeviceAbstractDriver): LOG.debug("heat-translator error: %s", str(e)) raise vnfm.HeatTranslatorFailed(error_msg_details=str(e)) heat_template_yaml = toscautils.post_process_heat_template( - heat_template_yaml, mgmt_ports, res_tpl) + heat_template_yaml, mgmt_ports, res_tpl, + unsupported_res_prop) else: assert 'template' not in fields assert 'template_url' not in fields @@ -312,9 +336,9 @@ class DeviceHeat(abstract_driver.DeviceAbstractDriver): for (key, vdu_key) in KEY_LIST: properties[key] = vdu_dict[vdu_key] if 'network_interfaces' in vdu_dict: - self._process_vdu_network_interfaces(vdu_id, vdu_dict, - properties, - template_dict) + self._process_vdu_network_interfaces(vdu_id, + vdu_dict, properties, template_dict, + unsupported_res_prop) if ('user_data' in vdu_dict and 'user_data_format' in vdu_dict): properties['user_data_format'] = vdu_dict[ @@ -542,3 +566,7 @@ class HeatClient(object): def get(self, stack_id): return self.stacks.get(stack_id) + + def resource_attr_support(self, resource_name, property_name): + resource = self.resource_types.get(resource_name) + return property_name in resource['attributes'] diff --git a/tacker/vm/tosca/utils.py b/tacker/vm/tosca/utils.py index 8d256866a..8a1ee1513 100644 --- a/tacker/vm/tosca/utils.py +++ b/tacker/vm/tosca/utils.py @@ -143,7 +143,30 @@ def add_resources_tpl(heat_dict, hot_res_tpl): @log.log -def post_process_heat_template(heat_tpl, mgmt_ports, res_tpl): +def convert_unsupported_res_prop(heat_dict, unsupported_res_prop): + res_dict = heat_dict['resources'] + + for res, attr in res_dict.iteritems(): + res_type = attr['type'] + if res_type in unsupported_res_prop: + prop_dict = attr['properties'] + unsupported_prop_dict = unsupported_res_prop[res_type] + unsupported_prop = set(prop_dict.keys()) & set( + unsupported_prop_dict.keys()) + for prop in unsupported_prop: + # some properties are just punted to 'value_specs' + # property if they are incompatible + new_prop = unsupported_prop_dict[prop] + if new_prop == 'value_specs': + prop_dict.setdefault(new_prop, {})[ + prop] = prop_dict.pop(prop) + else: + prop_dict[new_prop] = prop_dict.pop(prop) + + +@log.log +def post_process_heat_template(heat_tpl, mgmt_ports, res_tpl, + unsupported_res_prop=None): heat_dict = yamlparser.simple_ordered_parse(heat_tpl) for outputname, portname in mgmt_ports.items(): ipval = {'get_attr': [portname, 'fixed_ips', 0, 'ip_address']} @@ -154,6 +177,8 @@ def post_process_heat_template(heat_tpl, mgmt_ports, res_tpl): heat_dict['outputs'] = output LOG.debug(_('Added output for %s') % outputname) add_resources_tpl(heat_dict, res_tpl) + if unsupported_res_prop: + convert_unsupported_res_prop(heat_dict, unsupported_res_prop) return yaml.dump(heat_dict)