Merge "Add tacker datasource driver"
This commit is contained in:
commit
2df45fffbd
|
@ -0,0 +1,130 @@
|
|||
# Copyright (c) 2018 NEC, Inc.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import division
|
||||
from __future__ import absolute_import
|
||||
import json
|
||||
from tackerclient.v1_0 import client as tacker_client
|
||||
|
||||
from congress.datasources import constants
|
||||
from congress.datasources import datasource_driver
|
||||
from congress.datasources import datasource_utils as ds_utils
|
||||
|
||||
|
||||
class TackerDriver(datasource_driver.PollingDataSourceDriver,
|
||||
datasource_driver.ExecutionDriver):
|
||||
|
||||
VNFS = 'vnfs'
|
||||
VNFDS = 'vnfds'
|
||||
INSTANCES = VNFS + '.instances'
|
||||
value_trans = {'translation-type': 'VALUE'}
|
||||
|
||||
def extract_mgmt_urls(mgmt_url):
|
||||
return json.loads(mgmt_url)
|
||||
|
||||
vnfds_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': VNFDS,
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'field-translators':
|
||||
({'fieldname': 'id', 'translator': value_trans},
|
||||
{'fieldname': 'name', 'translator': value_trans},
|
||||
{'fieldname': 'description', 'translator': value_trans},
|
||||
{'fieldname': 'template_source', 'translator': value_trans},
|
||||
{'fieldname': 'tenant_id', 'translator': value_trans},
|
||||
{'fieldname': 'created_at', 'translator': value_trans},
|
||||
{'fieldname': 'updated_at', 'translator': value_trans})
|
||||
}
|
||||
|
||||
vnfs_translator = {
|
||||
'translation-type': 'HDICT',
|
||||
'table-name': VNFS,
|
||||
'selector-type': 'DICT_SELECTOR',
|
||||
'field-translators':
|
||||
({'fieldname': 'id', 'translator': value_trans},
|
||||
{'fieldname': 'name', 'translator': value_trans},
|
||||
{'fieldname': 'status', 'translator': value_trans},
|
||||
{'fieldname': 'description', 'translator': value_trans},
|
||||
{'fieldname': 'vnfd_id', 'translator': value_trans},
|
||||
{'fieldname': 'vim_id', 'translator': value_trans},
|
||||
{'fieldname': 'tenant_id', 'translator': value_trans},
|
||||
{'fieldname': 'instance_id', 'translator': value_trans},
|
||||
{'fieldname': 'created_at', 'translator': value_trans},
|
||||
{'fieldname': 'updated_at', 'translator': value_trans},
|
||||
{'fieldname': 'error_reason', 'translator': value_trans},
|
||||
{'fieldname': 'mgmt_url',
|
||||
'translator': {'translation-type': 'VDICT',
|
||||
'table-name': INSTANCES,
|
||||
'parent-key': 'id',
|
||||
'parent-col-name': 'vnf_id',
|
||||
'key-col': 'key',
|
||||
'val-col': 'value',
|
||||
'objects-extract-fn': extract_mgmt_urls,
|
||||
'translator': value_trans}})
|
||||
}
|
||||
|
||||
TRANSLATORS = [vnfds_translator, vnfs_translator]
|
||||
|
||||
def __init__(self, name='', args=None):
|
||||
super(TackerDriver, self).__init__(name, args=args)
|
||||
datasource_driver.ExecutionDriver.__init__(self)
|
||||
self.creds = args
|
||||
session = ds_utils.get_keystone_session(self.creds)
|
||||
self.tacker_client = tacker_client.Client(session=session)
|
||||
self.add_executable_client_methods(self.tacker_client,
|
||||
'tackerclient.v1_0.client')
|
||||
self.initialize_update_methods()
|
||||
self._init_end_start_poll()
|
||||
|
||||
@staticmethod
|
||||
def get_datasource_info():
|
||||
result = {}
|
||||
result['id'] = 'tacker'
|
||||
result['description'] = ('Datasource driver that interfaces with '
|
||||
'OpenStack tacker.')
|
||||
result['config'] = ds_utils.get_openstack_required_config()
|
||||
result['config']['api_version'] = constants.OPTIONAL
|
||||
result['config']['lazy_tables'] = constants.OPTIONAL
|
||||
result['secret'] = ['password']
|
||||
return result
|
||||
|
||||
def initialize_update_methods(self):
|
||||
vnfds_method = lambda: self._translate_vnfds(
|
||||
self.tacker_client.list_vnfds()['vnfds'])
|
||||
self.add_update_method(vnfds_method, self.vnfds_translator)
|
||||
|
||||
vnf_method = lambda: self._translate_vnf(
|
||||
self.tacker_client.list_vnfs()['vnfs'])
|
||||
self.add_update_method(vnf_method, self.vnfs_translator)
|
||||
|
||||
@ds_utils.update_state_on_changed(VNFDS)
|
||||
def _translate_vnfds(self, obj):
|
||||
row_data = TackerDriver.convert_objs(obj, self.vnfds_translator)
|
||||
return row_data
|
||||
|
||||
@ds_utils.update_state_on_changed(VNFS)
|
||||
def _translate_vnf(self, obj):
|
||||
row_data = TackerDriver.convert_objs(obj, self.vnfs_translator)
|
||||
return row_data
|
||||
|
||||
def execute(self, action, action_args):
|
||||
"""Overwrite ExecutionDriver.execute()."""
|
||||
# action can be written as a method or an API call.
|
||||
func = getattr(self, action, None)
|
||||
if func and self.is_executable(func):
|
||||
func(action_args)
|
||||
else:
|
||||
self._execute_api(self.tacker_client, action, action_args)
|
|
@ -0,0 +1,97 @@
|
|||
# Copyright (c) 2018 NEC, Inc. 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.
|
||||
#
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import division
|
||||
from __future__ import absolute_import
|
||||
|
||||
import mock
|
||||
|
||||
from congress.datasources import tacker_driver
|
||||
from congress.tests import base
|
||||
from congress.tests import helper
|
||||
|
||||
|
||||
class TestTackerDriver(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestTackerDriver, self).setUp()
|
||||
self.tacker_client_p = mock.patch("tackerclient.v1_0.client.Client")
|
||||
self.tacker_client_p.start()
|
||||
|
||||
args = helper.datasource_openstack_args()
|
||||
args['poll_time'] = 0
|
||||
args['client'] = mock.MagicMock()
|
||||
|
||||
self.driver = tacker_driver.TackerDriver(args=args)
|
||||
|
||||
self.mock_vnfds = {"vnfds": [
|
||||
{"template_source": "onboarded",
|
||||
"service_types": ["vnfd"],
|
||||
"description": "Demo example",
|
||||
"tenant_id": "a9d8315792db4007b4ef2495ad88757a",
|
||||
"created_at": "2018-09-11 06:12:03",
|
||||
"updated_at": None,
|
||||
"attributes": {"vnfd": "description: Demo example\nmetadata: {template_name: sample-tosca-vnfd}\ntopology_template:\n node_templates:\n CP1:\n properties: {anti_spoofing_protection: false, management: true, order: 0}\n requirements:\n - virtualLink: {node: VL1}\n - virtualBinding: {node: VDU1}\n type: tosca.nodes.nfv.CP.Tacker\n CP2:\n properties: {anti_spoofing_protection: false, order: 1}\n requirements:\n - virtualLink: {node: VL2}\n - virtualBinding: {node: VDU1}\n type: tosca.nodes.nfv.CP.Tacker\n CP3:\n properties: {anti_spoofing_protection: false, order: 2}\n requirements:\n - virtualLink: {node: VL3}\n - virtualBinding: {node: VDU1}\n type: tosca.nodes.nfv.CP.Tacker\n VDU1:\n capabilities:\n nfv_compute:\n properties: {disk_size: 1 GB, mem_size: 512 MB, num_cpus: 1}\n properties: {availability_zone: nova, config: 'param0: key1\n\n param1: key2\n\n ', image: cirros-0.4.0-x86_64-disk, mgmt_driver: noop}\n type: tosca.nodes.nfv.VDU.Tacker\n VL1:\n properties: {network_name: net_mgmt, vendor: Tacker}\n type: tosca.nodes.nfv.VL\n VL2:\n properties: {network_name: net0, vendor: Tacker}\n type: tosca.nodes.nfv.VL\n VL3:\n properties: {network_name: net1, vendor: Tacker}\n type: tosca.nodes.nfv.VL\ntosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0\n"}, # noqa
|
||||
"id": "b9a9f468-7966-422f-a6ff-b1931eea6af5",
|
||||
"name": "vnfd-hello"}]}
|
||||
|
||||
self.mock_vnfs = {'vnfs': [
|
||||
{'status': 'ACTIVE',
|
||||
'description': 'sample-tosca-vnfd-scaling',
|
||||
'vnfd_id': 'b9a9f468-7966-422f-a6ff-b1931eea6af5',
|
||||
'tenant_id': '49577ebc4eaa4d30abc9ecfd9bf23757',
|
||||
'created_at': '2018-10-12 05:47:03',
|
||||
'updated_at': None,
|
||||
'instance_id': '0be0b3b3-2da4-4e27-99a0-3bbf89fb1e4c',
|
||||
'mgmt_url': '{"VDU1": "192.168.120.22", "VDU2": "192.168.120.1"}',
|
||||
'vim_id': '856057ac-97d9-4eb7-881e-4530af24b187',
|
||||
'placement_attr': {'vim_name': 'hellovim'},
|
||||
'error_reason': None,
|
||||
'attributes': {'heat_template': "heat_template_version: 2013-05-23\ndescription: 'sample-tosca-vnfd-scaling\n\n '\nparameters: {}\nresources:\n CP1:\n type: OS::Neutron::Port\n properties: {port_security_enabled: false, network: net_mgmt}\n CP2:\n type: OS::Neutron::Port\n properties: {port_security_enabled: false, network: net_mgmt}\n VDU1:\n type: OS::Nova::Server\n properties:\n user_data_format: SOFTWARE_CONFIG\n availability_zone: nova\n image: cirros-0.4.0-x86_64-disk\n flavor: m1.tiny\n networks:\n - port: {get_resource: CP1}\n config_drive: false\n VDU2:\n type: OS::Nova::Server\n properties:\n user_data_format: SOFTWARE_CONFIG\n availability_zone: nova\n image: cirros-0.4.0-x86_64-disk\n flavor: m1.tiny\n networks:\n - port: {get_resource: CP2}\n config_drive: false\noutputs:\n mgmt_ip-VDU2:\n value:\n get_attr: [CP2, fixed_ips, 0, ip_address]\n mgmt_ip-VDU1:\n value:\n get_attr: [CP1, fixed_ips, 0, ip_address]\n"}, # noqa
|
||||
'id': 'd40ebb81-4cd2-4854-8665-77114d7c25e5',
|
||||
'name': 'sampleScalevnf123'}]}
|
||||
|
||||
self.expected_state = {
|
||||
'vnfds': {('b9a9f468-7966-422f-a6ff-b1931eea6af5',
|
||||
'vnfd-hello', 'Demo example', 'onboarded',
|
||||
'a9d8315792db4007b4ef2495ad88757a',
|
||||
'2018-09-11 06:12:03', None)},
|
||||
'vnfs': {('d40ebb81-4cd2-4854-8665-77114d7c25e5',
|
||||
'sampleScalevnf123', 'ACTIVE',
|
||||
'sample-tosca-vnfd-scaling',
|
||||
'b9a9f468-7966-422f-a6ff-b1931eea6af5',
|
||||
'856057ac-97d9-4eb7-881e-4530af24b187',
|
||||
'49577ebc4eaa4d30abc9ecfd9bf23757',
|
||||
'0be0b3b3-2da4-4e27-99a0-3bbf89fb1e4c',
|
||||
'2018-10-12 05:47:03', None, None)},
|
||||
'vnfs.instances': {
|
||||
('d40ebb81-4cd2-4854-8665-77114d7c25e5', 'VDU2',
|
||||
'192.168.120.1'),
|
||||
('d40ebb81-4cd2-4854-8665-77114d7c25e5', 'VDU1',
|
||||
'192.168.120.22')}
|
||||
}
|
||||
|
||||
def test_update_from_datasource(self):
|
||||
with base.nested(
|
||||
mock.patch.object(self.driver.tacker_client,
|
||||
"list_vnfds",
|
||||
return_value=self.mock_vnfds),
|
||||
mock.patch.object(self.driver.tacker_client,
|
||||
"list_vnfs",
|
||||
return_value=self.mock_vnfs)
|
||||
) as (list_vnfds, list_vnfs,):
|
||||
self.driver.update_from_datasource()
|
||||
self.assertEqual(self.expected_state, self.driver.state)
|
|
@ -518,5 +518,8 @@ def supported_drivers():
|
|||
"webhook alarm notifications."},
|
||||
{"id": "monasca_webhook",
|
||||
"description": "Datasource driver that accepts Monasca webhook "
|
||||
"alarm notifications."}]
|
||||
"alarm notifications."},
|
||||
{"id": "tacker",
|
||||
"description": "Datasource driver that interfaces with OpenStack "
|
||||
"tacker."}]
|
||||
return results
|
||||
|
|
|
@ -79,6 +79,7 @@ function configure_congress_datasources {
|
|||
_configure_service heat heat
|
||||
_configure_service aodh aodh
|
||||
_configure_service mistral mistral
|
||||
_configure_service tacker tacker
|
||||
if [[ $ENABLE_CONGRESS_AGENT == "True" ]] ; then
|
||||
_configure_service congress-agent config
|
||||
fi
|
||||
|
@ -93,7 +94,7 @@ function _configure_tempest {
|
|||
# set correctly due to different env setup scenario, so it is
|
||||
# better to set it explicitly here.
|
||||
local service
|
||||
local required_services="heat,ironic,aodh,murano,mistral,monasca,neutron-qos"
|
||||
local required_services="heat,ironic,aodh,murano,mistral,monasca,neutron-qos,tacker"
|
||||
for service in ${required_services//,/ }; do
|
||||
if is_service_enabled $service ; then
|
||||
iniset $TEMPEST_CONFIG service_available $service "True"
|
||||
|
|
|
@ -109,6 +109,7 @@ python-neutronclient==6.7.0
|
|||
python-novaclient==9.1.0
|
||||
python-subunit==1.0.0
|
||||
python-swiftclient==3.2.0
|
||||
python-tackerclient==0.8.0
|
||||
pytz==2018.3
|
||||
PyYAML==3.10.0
|
||||
reno==2.5.0
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
prelude: >
|
||||
features:
|
||||
- |
|
||||
Datasource driver for tacker is added, that will poll data from tacker
|
||||
service. It includes VNFDs and VNFs data which is stored in respective
|
||||
congress tables.
|
|
@ -11,6 +11,7 @@ Paste>=2.0.2 # MIT
|
|||
PasteDeploy>=1.5.0 # MIT
|
||||
pbr!=2.1.0,>=2.0.0 # Apache-2.0
|
||||
aodhclient>=0.9.0 # Apache-2.0
|
||||
python-tackerclient>=0.8.0 # Apache-2.0
|
||||
python-keystoneclient>=3.8.0 # Apache-2.0
|
||||
python-heatclient>=1.10.0 # Apache-2.0
|
||||
python-monascaclient>=1.12.1 # Apache-2.0
|
||||
|
@ -45,4 +46,4 @@ oslo.middleware>=3.31.0 # Apache-2.0
|
|||
oslo.vmware>=2.17.0 # Apache-2.0
|
||||
oslo.log>=3.36.0 # Apache-2.0
|
||||
WebOb>=1.7.1 # MIT
|
||||
PyYAML>=3.10.0 # MIT
|
||||
PyYAML>=3.10.0 # MIT
|
||||
|
|
|
@ -74,6 +74,7 @@ congress.datasource.drivers =
|
|||
nova = congress.datasources.nova_driver:NovaDriver
|
||||
plexxi = congress.datasources.plexxi_driver:PlexxiDriver
|
||||
swift = congress.datasources.swift_driver:SwiftDriver
|
||||
tacker = congress.datasources.tacker_driver:TackerDriver
|
||||
vcenter = congress.datasources.vCenter_driver:VCenterDriver
|
||||
vitrage = congress.datasources.vitrage_driver:VitrageDriver
|
||||
|
||||
|
|
Loading…
Reference in New Issue