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
(cherry picked from commit 801896e976)
This commit is contained in:
Sripriya 2016-04-15 00:15:18 -07:00 committed by Sripriya Seetharam
parent a5c2f876a4
commit bea76d90a9
17 changed files with 165 additions and 14 deletions

View File

@ -24,6 +24,7 @@ topology_template:
type: tosca.nodes.nfv.CP.Tacker
properties:
management: true
anti_spoofing_protection: false
requirements:
- virtualLink:
node: VL1

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -18,6 +18,7 @@ resources:
type: OS::Neutron::Port
properties:
network: existing_network_1
port_security_enabled: false
outputs:
mgmt_ip-VDU1:
value:

View File

@ -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]

View File

@ -29,6 +29,7 @@ topology_template:
type: tosca.nodes.nfv.CP.Tacker
properties:
management: true
anti_spoofing_protection: false
requirements:
- virtualLink:
node: VL1

View File

@ -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)

View File

@ -55,6 +55,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
"""
@ -173,15 +183,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
@ -229,6 +238,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)
@ -253,6 +274,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:
@ -286,7 +309,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
@ -314,9 +338,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[
@ -552,3 +576,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']

View File

@ -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)