[WIP] Initial patchset for tosca-parser integration

Change-Id: Idf902cd01bd369cfede83842e1ae295bff3da710
Paritally-implements: bp/tosca-parser-integration
This commit is contained in:
Bob.Haddleton 2016-02-03 20:14:09 -06:00
parent 302630d471
commit 87f710b51d
13 changed files with 695 additions and 138 deletions

View File

@ -0,0 +1,55 @@
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
description: Template for deploying a single server with predefined properties.
metadata:
template_name: OpenWRT
imports:
- tacker_defs.yaml
topology_template:
node_templates:
VDU1:
type: tosca.nodes.nfv.VDU.Tacker
properties:
image: OpenWRT
flavor: m1.tiny
config: |
param0: key1
param1: key2
mgmt_driver: openwrt
monitoring_policy:
name: ping
actions:
- {trigger: failure, action: respawn}
parameters:
count: "3"
interval: "10"
CP1:
type: tosca.nodes.nfv.CP.Tacker
properties:
management: true
requirements:
- virtualLink:
node: VL1
- virtualBinding:
node: VDU1
VL1:
type: tosca.nodes.nfv.VL
properties:
network_name: existing_network_1
vendor: ACME
# policies:
# - PING:
# type: tosca.policies.tacker.Monitoring.Ping
# monitoring_params: {count: 3, interval: 5}
# targets: [ VDU1 ]
#
# - RESPAWN:
# type: tosca.policies.failure.Respawn
# targets: [ VDU1 ]

View File

@ -29,3 +29,4 @@ oslo.rootwrap>=2.0.0 # Apache-2.0
oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0
python-novaclient!=2.33.0,>=2.29.0 # Apache-2.0
tosca-parser>=0.4.0 # Apache-2.0
heat-translator>=0.3.0 # Apache-2.0

View File

@ -0,0 +1,26 @@
description: OpenWRT with services
heat_template_version: 2013-05-23
outputs:
mgmt_ip-vdu1:
description: management ip address
value:
get_attr: [vdu1-net_mgmt-port, fixed_ips, 0, ip_address]
resources:
vdu1:
properties:
availability_zone: nova
config_drive: true
flavor: m1.tiny
image: cirros-0.3.2-x86_64-uec
metadata: {param0: key0, param1: key1}
networks:
- port: {get_resource: vdu1-net_mgmt-port}
- {network: net0}
- {network: net1}
type: OS::Nova::Server
vdu1-net_mgmt-port:
properties:
fixed_ips: []
network: net_mgmt
port_security_enabled: false
type: OS::Neutron::Port

View File

@ -0,0 +1,41 @@
description: Parameterized VNF descriptor for IP addresses
heat_template_version: 2013-05-23
outputs:
mgmt_ip-vdu1:
description: management ip address
value:
get_attr: [vdu1-net_mgmt-port, fixed_ips, 0, ip_address]
resources:
vdu1:
properties:
availability_zone: nova
config_drive: true
flavor: m1.tiny
image: cirros-0.3.4-x86_64-uec
metadata: {param0: key0, param1: key1}
networks:
- port: {get_resource: vdu1-net_mgmt-port}
- port: {get_resource: vdu1-net0-port}
- port: {get_resource: vdu1-net1-port}
type: OS::Nova::Server
vdu1-net0-port:
properties:
fixed_ips:
- {ip_address: 10.10.0.98}
network: net0
port_security_enabled: false
type: OS::Neutron::Port
vdu1-net1-port:
properties:
fixed_ips:
- {ip_address: 10.10.1.98}
network: net1
port_security_enabled: false
type: OS::Neutron::Port
vdu1-net_mgmt-port:
properties:
fixed_ips:
- {ip_address: 192.168.120.98}
network: net_mgmt
port_security_enabled: false
type: OS::Neutron::Port

View File

@ -0,0 +1,34 @@
description: Parameterized VNF descriptor
heat_template_version: 2013-05-23
outputs:
mgmt_ip-vdu1:
description: management ip address
value:
get_attr: [vdu1-net_mgmt-port, fixed_ips, 0, ip_address]
resources:
vdu1:
properties:
availability_zone: nova
config_drive: true
flavor: m1.tiny
image: cirros-0.3.4-x86_64-uec
metadata: {param0: key0, param1: key1}
networks:
- port: {get_resource: vdu1-net_mgmt-port}
- {network: net0}
- {network: net1}
user_data: '#!/bin/sh
echo "my hostname is `hostname`" > /tmp/hostname
df -h > /home/cirros/diskinfo
'
user_data_format: RAW
type: OS::Nova::Server
vdu1-net_mgmt-port:
properties:
fixed_ips: []
network: net_mgmt
port_security_enabled: false
type: OS::Neutron::Port

View File

@ -0,0 +1,20 @@
heat_template_version: 2013-05-23
description: >
Template for deploying a single server with predefined properties.
parameters: {}
resources:
VDU1:
type: OS::Nova::Server
properties:
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
outputs: {}

View File

@ -0,0 +1,35 @@
template_name: OpenWRT
description: OpenWRT with services
vdus:
vdu1:
id: vdu1
vm_image: cirros-0.3.2-x86_64-uec
instance_type: m1.tiny
service_type: firewall
mgmt_driver: openwrt
network_interfaces:
management:
network: net_mgmt
management: True
pkt_in:
network: net0
pkt_out:
network: net1
placement_policy:
availability_zone: nova
auto-scaling: noop
monitoring_policy: noop
failure_policy: noop
monitoring_parameter:
a:
config:
param0: key0
param1: key1

View File

@ -0,0 +1,55 @@
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
description: Template for deploying a single server with predefined properties.
metadata:
template_name: OpenWRT
imports:
- tacker_defs.yaml
topology_template:
node_templates:
VDU1:
type: tosca.nodes.nfv.VDU.Tacker
properties:
image: OpenWRT
flavor: m1.tiny
config: |
param0: key1
param1: key2
mgmt_driver: openwrt
monitoring_policy:
name: ping
actions:
- {trigger: failure, action: respawn}
parameters:
count: "3"
interval: "10"
CP1:
type: tosca.nodes.nfv.CP.Tacker
properties:
management: true
requirements:
- virtualLink:
node: VL1
- virtualBinding:
node: VDU1
VL1:
type: tosca.nodes.nfv.VL
properties:
network_name: existing_network_1
vendor: ACME
# policies:
# - PING:
# type: tosca.policies.tacker.Monitoring.Ping
# monitoring_params: {count: 3, interval: 5}
# targets: [ VDU1 ]
#
# - RESPAWN:
# type: tosca.policies.failure.Respawn
# targets: [ VDU1 ]

View File

@ -13,7 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
import codecs
import mock
import os
import testtools
from tacker import context
@ -35,7 +37,21 @@ class FakeHeatClient(mock.Mock):
return self.Stack()
def _get_template(name):
filename = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "data/", name)
f = codecs.open(filename, encoding='utf-8', errors='strict')
return f.read()
class TestDeviceHeat(testtools.TestCase):
hot_template = _get_template('hot_openwrt.yaml')
hot_param_template = _get_template('hot_openwrt_params.yaml')
hot_ipparam_template = _get_template('hot_openwrt_ipparams.yaml')
vnfd_openwrt = _get_template('openwrt.yaml')
tosca_hw = _get_template('tosca_hw.yaml')
hot_tosca_hw = _get_template('hot_tosca_hw.yaml')
def setUp(self):
super(TestDeviceHeat, self).setUp()
self.context = context.get_admin_context()
@ -54,65 +70,37 @@ class TestDeviceHeat(testtools.TestCase):
patcher = mock.patch(target, new)
return patcher.start()
def _get_device_template(self, template):
return {'device_template': {'attributes': {'vnfd': template}}}
def _get_expected_device_template(self, template):
return {'device_template': {'attributes': {'vnfd': template},
'description': 'OpenWRT with services',
'mgmt_driver': 'openwrt',
'name': 'OpenWRT'}}
def _get_expected_tosca_device_template(self, template):
return {'device_template': {'attributes': {'vnfd': template},
'description': 'Template for deploying'
' a single server with predefined '
'properties.',
'mgmt_driver': 'openwrt',
'name': 'OpenWRT'}}
def _get_expected_fields(self):
return {'stack_name': 'tacker.vm.drivers.heat.heat_DeviceHeat-eb84260e'
'-5ff7-4332-b032-50a14d6c1123', 'template':
'description: OpenWRT with services\nheat_template_version: '
'2013-05-23\noutputs:\n mgmt_ip-vdu1:\n description: '
'management ip address\n value:\n get_attr: [vdu1-net_mgmt'
'-port, fixed_ips, 0, ip_address]\nresources:\n vdu1:\n '
'properties:\n availability_zone: nova\n config_drive: '
'true\n flavor: m1.tiny\n image: cirros-0.3.2-x86_64-uec'
'\n metadata: {param0: key0, param1: key1}\n networks:\n'
' - port: {get_resource: vdu1-net_mgmt-port}\n - '
'{network: net0}\n - {network: net1}\n type: OS::Nova::'
'Server\n vdu1-net_mgmt-port:\n properties:\n fixed_ips: '
'[]\n network: net_mgmt\n port_security_enabled: false\n'
' type: OS::Neutron::Port\n'}
'-5ff7-4332-b032-50a14d6c1123',
'template': self.hot_template}
def _get_expected_fields_user_data(self):
return {'stack_name': 'tacker.vm.drivers.heat.heat_DeviceHeat-18685f68'
'-2b2a-4185-8566-74f54e548811', 'template':
'description: Parameterized VNF descriptor\nheat_template_version:'
' 2013-05-23\noutputs:\n mgmt_ip-vdu1:\n description: '
'management ip address\n value:\n get_attr: '
'[vdu1-net_mgmt-port, fixed_ips, 0, ip_address]\nresources:\n '
'vdu1:\n properties:\n availability_zone: nova\n '
'config_drive: true\n flavor: m1.tiny\n image: '
'cirros-0.3.4-x86_64-uec\n metadata: {param0: key0, param1: '
'key1}\n networks:\n - port: {get_resource: '
'vdu1-net_mgmt-port}\n - {network: net0}\n - '
'{network: net1}\n user_data: \'#!/bin/sh\n\n '
'echo "my hostname is `hostname`" > /tmp/hostname\n\n '
'df -h > /home/cirros/diskinfo\n\n \'\n '
'user_data_format: RAW\n type: OS::Nova::Server\n '
'vdu1-net_mgmt-port:\n properties:\n fixed_ips: []\n '
'network: net_mgmt\n port_security_enabled: false\n '
'type: OS::Neutron::Port\n'}
'-2b2a-4185-8566-74f54e548811',
'template': self.hot_param_template}
def _get_expected_fields_ipaddr_data(self):
return {'stack_name': 'tacker.vm.drivers.heat.heat_DeviceHeat-d1337add'
'-d5a1-4fd4-9447-bb9243c8460b', 'template':
'description: Parameterized VNF descriptor for IP addresses\n'
'heat_template_version: 2013-05-23\noutputs:\n mgmt_ip-vdu1:\n '
' description: management ip address\n value:\n '
'get_attr: [vdu1-net_mgmt-port, fixed_ips, 0, ip_address]\n'
'resources:\n vdu1:\n properties:\n availability_zone: '
'nova\n config_drive: true\n flavor: m1.tiny\n '
'image: cirros-0.3.4-x86_64-uec\n metadata: {param0: key0, '
'param1: key1}\n networks:\n - port: {get_resource: '
'vdu1-net_mgmt-port}\n - port: {get_resource: vdu1-net0-port}'
'\n - port: {get_resource: vdu1-net1-port}\n type: '
'OS::Nova::Server\n vdu1-net0-port:\n properties:\n '
'fixed_ips:\n - {ip_address: 10.10.0.98}\n network: net0'
'\n port_security_enabled: false\n type: '
'OS::Neutron::Port\n vdu1-net1-port:\n properties:\n '
'fixed_ips:\n - {ip_address: 10.10.1.98}\n network: net1'
'\n port_security_enabled: false\n type: '
'OS::Neutron::Port\n vdu1-net_mgmt-port:\n properties:\n '
'fixed_ips:\n - {ip_address: 192.168.120.98}\n network: '
'net_mgmt\n port_security_enabled: false\n '
'type: OS::Neutron::Port\n'}
'-d5a1-4fd4-9447-bb9243c8460b',
'template': self.hot_ipparam_template}
def _get_expected_device_wait_obj(self):
return {'status': 'PENDING_CREATE', 'instance_id': None, 'name':
@ -227,3 +215,47 @@ class TestDeviceHeat(testtools.TestCase):
device_id, device_obj,
device_config_obj)
self.assertEqual(device_obj, expected_device_update)
def test_create_device_template_pre_tosca(self):
dtemplate = self._get_device_template(self.tosca_hw)
exp_tmpl = self._get_expected_tosca_device_template(self.tosca_hw)
self.heat_driver.create_device_template_pre(None, None, dtemplate)
self.assertEqual(dtemplate, exp_tmpl)
def _get_expected_fields_tosca(self):
return {'stack_name': 'tacker.vm.drivers.heat.heat_DeviceHeat-eb84260e'
'-5ff7-4332-b032-50a14d6c1123',
'template': self.hot_tosca_hw}
def _get_expected_tosca_device(self):
exp_tmpl = self._get_expected_tosca_device_template(self.tosca_hw)
return {'device_template': exp_tmpl['device_template'],
'description': u'OpenWRT with services',
'attributes': {'heat_template': self.hot_tosca_hw,
'monitoring_policy': {}},
'id': 'eb84260e-5ff7-4332-b032-50a14d6c1123',
'instance_id': None, 'mgmt_url': None, 'name': u'test_openwrt',
'service_context': [], 'status': 'PENDING_CREATE',
'template_id': u'eb094833-995e-49f0-a047-dfb56aaf7c4e',
'tenant_id': u'ad7ebc56538745a08ef7c5e97f8bd437'}
def _get_dummy_tosca_device(self):
device = utils.get_dummy_device_obj()
dtemplate = self._get_expected_device_template(self.tosca_hw)
dtemplate['service_types'] = [{'service_type': 'vnfd', 'id':
'4a4c2d44-8a52-4895-9a75-9d1c76c3e738'}]
dtemplate['tenant_id'] = 'ad7ebc56538745a08ef7c5e97f8bd437'
device['device_template'] = dtemplate['device_template']
return device
def test_create_tosca(self):
self.skipTest("Not ready yet")
device = self._get_dummy_tosca_device()
expected_result = '4a4c2d44-8a52-4895-9a75-9d1c76c3e738'
expected_fields = self._get_expected_fields_tosca()
expected_device = self._get_expected_tosca_device()
result = self.heat_driver.create(plugin=None, context=self.context,
device=device)
self.heat_client.create.assert_called_once_with(expected_fields)
self.assertEqual(expected_result, result)
self.assertEqual(device, expected_device)

View File

@ -21,7 +21,9 @@ import time
from heatclient import exc as heatException
from oslo_config import cfg
from toscaparser.tosca_template import ToscaTemplate
from toscaparser.utils import yamlparser
from translator.hot.tosca_translator import TOSCATranslator
import yaml
from tacker.common import clients
@ -30,6 +32,7 @@ from tacker.extensions import vnfm
from tacker.openstack.common import jsonutils
from tacker.openstack.common import log as logging
from tacker.vm.drivers import abstract_driver
from tacker.vm.tosca import utils as toscautils
LOG = logging.getLogger(__name__)
@ -77,24 +80,45 @@ class DeviceHeat(abstract_driver.DeviceAbstractDriver):
return
vnfd_dict = yaml.load(vnfd_yaml)
KEY_LIST = (('name', 'template_name'), ('description', 'description'))
LOG.debug(_('vnfd_dict: %s'), vnfd_dict)
device_template_dict.update(
dict((key, vnfd_dict[vnfd_key]) for (key, vnfd_key) in KEY_LIST
if ((key not in device_template_dict or
device_template_dict[key] == '') and
vnfd_key in vnfd_dict and
vnfd_dict[vnfd_key] != '')))
if 'tosca_definitions_version' in vnfd_dict:
# Prepend the tacker_defs.yaml import file with the full
# path to the file
toscautils.updateimport(vnfd_dict)
service_types = vnfd_dict.get('service_properties', {}).get('type', [])
if service_types:
device_template_dict.setdefault('service_types', []).extend(
[{'service_type': service_type}
for service_type in service_types])
for vdu in vnfd_dict.get('vdus', {}).values():
mgmt_driver = vdu.get('mgmt_driver')
if mgmt_driver:
device_template_dict['mgmt_driver'] = mgmt_driver
tosca = ToscaTemplate(a_file=False, yaml_dict_tpl=vnfd_dict)
device_template_dict['description'] = vnfd_dict.get('description',
'')
if 'name' not in device_template_dict and 'metadata' in vnfd_dict:
device_template_dict['name'] = vnfd_dict['metadata'].get(
'template_name', '')
device_template_dict['mgmt_driver'] = toscautils.get_mgmt_driver(
tosca)
else:
KEY_LIST = (('name', 'template_name'),
('description', 'description'))
device_template_dict.update(
dict((key, vnfd_dict[vnfd_key]) for (key, vnfd_key) in KEY_LIST
if ((key not in device_template_dict or
device_template_dict[key] == '') and
vnfd_key in vnfd_dict and
vnfd_dict[vnfd_key] != '')))
service_types = vnfd_dict.get('service_properties', {}).get('type',
[])
if service_types:
device_template_dict.setdefault('service_types', []).extend(
[{'service_type': service_type}
for service_type in service_types])
# TODO(anyone) - this code assumes one mgmt_driver per VNFD???
for vdu in vnfd_dict.get('vdus', {}).values():
mgmt_driver = vdu.get('mgmt_driver')
if mgmt_driver:
device_template_dict['mgmt_driver'] = mgmt_driver
LOG.debug(_('device_template %s'), device_template)
@log.log
@ -196,7 +220,10 @@ class DeviceHeat(abstract_driver.DeviceAbstractDriver):
def create(self, plugin, context, device):
LOG.debug(_('device %s'), device)
heatclient_ = HeatClient(context)
attributes = device['device_template']['attributes'].copy()
try:
attributes = device['device_template']['attributes'].copy()
except Exception:
raise Exception(device)
vnfd_yaml = attributes.pop('vnfd', None)
fields = dict((key, attributes.pop(key)) for key
in ('stack_name', 'template_url', 'template')
@ -217,89 +244,110 @@ class DeviceHeat(abstract_driver.DeviceAbstractDriver):
LOG.debug('vnfd_yaml %s', vnfd_yaml)
if vnfd_yaml is not None:
assert 'template' not in fields
assert 'template_url' not in fields
template_dict = yaml.load(HEAT_TEMPLATE_BASE)
outputs_dict = {}
template_dict['outputs'] = outputs_dict
vnfd_dict = yamlparser.simple_ordered_parse(vnfd_yaml)
LOG.debug('vnfd_dict %s', vnfd_dict)
if 'get_input' in vnfd_yaml:
self._process_parameterized_input(dev_attrs, vnfd_dict)
KEY_LIST = (('description', 'description'),
)
for (key, vnfd_key) in KEY_LIST:
if vnfd_key in vnfd_dict:
template_dict[key] = vnfd_dict[vnfd_key]
monitoring_dict = {'vdus': {}}
for vdu_id, vdu_dict in vnfd_dict.get('vdus', {}).items():
template_dict.setdefault('resources', {})[vdu_id] = {
"type": "OS::Nova::Server"
}
resource_dict = template_dict['resources'][vdu_id]
KEY_LIST = (('image', 'vm_image'),
('flavor', 'instance_type'))
resource_dict['properties'] = {}
properties = resource_dict['properties']
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)
if 'user_data' in vdu_dict and 'user_data_format' in vdu_dict:
properties['user_data_format'] = vdu_dict[
'user_data_format']
properties['user_data'] = vdu_dict['user_data']
elif 'user_data' in vdu_dict or 'user_data_format' in vdu_dict:
raise vnfm.UserDataFormatNotFound()
if ('placement_policy' in vdu_dict and
'availability_zone' in vdu_dict['placement_policy']):
properties['availability_zone'] = vdu_dict[
'placement_policy']['availability_zone']
if 'config' in vdu_dict:
properties['config_drive'] = True
metadata = properties.setdefault('metadata', {})
metadata.update(vdu_dict['config'])
for key, value in metadata.items():
metadata[key] = value[:255]
if 'tosca_definitions_version' in vnfd_dict:
toscautils.updateimport(vnfd_dict)
parsed_params = dev_attrs.pop('param_values', None)
# Prepend the tacker_defs.yaml import file with the full
# path to the file
monitoring_policy = vdu_dict.get('monitoring_policy', 'noop')
failure_policy = vdu_dict.get('failure_policy', 'noop')
tosca = ToscaTemplate(parsed_params=parsed_params,
a_file=False, yaml_dict_tpl=vnfd_dict)
# Convert the old monitoring specification to the new format
# This should be removed after Mitaka
if monitoring_policy == 'ping' and failure_policy == 'respawn':
vdu_dict['monitoring_policy'] = {'ping': {
'actions': {
'failure': 'respawn'
}}}
vdu_dict.pop('failure_policy')
monitoring_dict = toscautils.get_vdu_monitoring(tosca)
toscautils.post_process_template(tosca)
raise NotImplementedError()
translator = TOSCATranslator(tosca, parsed_params)
heat_template_yaml = translator.translate()
else:
assert 'template' not in fields
assert 'template_url' not in fields
template_dict = yaml.load(HEAT_TEMPLATE_BASE)
outputs_dict = {}
template_dict['outputs'] = outputs_dict
if monitoring_policy != 'noop':
monitoring_dict['vdus'][vdu_id] = \
vdu_dict['monitoring_policy']
if 'get_input' in vnfd_yaml:
self._process_parameterized_input(dev_attrs, vnfd_dict)
# to pass necessary parameters to plugin upwards.
for key in ('service_type',):
if key in vdu_dict:
device.setdefault(
'attributes', {})[vdu_id] = jsonutils.dumps(
{key: vdu_dict[key]})
KEY_LIST = (('description', 'description'), )
for (key, vnfd_key) in KEY_LIST:
if vnfd_key in vnfd_dict:
template_dict[key] = vnfd_dict[vnfd_key]
if monitoring_dict.keys():
device['attributes']['monitoring_policy'] = jsonutils.dumps(
monitoring_dict)
for vdu_id, vdu_dict in vnfd_dict.get('vdus', {}).items():
template_dict.setdefault('resources', {})[vdu_id] = {
"type": "OS::Nova::Server"
}
resource_dict = template_dict['resources'][vdu_id]
KEY_LIST = (('image', 'vm_image'),
('flavor', 'instance_type'))
resource_dict['properties'] = {}
properties = resource_dict['properties']
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)
if ('user_data' in vdu_dict and
'user_data_format' in vdu_dict):
properties['user_data_format'] = vdu_dict[
'user_data_format']
properties['user_data'] = vdu_dict['user_data']
elif ('user_data' in vdu_dict or
'user_data_format' in vdu_dict):
raise vnfm.UserDataFormatNotFound()
if ('placement_policy' in vdu_dict and
'availability_zone' in vdu_dict['placement_policy']):
properties['availability_zone'] = vdu_dict[
'placement_policy']['availability_zone']
if 'config' in vdu_dict:
properties['config_drive'] = True
metadata = properties.setdefault('metadata', {})
metadata.update(vdu_dict['config'])
for key, value in metadata.items():
metadata[key] = value[:255]
monitoring_policy = vdu_dict.get('monitoring_policy',
'noop')
failure_policy = vdu_dict.get('failure_policy', 'noop')
# Convert the old monitoring specification to the new
# network. This should be removed after Mitaka
if (monitoring_policy == 'ping' and
failure_policy == 'respawn'):
vdu_dict['monitoring_policy'] = {'ping': {
'actions': {
'failure':
'respawn'
}}}
vdu_dict.pop('failure_policy')
if monitoring_policy != 'noop':
monitoring_dict['vdus'][vdu_id] = \
vdu_dict['monitoring_policy']
# to pass necessary parameters to plugin upwards.
for key in ('service_type',):
if key in vdu_dict:
device.setdefault(
'attributes', {})[vdu_id] = jsonutils.dumps(
{key: vdu_dict[key]})
heat_template_yaml = yaml.dump(template_dict)
heat_template_yaml = yaml.dump(template_dict)
fields['template'] = heat_template_yaml
if not device['attributes'].get('heat_template'):
device['attributes']['heat_template'] = heat_template_yaml
device['attributes']['heat_template'] = \
heat_template_yaml
if monitoring_dict.keys():
device['attributes']['monitoring_policy'] = \
jsonutils.dumps(monitoring_dict)
if 'stack_name' not in fields:
name = (__name__ + '_' + self.__class__.__name__ + '-' +

View File

View File

@ -0,0 +1,115 @@
data_types:
tosca.datatypes.tacker.ActionMap:
properties:
trigger:
type: string
required: true
action:
type: string
required: true
params:
type: map
entry_schema:
type: string
tosca.datatypes.tacker.MonitoringType:
properties:
name:
type: string
required: true
actions:
type: list
entry_schema:
type: tosca.datatypes.tacker.ActionMap
parameters:
type: map
entry_schema:
type: string
node_types:
tosca.nodes.nfv.VDU.Tacker:
derived_from: tosca.nodes.nfv.VDU
properties:
image:
# type: tosca.artifacts.Deployment.Image.VM
type: string
flavor:
type: string
availability_zone:
type: string
metadata:
type: map
entry_schema:
type: string
config_drive:
type: boolean
default: false
placement_policy:
# type: tosca.policies.tacker.Placement
type: string
monitoring_policy:
# type: tosca.policies.tacker.Monitoring
type: tosca.datatypes.tacker.MonitoringType
config:
type: string
mgmt_driver:
type: string
service_type:
type: string
tosca.nodes.nfv.CP.Tacker:
derived_from: tosca.nodes.nfv.CP
properties:
management:
type: boolean
required: false
default: false
policy_types:
tosca.policies.tacker.Placement:
derived_from: tosca.policies.Root
tosca.policies.tacker.Failure:
derived_from: tosca.policies.Root
action:
type: string
tosca.policies.tacker.Failure.Respawn:
derived_from: tosca.policies.tacker.Failure
action: respawn
tosca.policies.tacker.Failure.Terminate:
derived_from: tosca.policies.tacker.Failure
action: log_and_kill
tosca.policies.tacker.Failure.Log:
derived_from: tosca.policies.tacker.Failure
action: log
tosca.policies.tacker.Monitoring:
derived_from: tosca.policies.Root
monitoring_params:
type: map
entry_schema:
type: string
tosca.policies.tacker.Monitoring.NoOp:
derived_from: tosca.policies.tacker.Monitoring
tosca.policies.tacker.Monitoring.Ping:
derived_from: tosca.policies.tacker.Monitoring
monitoring_params:
count: 3
interval: 5
tosca.policies.tacker.Monitoring.HttpPing:
derived_from: tosca.policies.tacker.Monitoring.Ping
group_types:
tosca.groups.tacker.VDU:
derived_from: tosca.groups.Root

95
tacker/vm/tosca/utils.py Normal file
View 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.
import os
from tacker.openstack.common import log as logging
LOG = logging.getLogger(__name__)
TACKERCP = 'tosca.nodes.nfv.CP.Tacker'
MONITORING = 'tosca.policies.tacker.Monitoring'
PLACEMENT = 'tosca.policies.tacker.Placement'
FAILURE = 'tosca.policies.tacker.Failure'
VDU = 'tosca.nodes.nfv.VDU'
TACKERVDU = 'tosca.nodes.nfv.VDU.Tacker'
# from toscaparser.tosca_template import ToscaTemplate
delpropmap = {TACKERVDU: ('mgmt_driver', 'config', 'service_type',
'placement_policy', 'monitoring_policy',
'failure_policy'),
TACKERCP: ('management',)}
deletenodes = (MONITORING, FAILURE, PLACEMENT)
def preprocess(template):
pass
def updateimport(template):
file = os.path.dirname(os.path.abspath(__file__)) + '/lib/tacker_defs.yaml'
template['imports'] = [file]
LOG.debug(_("%s") % file)
def findvdus(template):
vdus = []
for nt in template.nodetemplates:
if nt.type_definition.is_derived_from(TACKERVDU):
vdus.append(nt)
return vdus
def get_vdu_monitoring(template):
monitoring_dict = {'vdus': {}}
for nt in template.nodetemplates:
if nt.type_definition.is_derived_from(TACKERVDU):
mon_policy = nt.get_property_value('monitoring_policy') or 'noop'
# mon_data = {mon_policy['name']: {'actions': {'failure':
# 'respawn'}}}
if mon_policy != 'noop':
monitoring_dict['vdus'][nt.name] = mon_policy
return monitoring_dict
def post_process_template(template):
for nt in template.nodetemplates:
if (nt.type_definition.is_derived_from(MONITORING) or
nt.type_definition.is_derived_from(FAILURE) or
nt.type_definition.is_derived_from(PLACEMENT)):
template.nodetemplates.remove(nt)
if nt.type_definition.is_derived_from(TACKERVDU):
pass
if nt.type in delpropmap.keys():
for prop in delpropmap[nt.type]:
for p in nt.get_properties_objects():
if prop == p.name:
nt.get_properties_objects().remove(p)
def get_mgmt_driver(template):
mgmt_driver = None
for nt in template.nodetemplates:
if nt.type_definition.is_derived_from(TACKERVDU):
mgmt_driver = nt.get_property_value('mgmt_driver')
return mgmt_driver
def process_hot_template(hot):
pass