`$ ./install_osm.sh --pla`
## Create the price lists
-The price list for compute determines the price for each VNF at each VIM (or Point of Presence - PoP). The file (vnf_price_list.yaml) is written in Yaml and is exemplified below.
+The price list for compute determines the price for each VNF at each VIM (or Point of Presence - PoP).
+The file (vnf_price_list.yaml) is written in Yaml. There are two different structures possible for the price list file.
+In the first alternative prices for a specific VIM are directly associated with a vnfd.
+In the second alternative prices for a specific VIM are also associated with a OSM project id.
+The latter alternative makes it possible for different OMS users to have different price models depending on their
+associated OMS project.
+
+###vnf_price_lists.yaml - Alternative one
```
- vnfd: testVnfOne
- vim_url: http://10.234.12.44:5000/v3
vim_name: OpenStack2
price: 9
- - vim_url: http://10.234.12.46:5000/v3
- vim_name: OpenStack3
- price: 8
- - vim_url: http://10.234.12.43:5000/v3
- vim_name: OpenStack4
- price: 7
- vnfd: hackfest_multivdu-vnf
prices:
- vim_url: http://10.234.12.47:5000/v3
- vim_url: http://10.234.12.44:5000/v3
vim_name: OpenStack2
price: 18
- - vim_url: http://10.234.12.46:5000/v3
- vim_name: OpenStack3
- price: 19
- - vim_url: http://10.234.12.43:5000/v3
- vim_name: OpenStack4
- price: 20
+```
+###vnf_price_list.yaml - Alternative two
+```
+- vnfd: testVnfOne
+ project_alfa:
+ prices:
+ - vim_url: http://10.234.12.47:5000/v3
+ vim_name: OpenStack1
+ price: 10
+ - vim_url: http://10.234.12.44:5000/v3
+ vim_name: OpenStack2
+ price: 9
+ project_beta:
+ prices:
+ - vim_url: http://10.234.12.47:5000/v3
+ vim_name: OpenStack1
+ price: 9
+ - vim_url: http://10.234.12.44:5000/v3
+ vim_name: OpenStack2
+ price: 10
+- vnfd: hackfest_multivdu-vnf
+ project_alfa:
+ prices:
+ - vim_url: http://10.234.12.47:5000/v3
+ vim_name: OpenStack1
+ price: 17
+ - vim_url: http://10.234.12.44:5000/v3
+ vim_name: OpenStack2
+ price: 18
+ project_beta:
+ prices:
+ - vim_url: http://10.234.12.47:5000/v3
+ vim_name: OpenStack1
+ price: 7
+ - vim_url: http://10.234.12.44:5000/v3
+ vim_name: OpenStack2
+ price: 8
```
The price list for transport links between VIMs (PoP Interconnecting Link – PiL). In current release the price is given per link without any consideration to BW or other QoS parameter. The file (pil_price_list.yaml) is written in Yaml and is exemplified below. Note: In current OSM release the link characteristics are hard coded into this file, in future releases this data should be retrieved from the infrastructure by monitoring mechanisms.
pil_latency: 120
pil_jitter: 12
pil_endpoints:
- - http://10.234.12.47:5000/v3
- - http://10.234.12.44:5000/v3
+ - OpenStack1
+ - OpenStack2
- pil_description: Link between OpenStack1 and OpenStack3
pil_price: 13
pil_latency: 130
pil_jitter: 13
pil_endpoints:
- - http://10.234.12.47:5000/v3
- - http://10.234.12.46:5000/v3
+ - OpenStack1
+ - OpenStack3
- pil_description: Link between OpenStack1 and OpenStack4
pil_price: 14
pil_latency: 140
pil_jitter: 14
pil_endpoints:
- - http://10.234.12.47:5000/v3
- - http://10.234.12.43:5000/v3
+ - OpenStack1
+ - OpenStack4
- pil_description: Link between OpenStack2 and OpenStack3
pil_price: 23
pil_latency: 230
pil_jitter: 23
pil_endpoints:
- - http://10.234.12.44:5000/v3
- - http://10.234.12.46:5000/v3
+ - OpenStack2
+ - OpenStack3
- pil_description: Link between OpenStack2 and OpenStack4
pil_price: 24
pil_latency: 240
pil_jitter: 24
pil_endpoints:
- - http://10.234.12.44:5000/v3
- - http://10.234.12.43:5000/v3
+ - OpenStack2
+ - OpenStack4
- pil_description: Link between OpenStack3 and OpenStack4
pil_price: 34
pil_latency: 340
pil_jitter: 34
pil_endpoints:
- - http://10.234.12.46:5000/v3
- - http://10.234.12.43:5000/v3
+ - OpenStack3
+ - OpenStack4
```
trp_link_characteristics = [[0 if col == row else 0x7fff for col in range(num_vims)] for row in range(num_vims)]
for pil in self._pil_info['pil']:
if characteristics in pil.keys():
- url1 = pil['pil_endpoints'][0]
- url2 = pil['pil_endpoints'][1]
+ ep1 = pil['pil_endpoints'][0]
+ ep2 = pil['pil_endpoints'][1]
# only consider links between applicable vims
- if url1 in self._vim_accounts_info and url2 in self._vim_accounts_info:
- idx1 = self._vim_accounts_info[url1]['idx']
- idx2 = self._vim_accounts_info[url2]['idx']
+ if ep1 in self._vim_accounts_info and ep2 in self._vim_accounts_info:
+ idx1 = self._vim_accounts_info[ep1]['idx']
+ idx2 = self._vim_accounts_info[ep2]['idx']
trp_link_characteristics[idx1][idx2] = pil[characteristics]
trp_link_characteristics[idx2][idx1] = pil[characteristics]
"""
vld_desc = []
for vld in self._nsd['vld']:
- if vld['mgmt-network'] is False:
+ if vld.get('mgmt-network', False) is False:
vld_desc_entry = {}
cp_refs = [ep_ref['member-vnf-index-ref'] for ep_ref in vld['vnfd-connection-point-ref']]
- vld_desc_entry['cp_refs'] = cp_refs
- if 'link-constraint' in vld.keys():
- for constraint in vld['link-constraint']:
- if constraint['constraint-type'] == 'LATENCY':
- vld_desc_entry['latency'] = constraint['value']
- elif constraint['constraint-type'] == 'JITTER':
- vld_desc_entry['jitter'] = constraint['value']
- vld_desc.append(vld_desc_entry)
+ if len(cp_refs) == 2:
+ vld_desc_entry['cp_refs'] = cp_refs
+ if 'link-constraint' in vld.keys():
+ for constraint in vld['link-constraint']:
+ if constraint['constraint-type'] == 'LATENCY':
+ vld_desc_entry['latency'] = constraint['value']
+ elif constraint['constraint-type'] == 'JITTER':
+ vld_desc_entry['jitter'] = constraint['value']
+ vld_desc.append(vld_desc_entry)
# create candidates from instantiate params
if self._order_constraints is not None:
def create_ns_placement_data(self):
"""populate NsPlacmentData object
"""
- ns_placement_data = {'vim_accounts': [vim_data['id'] for
- vim_data in self._vim_accounts_info.values()],
+ ns_placement_data = {'vim_accounts': [vim_data['id'] for _, vim_data in sorted(self._vim_accounts_info.items(),
+ key=lambda item: item[1][
+ 'idx'])],
'trp_link_latency': self._produce_trp_link_characteristics_data('pil_latency'),
'trp_link_jitter': self._produce_trp_link_characteristics_data('pil_jitter'),
'trp_link_price_list': self._produce_trp_link_characteristics_data('pil_price'),
import asyncio
import logging
-# import platform
from pathlib import Path
-# import pkg_resources
import yaml
from osm_common import dbmemory, dbmongo, msglocal, msgkafka
nslcmop = self.db.get_one("nslcmops", db_filter)
return nslcmop
+ def _get_projects(self):
+ """
+ :return: project name to project id mapping
+ """
+ projects = self.db.get_list("projects")
+ return {project['_id']: project['name'] for project in projects}
+
def _get_nsd(self, nsd_id):
"""
:param nsd_id:
db_filter = {"_id": vim_account_ids}
return self.db.get_list("vim_accounts", db_filter)
- def _get_vnf_price_list(self, price_list_file_path):
+ def _read_vnf_price_list(self, price_list_file_path):
+ """
+ read vnf price list configuration file
+ :param price_list_file_path:
+ :return:
+ """
+ with open(str(price_list_file_path)) as pl_fd:
+ price_list = yaml.safe_load_all(pl_fd)
+ return next(price_list)
+
+ def _price_list_with_project(self, price_list):
+ """
+ Figure out if this price list is with project or not.
+ Note: to handle the unlikely event that a project is called 'prices' we do not simply check if 'prices'
+ is in the dict keys for a price list sequence but rather go down one step in the nesting
+ in which we either have
+ 1) 'prices:{vim_url:...}' if prices are also per project, or
+ 2) '{vim_url:...}' if prices are only per vim
+
+ :param price_list:
+ :return: True if project part of price list, else False
+ """
+ price_list_entry_keys = set(price_list[0].keys())
+ price_list_entry_keys.remove('vnfd')
+ pl_key = price_list_entry_keys.pop()
+ entry_to_check = price_list[0][pl_key][0].keys()
+ return True if 'prices' in entry_to_check else False
+
+ def _get_vnf_price_list(self, price_list_file_path, project_name=None):
"""
- read vnf price list configuration file and reformat its content
+ read vnf price list configuration file, determine its type and reformat content accordingly
- :param: price_list_file: Path to price list file
+ :param price_list_file_path:
+ :param project_name:
:return: dictionary formatted as {'<vnfd>': {'<vim-url>':'<price>'}}
"""
- with open(str(price_list_file_path)) as pl_fd:
- price_list_data = yaml.safe_load_all(pl_fd)
- return {i['vnfd']: {i1['vim_url']: i1['price'] for i1 in i['prices']} for i in next(price_list_data)}
+ price_list_data = self._read_vnf_price_list(price_list_file_path)
+ if self._price_list_with_project(price_list_data):
+ res = {}
+ for i in price_list_data:
+ price_data = i[project_name] if type(i[project_name]) is dict else i[project_name][0]
+ res_component = {i['vim_name']: i['price'] for i in price_data['prices']}
+ res.update({i['vnfd']: res_component})
+ return res
+ else:
+ return {i['vnfd']: {i1['vim_name']: i1['price'] for i1 in i['prices']} for i in price_list_data}
def _get_pil_info(self, pil_info_file_path):
"""
nslcmop = self._get_nslcmop(nslcmop_id)
nsd = self._get_nsd(nslcmop['operationParams']['nsdId'])
self.log.info("nsd: {}".format(nsd))
+ projects = self._get_projects()
+ self.log.info("projects: {}".format(projects))
+ nslcmop_project = nslcmop['_admin']['projects_read'][0]
+ self.log.info("nslcmop_project: {}".format(nslcmop_project))
valid_vim_accounts = nslcmop['operationParams']['validVimAccounts']
vim_accounts_data = self._get_vim_accounts(valid_vim_accounts)
- vims_information = {_['vim_url']: _['_id'] for _ in vim_accounts_data}
- price_list = self._get_vnf_price_list(Server.vnf_price_list_file)
+ vims_information = {_['name']: _['_id'] for _ in vim_accounts_data}
+ price_list = self._get_vnf_price_list(Server.vnf_price_list_file, projects[nslcmop_project])
pil_info = self._get_pil_info(Server.pil_price_list_file)
pinning = nslcmop['operationParams'].get('vnf')
self.log.info("pinning: {}".format(pinning))
--- /dev/null
+# Copyright 2020 ArctosLabs Scandinavia AB
+#
+# 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.
+
+# POP Interconnecting Link (PIL), price list and latency
+pil:
+ - pil_description: Link between OpenStack1 and OpenStack2
+ pil_price: 5
+ pil_latency: 20
+ pil_endpoints:
+ - OpenStack1
+ - OpenStack2
+ - pil_description: Link between OpenStack1 and OpenStack3
+ pil_price: 30
+ pil_latency: 30
+ pil_endpoints:
+ - OpenStack1
+ - OpenStack3
+ - pil_description: Link between OpenStack1 and OpenStack4
+ pil_price: 30
+ pil_latency: 30
+ pil_endpoints:
+ - OpenStack1
+ - OpenStack4
+ - pil_description: Link between OpenStack2 and OpenStack3
+ pil_price: 10
+ pil_latency: 10
+ pil_endpoints:
+ - OpenStack2
+ - OpenStack3
+ - pil_description: Link between OpenStack2 and OpenStack4
+ pil_price: 10
+ pil_latency: 10
+ pil_endpoints:
+ - OpenStack2
+ - OpenStack4
--- /dev/null
+# Copyright 2020 ArctosLabs Scandinavia AB
+#
+# 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.
+
+# POP Interconnecting Link (PIL), price list and latency
+pil:
+ - pil_description: Link between OpenStack1 and OpenStack2
+ pil_price: 12
+ pil_latency: 120
+ pil_jitter: 1200
+ project: hackfest_project_a
+ pil_endpoints:
+ - OpenStack1
+ - OpenStack2
+ - pil_description: Link between OpenStack1 and OpenStack3
+ pil_price: 13
+ pil_latency: 130
+ pil_jitter: 1300
+ project: hackfest_project_a
+ pil_endpoints:
+ - OpenStack1
+ - OpenStack3
+ - pil_description: Link between OpenStack1 and OpenStack4
+ pil_price: 14
+ pil_latency: 140
+ pil_jitter: 1400
+ project: hackfest_project_a
+ pil_endpoints:
+ - OpenStack1
+ - OpenStack4
+ - pil_description: Link between OpenStack2 and OpenStack3
+ pil_price: 23
+ pil_latency: 230
+ pil_jitter: 2300
+ project: hackfest_project_a
+ pil_endpoints:
+ - OpenStack2
+ - OpenStack3
+ - pil_description: Link between OpenStack2 and OpenStack4
+ pil_price: 24
+ pil_latency: 240
+ pil_jitter: 2400
+ project: hackfest_project_a
+ pil_endpoints:
+ - OpenStack2
+ - OpenStack4
+ - pil_description: Link between OpenStack3 and OpenStack4
+ pil_price: 34
+ pil_latency: 340
+ pil_jitter: 3400
+ project: hackfest_project_a
+ pil_endpoints:
+ - OpenStack3
+ - OpenStack4
--- /dev/null
+# Copyright 2020 ArctosLabs Scandinavia AB
+#
+# 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.
+
+# POP Interconnecting Link (PIL), price list and latency
+pil:
+ - pil_description: Link between OpenStack1 and OpenStack2
+ pil_price: 12
+ pil_latency: 120
+ pil_jitter: 1200
+ project: hackfest_project_a
+ pil_endpoints:
+ - OpenStack1
+ - OpenStack2
+ - pil_description: Link between OpenStack1 and OpenStack3
+ pil_price: 13
+ pil_latency: 130
+ project: hackfest_project_a
+ pil_endpoints:
+ - OpenStack1
+ - OpenStack3
+ - pil_description: Link between OpenStack1 and OpenStack4
+ pil_price: 14
+ pil_jitter: 1400
+ project: hackfest_project_a
+ pil_endpoints:
+ - OpenStack1
+ - OpenStack4
+ - pil_description: Link between OpenStack2 and OpenStack3
+ pil_price: 23
+ project: hackfest_project_a
+ pil_endpoints:
+ - OpenStack2
+ - OpenStack3
+ - pil_description: Link between OpenStack2 and OpenStack4
+ pil_price: 24
+ pil_latency: 240
+ pil_jitter: 2400
+ project: hackfest_project_a
+ pil_endpoints:
+ - OpenStack2
+ - OpenStack4
+ - pil_description: Link between OpenStack3 and OpenStack4
+ pil_price: 34
+ pil_latency: 340
+ pil_jitter: 3400
+ project: hackfest_project_a
+ pil_endpoints:
+ - OpenStack3
+ - OpenStack4
--- /dev/null
+# Licensed under the Apache License, Version 2.0 (the "License");\r
+# you may not use this file except in compliance with the License.\r
+# You may obtain a copy of the License at\r
+#\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+# Unless required by applicable law or agreed to in writing, software\r
+# distributed under the License is distributed on an "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+# implied.\r
+# See the License for the specific language governing permissions and\r
+# limitations under the License.\r
+\r
+nsd-catalog:\r
+ nsd:\r
+ - id: slice_hackfest_middle_nsd\r
+ name: slice_hackfest_middle_nsd\r
+ short-name: slice_hackfest_middle_ns\r
+ description: NSD to be used on Slice Session of the 8th hackfest\r
+ vendor: OSM\r
+ version: '1.0'\r
+ logo: osm_2x.png\r
+\r
+ constituent-vnfd:\r
+ - member-vnf-index: "1"\r
+ vnfd-id-ref: slice_hackfest_middle_vnfd\r
+\r
+ connection-point:\r
+ - name: nsd_cp_mgmt\r
+ vld-id-ref: nsd_vnfd_vld_mgmt\r
+ - name: nsd_cp_data1\r
+ vld-id-ref: nsd_vnfd_vld_data1\r
+ - name: nsd_cp_data2\r
+ vld-id-ref: nsd_vnfd_vld_data2\r
+\r
+ vld:\r
+ - id: nsd_vnfd_vld_mgmt\r
+ name: nsd_vnfd_vld_mgmt\r
+ short-name: nsd_vnfd_vld_mgmt\r
+ type: ELAN\r
+ mgmt-network: !!bool True\r
+ vnfd-connection-point-ref:\r
+ - member-vnf-index-ref: "1"\r
+ vnfd-id-ref: slice_hackfest_middle_vnfd\r
+ vnfd-connection-point-ref: eth0\r
+ - id: nsd_vnfd_vld_data1\r
+ name: nsd_vnfd_vld_data1\r
+ short-name: nsd_vnfd_vld_data1\r
+ type: ELAN\r
+ mgmt-network: !!bool False\r
+ vnfd-connection-point-ref:\r
+ - member-vnf-index-ref: "1"\r
+ vnfd-id-ref: slice_hackfest_middle_vnfd\r
+ vnfd-connection-point-ref: eth1\r
+ - id: nsd_vnfd_vld_data2\r
+ name: nsd_vnfd_vld_data2\r
+ short-name: nsd_vnfd_vld_data2\r
+ type: ELAN\r
+ mgmt-network: !!bool False\r
+ vnfd-connection-point-ref:\r
+ - member-vnf-index-ref: "1"\r
+ vnfd-id-ref: slice_hackfest_middle_vnfd\r
+ vnfd-connection-point-ref: eth2
\ No newline at end of file
FIXME temporary, we will need more control over vim_urls and _id for test purpose - make a generator
:return: vim_url and _id as dict, i.e. extract these from vim_accounts data
"""
- return {_['vim_url']: _['_id'] for _ in vim_accounts}
+ return {_['name']: _['_id'] for _ in vim_accounts}
def _adjust_path(self, file):
"""In case we are not running from test directory,
price_list_file = "vnf_price_list.yaml"
with open(str(Path(self._adjust_path(price_list_file)))) as pl_fd:
price_list_data = yaml.safe_load_all(pl_fd)
- return {i['vnfd']: {i1['vim_url']: i1['price'] for i1 in i['prices']} for i in next(price_list_data)}
+ return {i['vnfd']: {i1['vim_name']: i1['price'] for i1 in i['prices']} for i in next(price_list_data)}
def _produce_ut_vnf_test_price_list(self, price_list):
price_list_file = price_list
with open(str(Path(self._adjust_path(price_list_file)))) as pl_fd:
price_list_data = yaml.safe_load_all(pl_fd)
- return {i['vnfd']: {i1['vim_url']: i1['price'] for i1 in i['prices']} for i in next(price_list_data)}
+ return {i['vnfd']: {i1['vim_name']: i1['price'] for i1 in i['prices']} for i in next(price_list_data)}
def test__produce_trp_link_characteristics_link_latency_with_more_vims(self):
"""
self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts_more_vims),
self._produce_ut_vnf_price_list(),
nsd=None,
- pil_info=self._populate_pil_info('pil_unittest1.yaml'),
+ pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'),
pinning=None)
pil_latencies = nspdf._produce_trp_link_characteristics_data('pil_latency')
content_produced = [i for row in pil_latencies for i in row]
self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts_fewer_vims),
self._produce_ut_vnf_price_list(),
nsd=None,
- pil_info=self._populate_pil_info('pil_unittest1.yaml'),
+ pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'),
pinning=None)
pil_latencies = nspdf._produce_trp_link_characteristics_data('pil_latency')
content_produced = [i for row in pil_latencies for i in row]
nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
self._produce_ut_vnf_price_list(),
nsd=None,
- pil_info=self._populate_pil_info('pil_unittest1.yaml'), pinning=None)
+ pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
pil_latencies = nspdf._produce_trp_link_characteristics_data('pil_latency')
content_produced = [i for row in pil_latencies for i in row]
self.assertEqual(Counter(content_expected), Counter(content_produced), 'trp_link_latency incorrect')
nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
self._produce_ut_vnf_price_list(),
nsd=None,
- pil_info=self._populate_pil_info('pil_unittest1.yaml'), pinning=None)
+ pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
pil_jitter = nspdf._produce_trp_link_characteristics_data('pil_jitter')
content_produced = [i for row in pil_jitter for i in row]
self.assertEqual(Counter(content_expected), Counter(content_produced), 'trp_link_jitter incorrect')
nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(self.vim_accounts_fewer_vims),
self._produce_ut_vnf_price_list(),
nsd=None,
- pil_info=self._populate_pil_info('pil_unittest1.yaml'), pinning=None)
+ pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
pil_latencies = nspdf._produce_trp_link_characteristics_data('pil_jitter')
content_produced = [i for row in pil_latencies for i in row]
self.assertEqual(Counter(content_expected), Counter(content_produced), 'trp_link_jitter incorrect')
nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(self.vim_accounts_more_vims),
self._produce_ut_vnf_price_list(),
nsd=None,
- pil_info=self._populate_pil_info('pil_unittest1.yaml'), pinning=None)
+ pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
pil_latencies = nspdf._produce_trp_link_characteristics_data('pil_jitter')
content_produced = [i for row in pil_latencies for i in row]
self.assertEqual(Counter(content_expected), Counter(content_produced), 'trp_link_jitter incorrect')
nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
self._produce_ut_vnf_price_list(),
nsd=None,
- pil_info=self._populate_pil_info('pil_unittest1.yaml'), pinning=None)
+ pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
pil_prices = nspdf._produce_trp_link_characteristics_data('pil_price')
content_produced = [i for row in pil_prices for i in row]
self.assertEqual(Counter(content_expected), Counter(content_produced), 'invalid trp link prices')
nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(self.vim_accounts_fewer_vims),
self._produce_ut_vnf_price_list(),
nsd=None,
- pil_info=self._populate_pil_info('pil_unittest1.yaml'), pinning=None)
+ pil_info=self._populate_pil_info('pil_unittest1_keys.yaml'), pinning=None)
pil_prices = nspdf._produce_trp_link_characteristics_data('pil_price')
content_produced = [i for row in pil_prices for i in row]
self.assertEqual(Counter(content_expected), Counter(content_produced), 'invalid trp link prices')
nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
self._produce_ut_vnf_price_list(),
nsd=None,
- pil_info=self._populate_pil_info('pil_unittest2.yaml'), pinning=None)
+ pil_info=self._populate_pil_info('pil_unittest2_keys.yaml'), pinning=None)
pil_jitter = nspdf._produce_trp_link_characteristics_data('pil_jitter')
content_produced = [i for row in pil_jitter for i in row]
self.assertEqual(Counter(content_expected), Counter(content_produced),
self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(), "vld_desc_incorrect")
+ def test__produce_vld_desc_slice_nsd(self):
+ vld_desc_expected = []
+ nsd = self._get_ut_nsd_from_file('slice_hackfest_middle_nsd.yaml')
+ nsd = nsd['nsd-catalog']['nsd'][0]
+ nspdf = NsPlacementDataFactory(self._produce_ut_vim_accounts_info(TestNsPlacementDataFactory.vim_accounts),
+ self._produce_ut_vnf_price_list(),
+ nsd=nsd,
+ pil_info=None, pinning=None,
+ order_constraints=None)
+
+ self.assertEqual(vld_desc_expected, nspdf._produce_vld_desc(), "vld_desc_incorrect")
+
def test__produce_vld_desc(self):
"""
# See the License for the specific language governing permissions and
# limitations under the License.
import asyncio
-# import platform
-# import random
import os
import sys
-# import unittest
from unittest import TestCase, mock
from unittest.mock import Mock
-# import pkg_resources
import yaml
from osm_pla.placement.mznplacement import NsPlacementDataFactory, MznPlacementConductor
FIXME temporary, we will need more control over vim_urls and _id for test purpose - make a generator
:return: vim_url and _id as dict, i.e. extract these from vim_accounts data
"""
- return {_['vim_url']: _['_id'] for _ in list_of_vims}
+ return {_['name']: _['_id'] for _ in list_of_vims}
def _produce_ut_vnf_price_list(self):
price_list_file = "vnf_price_list.yaml"
with open(str(Path(price_list_file))) as pl_fd:
price_list_data = yaml.safe_load_all(pl_fd)
- return {i['vnfd']: {i1['vim_url']: i1['price'] for i1 in i['prices']} for i in next(price_list_data)}
+ return {i['vnfd']: {i1['vim_name']: i1['price'] for i1 in i['prices']} for i in next(price_list_data)}
def _populate_pil_info(self, file):
"""
def test__get_vnf_price_list(self):
server = self.serverSetup()
- pl = server._get_vnf_price_list(Path(self._adjust_path('./vnf_price_list.yaml')))
- self.assertIs(type(pl), dict, "price list not a dictionary")
- for k, v in pl.items():
+ pl1 = server._get_vnf_price_list(Path(self._adjust_path('./vnf_price_list.yaml')))
+ self.assertIs(type(pl1), dict, "price list not a dictionary")
+ for k, v in pl1.items():
self.assertIs(type(v), dict, "price list values not a dict")
+ pl2 = server._get_vnf_price_list(Path(self._adjust_path('./vnf_price_list_keys.yaml')), 'hackfest_project_a')
+ self.assertIs(type(pl2), dict, "price list not a dictionary")
+ for k, v in pl2.items():
+ self.assertIs(type(v), dict, "price list values not a dict")
+ self.assertEqual(pl1, pl2, "non-project and project price lists differ")
+
def test__get_pil_info(self):
server = self.serverSetup()
ppi = server._get_pil_info(Path(self._adjust_path('./pil_price_list.yaml')))
@mock.patch.object(Server, '_get_nslcmop')
@mock.patch.object(Server, '_get_vnf_price_list')
@mock.patch.object(Server, '_get_pil_info')
- def test_get_placement(self, mock_get_pil_info, mock_get_vnf_price_list, mock__get_nslcmop, mock__get_nsd,
+ @mock.patch.object(Server, '_get_projects')
+ def test_get_placement(self, mock_get_projects, mock_get_pil_info, mock_get_vnf_price_list, mock__get_nslcmop,
+ mock__get_nsd,
mock__get_vim_accounts,
mock_create_ns_placement_data,
mock_do_placement_computation):
mock_do_placement_computation.return_value = placement_ret_val
_run(server.get_placement(nslcmop_record_wo_pinning['id']))
+ self.assertTrue(mock_get_projects.called, '_get_projects not called as expected')
self.assertTrue(mock_get_vnf_price_list.called, '_get_vnf_price_list not called as expected')
self.assertTrue(mock_get_pil_info.called, '_get_pil_info not called as expected')
self.assertTrue(mock__get_nslcmop.called, '_get_nslcmop not called as expected')
@mock.patch.object(Server, '_get_nslcmop')
@mock.patch.object(Server, '_get_vnf_price_list')
@mock.patch.object(Server, '_get_pil_info')
- def test_get_placement_with_pinning(self, mock_get_pil_info, mock_get_vnf_price_list, mock__get_nslcmop,
+ @mock.patch.object(Server, '_get_projects')
+ def test_get_placement_with_pinning(self, mock_get_projects, mock_get_pil_info, mock_get_vnf_price_list,
+ mock__get_nslcmop,
mock__get_nsd, mock__get_vim_accounts,
mock_create_ns_placement_data,
mock_do_placement_computation):
mock_do_placement_computation.return_value = placement_ret_val
_run(server.get_placement(nslcmop_record_w_pinning['id']))
+ self.assertTrue((mock_get_projects.called, '_get_projects not called as expected'))
self.assertTrue(mock_get_vnf_price_list.called, '_get_vnf_price_list not called as expected')
self.assertTrue(mock_get_pil_info.called, '_get_pil_info not called as expected')
self.assertTrue(mock__get_nslcmop.called, '_get_nslcmop not called as expected')
--- /dev/null
+# Copyright 2020 ArctosLabs Scandinavia AB
+#
+# 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.
+- vnfd: cirros_vnfd_v2
+ hackfest_project_a:
+ - prices:
+ - vim_url: http://10.234.12.47:5000/v3
+ vim_name: OpenStack1
+ price: 5
+ - vim_url: http://10.234.12.44:5000/v3
+ vim_name: OpenStack2
+ price: 10
+ - vim_url: http://10.234.12.46:5000/v3
+ vim_name: OpenStack3
+ price: 30
+ - vim_url: http://10.234.12.43:5000/v3
+ vim_name: OpenStack4
+ price: 30
+ hackfest_project_b:
+ - prices:
+ - vim_url: http://10.234.12.47:5000/v3
+ vim_name: OpenStack1
+ price: 5
+ - vim_url: http://10.234.12.44:5000/v3
+ vim_name: OpenStack2
+ price: 10
+ - vim_url: http://10.234.12.46:5000/v3
+ vim_name: OpenStack3
+ price: 30
+ - vim_url: http://10.234.12.43:5000/v3
+ vim_name: OpenStack4
+ price: 30
+- vnfd: hackfest_multivdu-vnf
+ hackfest_project_a:
+ prices:
+ - vim_url: http://10.234.12.47:5000/v3
+ vim_name: OpenStack1
+ price: 17
+ - vim_url: http://10.234.12.44:5000/v3
+ vim_name: OpenStack2
+ price: 18
+ - vim_url: http://10.234.12.46:5000/v3
+ vim_name: OpenStack3
+ price: 19
+ - vim_url: http://10.234.12.43:5000/v3
+ vim_name: OpenStack4
+ price: 20
+- vnfd: test_one_a_vnfd
+ hackfest_project_a:
+ prices:
+ - vim_url: http://10.234.12.47:5000/v3
+ vim_name: OpenStack1
+ price: 10
+ - vim_url: http://10.234.12.44:5000/v3
+ vim_name: OpenStack2
+ price: 20
+ - vim_url: http://10.234.12.46:5000/v3
+ vim_name: OpenStack3
+ price: 30
+ - vim_url: http://10.234.12.43:5000/v3
+ vim_name: OpenStack4
+ price: 30
+- vnfd: test_one_b_vnfd
+ hackfest_project_a:
+ prices:
+ - vim_url: http://10.234.12.47:5000/v3
+ vim_name: OpenStack1
+ price: 10
+ - vim_url: http://10.234.12.44:5000/v3
+ vim_name: OpenStack2
+ price: 20
+ - vim_url: http://10.234.12.46:5000/v3
+ vim_name: OpenStack3
+ price: 30
+ - vim_url: http://10.234.12.43:5000/v3
+ vim_name: OpenStack4
+ price: 30
+- vnfd: test_one_c_vnfd
+ hackfest_project_a:
+ prices:
+ - vim_url: http://10.234.12.47:5000/v3
+ vim_name: OpenStack1
+ price: 10
+ - vim_url: http://10.234.12.44:5000/v3
+ vim_name: OpenStack2
+ price: 20
+ - vim_url: http://10.234.12.46:5000/v3
+ vim_name: OpenStack3
+ price: 30
+ - vim_url: http://10.234.12.43:5000/v3
+ vim_name: OpenStack4
+ price: 30
def parse_requirements(requirements):
with open(requirements) as f:
- return [l.strip('\n') for l in f if l.strip('\n') and not l.startswith('#') and '://' not in l]
+ return [req.strip('\n') for req in f if req.strip('\n') and not req.startswith('#') and '://' not in req]
_name = 'osm_pla'