Add toggle to recreate Cinder volumes in v1 Heal
Extend v1 Heal to accept an optional additionalParams key that toggles recreation of Cinder volumes. Add two [vnf_lcm] options in tacker.conf: - heal_vnfc_block_storage: default when the request omits the key - heal_include_block_storage_key: key name in additionalParams If neither is set, existing behavior is unchanged. Implements: blueprint v1-heal-cinder-volume Change-Id: I29ca4dceac40d3d0fe1fcb1f6bf4c4f1729e883b Signed-off-by: Hitomi Koba <hi-koba@kddi.com>
This commit is contained in:
@@ -702,6 +702,14 @@ grant_id:
|
|||||||
in: body
|
in: body
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
heal_additional_params:
|
||||||
|
description: |
|
||||||
|
Additional parameters passed by the NFVO as input to the healing process,
|
||||||
|
specific to the VNF being healed, as declared in the VNFD as part of
|
||||||
|
"HealVnfOpConfig".
|
||||||
|
in: body
|
||||||
|
required: false
|
||||||
|
type: key value pairs
|
||||||
instantiated_vnf_info:
|
instantiated_vnf_info:
|
||||||
description: |
|
description: |
|
||||||
Information specific to an instantiated VNF instance. This attribute shall
|
Information specific to an instantiated VNF instance. This attribute shall
|
||||||
@@ -985,6 +993,23 @@ subscription_id_response:
|
|||||||
in: body
|
in: body
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
tacker_extension_heal_include_block_storage:
|
||||||
|
description: |
|
||||||
|
** Admin-configurable parameter name. **
|
||||||
|
Controls whether related Cinder block storage is recreated when
|
||||||
|
healing specified VNFC instance(s).
|
||||||
|
|
||||||
|
The key name is configured by ``[vnf_lcm] heal_include_block_storage_key``
|
||||||
|
in ``tacker.conf`` (default: ``tacker_extension_heal_include_block_storage``).
|
||||||
|
If the key is omitted, the default behavior is controlled by
|
||||||
|
``[vnf_lcm] heal_vnfc_block_storage``.
|
||||||
|
|
||||||
|
**Recommendation:** Because both the key name and the default behavior
|
||||||
|
depend on your deployment settings, it is recommended to confirm them
|
||||||
|
with your environment administrator.
|
||||||
|
in: body
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
termination_type:
|
termination_type:
|
||||||
description: |
|
description: |
|
||||||
Indicates whether forceful or graceful termination is requested.
|
Indicates whether forceful or graceful termination is requested.
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
{
|
{
|
||||||
"cause": "healing",
|
"cause": "healing",
|
||||||
"vnfcInstanceId": ["c51c98dc-b918-4681-a9eb-4f32a57c4e08"]
|
"vnfcInstanceId": ["c51c98dc-b918-4681-a9eb-4f32a57c4e08"],
|
||||||
|
"additionalParams": {
|
||||||
|
"tacker_extension_heal_include_block_storage": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -229,6 +229,8 @@ Request Parameters
|
|||||||
- vnfInstanceId: vnf_instance_id
|
- vnfInstanceId: vnf_instance_id
|
||||||
- cause: cause
|
- cause: cause
|
||||||
- vnfcInstanceId: vnfc_resource_info_ids
|
- vnfcInstanceId: vnfc_resource_info_ids
|
||||||
|
- additionalParams: heal_additional_params
|
||||||
|
- tacker_extension_heal_include_block_storage: tacker_extension_heal_include_block_storage
|
||||||
|
|
||||||
|
|
||||||
Request Example
|
Request Example
|
||||||
|
|||||||
@@ -733,8 +733,14 @@ VDU1 information before healing:
|
|||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ openstack stack resource show HEAT_STACK_ID \
|
$ openstack stack resource show HEAT_STACK_ID VDU1_SERVER_NAME \
|
||||||
VDU_NAME -c physical_resource_id -c resource_status
|
-c physical_resource_id -c resource_name -c resource_status -c resource_type
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ openstack stack resource show HEAT_STACK_ID VDU1_VOLUME_NAME \
|
||||||
|
-c physical_resource_id -c resource_name -c resource_status -c resource_type
|
||||||
|
|
||||||
|
|
||||||
Result:
|
Result:
|
||||||
@@ -744,17 +750,75 @@ Result:
|
|||||||
+----------------------+--------------------------------------+
|
+----------------------+--------------------------------------+
|
||||||
| Field | Value |
|
| Field | Value |
|
||||||
+----------------------+--------------------------------------+
|
+----------------------+--------------------------------------+
|
||||||
| physical_resource_id | 6b89f9c9-ebd8-49ca-8e2c-c01838daeb95 |
|
| physical_resource_id | ed781426-c59d-4c32-8bc3-e26144167220 |
|
||||||
|
| resource_name | VDU1 |
|
||||||
| resource_status | CREATE_COMPLETE |
|
| resource_status | CREATE_COMPLETE |
|
||||||
|
| resource_type | OS::Nova::Server |
|
||||||
+----------------------+--------------------------------------+
|
+----------------------+--------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
+----------------------+--------------------------------------+
|
||||||
|
| Field | Value |
|
||||||
|
+----------------------+--------------------------------------+
|
||||||
|
| physical_resource_id | 2d4715e6-1e0e-449e-91b5-a6c162adbb39 |
|
||||||
|
| resource_name | VDU1-VirtualStorage |
|
||||||
|
| resource_status | CREATE_COMPLETE |
|
||||||
|
| resource_type | OS::Cinder::Volume |
|
||||||
|
+----------------------+--------------------------------------+
|
||||||
|
|
||||||
|
Heal Specified with VNFC Instances can control whether related Cinder
|
||||||
|
block storage is recreated for the healed VNFC(s).
|
||||||
|
|
||||||
|
This is done via an optional key inside ``additionalParams`` in the Heal
|
||||||
|
request. The key name is operator-configurable, and when the request
|
||||||
|
omits the key, a configurable default is applied [Conf-Options_].
|
||||||
|
|
||||||
|
* **Request key (configurable)**:
|
||||||
|
the key to read from ``additionalParams`` is configured by
|
||||||
|
``[vnf_lcm] heal_include_block_storage_key`` on the VNFM.
|
||||||
|
By default it is ``tacker_extension_heal_include_block_storage``.
|
||||||
|
* **Default behavior (configurable)**:
|
||||||
|
when the request does not include the key, the behavior is decided by
|
||||||
|
``[vnf_lcm] heal_vnfc_block_storage``.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
The default behavior (when the key is not provided) and the key name
|
||||||
|
itself depend on ``tacker.conf``. If you are unsure, contact your
|
||||||
|
environment administrator.
|
||||||
|
|
||||||
|
In the examples below, the parameter name is shown as
|
||||||
|
``tacker_extension_heal_include_block_storage``.
|
||||||
|
|
||||||
|
*Example: recreate storage (boolean true)*
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"additionalParams": {
|
||||||
|
"tacker_extension_heal_include_block_storage": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*Example: do not recreate storage (boolean false)*
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"additionalParams": {
|
||||||
|
"tacker_extension_heal_include_block_storage": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Healing execution of VDU1:
|
Healing execution of VDU1:
|
||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ openstack vnflcm heal VNF_INSTANCE_ID --vnfc-instance VNFC_INSTANCE_ID
|
$ openstack vnflcm heal VNF_INSTANCE_ID --vnfc-instance VNFC_INSTANCE_ID \
|
||||||
|
--additional-param-file heal-params.json \
|
||||||
|
|
||||||
Result:
|
Result:
|
||||||
|
|
||||||
@@ -772,8 +836,14 @@ VDU1 information after healing:
|
|||||||
|
|
||||||
.. code-block:: console
|
.. code-block:: console
|
||||||
|
|
||||||
$ openstack stack resource show HEAT_STACK_ID \
|
$ openstack stack resource show HEAT_STACK_ID VDU1_SERVER_NAME \
|
||||||
VDU_NAME -c physical_resource_id -c resource_status
|
-c physical_resource_id -c resource_name -c resource_status -c resource_type
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ openstack stack resource show HEAT_STACK_ID VDU1_VOLUME_NAME \
|
||||||
|
-c physical_resource_id -c resource_name -c resource_status -c resource_type
|
||||||
|
|
||||||
|
|
||||||
Result:
|
Result:
|
||||||
@@ -783,11 +853,39 @@ Result:
|
|||||||
+----------------------+--------------------------------------+
|
+----------------------+--------------------------------------+
|
||||||
| Field | Value |
|
| Field | Value |
|
||||||
+----------------------+--------------------------------------+
|
+----------------------+--------------------------------------+
|
||||||
| physical_resource_id | 6b89f9c9-ebd8-49ca-8e2c-c01838daeb95 |
|
| physical_resource_id | ed781426-c59d-4c32-8bc3-e26144167220 |
|
||||||
|
| resource_name | VDU1 |
|
||||||
| resource_status | UPDATE_COMPLETE |
|
| resource_status | UPDATE_COMPLETE |
|
||||||
|
| resource_type | OS::Nova::Server |
|
||||||
+----------------------+--------------------------------------+
|
+----------------------+--------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
*recreate storage*
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
+----------------------+--------------------------------------+
|
||||||
|
| Field | Value |
|
||||||
|
+----------------------+--------------------------------------+
|
||||||
|
| physical_resource_id | 2d4715e6-1e0e-449e-91b5-a6c162adbb39 |
|
||||||
|
| resource_name | VDU1-VirtualStorage |
|
||||||
|
| resource_status | UPDATE_COMPLETE |
|
||||||
|
| resource_type | OS::Cinder::Volume |
|
||||||
|
+----------------------+--------------------------------------+
|
||||||
|
|
||||||
|
*do not recreate storage*
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
+----------------------+--------------------------------------+
|
||||||
|
| Field | Value |
|
||||||
|
+----------------------+--------------------------------------+
|
||||||
|
| physical_resource_id | 2d4715e6-1e0e-449e-91b5-a6c162adbb39 |
|
||||||
|
| resource_name | VDU1-VirtualStorage |
|
||||||
|
| resource_status | CREATE_COMPLETE |
|
||||||
|
| resource_type | OS::Cinder::Volume |
|
||||||
|
+----------------------+--------------------------------------+
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
'physical_resource_id' has not changed from the ID before healing.
|
'physical_resource_id' has not changed from the ID before healing.
|
||||||
@@ -797,3 +895,4 @@ Result:
|
|||||||
.. _NFV-SOL002 v2.6.1 : https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/002/02.06.01_60/gs_NFV-SOL002v020601p.pdf
|
.. _NFV-SOL002 v2.6.1 : https://www.etsi.org/deliver/etsi_gs/NFV-SOL/001_099/002/02.06.01_60/gs_NFV-SOL002v020601p.pdf
|
||||||
.. _Heat API reference : https://docs.openstack.org/api-ref/orchestration/v1/index.html
|
.. _Heat API reference : https://docs.openstack.org/api-ref/orchestration/v1/index.html
|
||||||
.. _Heat CLI reference : https://docs.openstack.org/python-openstackclient/latest/cli/plugin-commands/heat.html
|
.. _Heat CLI reference : https://docs.openstack.org/python-openstackclient/latest/cli/plugin-commands/heat.html
|
||||||
|
.. _Conf-Options : https://docs.openstack.org/tacker/latest/configuration/config.html#vnf-lcm
|
||||||
|
|||||||
@@ -20,6 +20,33 @@ OPTS = [
|
|||||||
'endpoint_url',
|
'endpoint_url',
|
||||||
default='http://localhost:9890/',
|
default='http://localhost:9890/',
|
||||||
help="endpoint_url"),
|
help="endpoint_url"),
|
||||||
|
cfg.StrOpt(
|
||||||
|
'heal_include_block_storage_key',
|
||||||
|
default='tacker_extension_heal_include_block_storage',
|
||||||
|
help="""
|
||||||
|
Name of the boolean key in ``additionalParams`` that toggles including
|
||||||
|
block storage for a v1 heal request.
|
||||||
|
|
||||||
|
Example payload::
|
||||||
|
|
||||||
|
{
|
||||||
|
"additionalParams": {
|
||||||
|
"tacker_extension_heal_include_block_storage": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""),
|
||||||
|
cfg.BoolOpt(
|
||||||
|
'heal_vnfc_block_storage',
|
||||||
|
default=True,
|
||||||
|
help="""
|
||||||
|
Default behaviour when a v1 heal request omits the per-request key.
|
||||||
|
If ``additionalParams[<heal_include_block_storage_key>]`` is present,
|
||||||
|
that value takes precedence over this option.
|
||||||
|
|
||||||
|
In ``tacker.conf`` (``[vnf_lcm]`` section)::
|
||||||
|
|
||||||
|
heal_vnfc_block_storage = false
|
||||||
|
"""),
|
||||||
cfg.IntOpt(
|
cfg.IntOpt(
|
||||||
'subscription_num',
|
'subscription_num',
|
||||||
default=100,
|
default=100,
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
# Copyright (C) 2025 KDDI
|
||||||
|
# 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 oslo_config import cfg
|
||||||
|
from oslo_config import fixture as config
|
||||||
|
from tacker.conf import vnf_lcm as vnf_lcm_conf
|
||||||
|
from tacker.objects import fields
|
||||||
|
from tacker.vnfm.infra_drivers.openstack import openstack as os_drv
|
||||||
|
from types import SimpleNamespace
|
||||||
|
import unittest
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
|
||||||
|
class TestHealStorageToggleMin(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
self.conf_fix = config.Config(cfg.CONF)
|
||||||
|
self.conf_fix.setUp()
|
||||||
|
vnf_lcm_conf.register_opts(cfg.CONF)
|
||||||
|
|
||||||
|
self.driver = os_drv.OpenStack()
|
||||||
|
self.recorded = []
|
||||||
|
|
||||||
|
hc_patch = mock.patch(
|
||||||
|
'tacker.vnfm.infra_drivers.openstack.openstack.hc.HeatClient')
|
||||||
|
self.addCleanup(hc_patch.stop)
|
||||||
|
FakeHC = hc_patch.start()
|
||||||
|
hc = FakeHC.return_value
|
||||||
|
hc.get.return_value = SimpleNamespace(stack_status='CREATE_COMPLETE')
|
||||||
|
|
||||||
|
def rec_mark_unhealthy(*, stack_id, resource_name, **_):
|
||||||
|
self.recorded.append(resource_name)
|
||||||
|
|
||||||
|
hc.resource_mark_unhealthy.side_effect = rec_mark_unhealthy
|
||||||
|
hc.update.return_value = None
|
||||||
|
|
||||||
|
mock.patch(
|
||||||
|
'tacker.vnfm.infra_drivers.openstack.openstack.vnflcm_utils.'
|
||||||
|
'get_base_nest_hot_dict',
|
||||||
|
return_value=({}, {})
|
||||||
|
).start()
|
||||||
|
mock.patch(
|
||||||
|
'tacker.vnfm.infra_drivers.openstack.openstack.vnflcm_utils.'
|
||||||
|
'get_stack_param',
|
||||||
|
return_value={}
|
||||||
|
).start()
|
||||||
|
mock.patch(
|
||||||
|
'tacker.vnfm.infra_drivers.openstack.openstack.manager.'
|
||||||
|
'TackerManager.get_service_plugins',
|
||||||
|
return_value={'VNFM': SimpleNamespace(
|
||||||
|
get_vnf=lambda *a, **k: {'vnfd_id': 'vnfd-1'})}
|
||||||
|
).start()
|
||||||
|
mock.patch(
|
||||||
|
'tacker.vnfm.infra_drivers.openstack.openstack.objects.'
|
||||||
|
'VnfLcmOpOcc.get_by_vnf_instance_id',
|
||||||
|
return_value=SimpleNamespace(
|
||||||
|
error_point=fields.ErrorPoint.PRE_VIM_CONTROL)
|
||||||
|
).start()
|
||||||
|
|
||||||
|
mock.patch.object(
|
||||||
|
os_drv.OpenStack, '_get_stack_resources',
|
||||||
|
return_value={
|
||||||
|
'stack-123': {
|
||||||
|
'VDU1': {'physical_resource_id': 'srv-001'},
|
||||||
|
'VDU1-volume': {'physical_resource_id': 'vol-001'},
|
||||||
|
'child_stack': False
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).start()
|
||||||
|
|
||||||
|
mock.patch(
|
||||||
|
'tacker.vnfm.infra_drivers.openstack.openstack.vnflcm_utils.'
|
||||||
|
'get_vnfd_dict',
|
||||||
|
return_value={
|
||||||
|
'flavours': {'flv': {}},
|
||||||
|
'topology_template': {}
|
||||||
|
}
|
||||||
|
).start()
|
||||||
|
|
||||||
|
vnfc = SimpleNamespace(
|
||||||
|
id='vnfc-1',
|
||||||
|
vdu_id='VDU1',
|
||||||
|
compute_resource=SimpleNamespace(resource_id='srv-001'),
|
||||||
|
storage_resource_ids=['s-1'],
|
||||||
|
)
|
||||||
|
vstorage = SimpleNamespace(
|
||||||
|
id='s-1',
|
||||||
|
virtual_storage_desc_id='VDU1-volume',
|
||||||
|
storage_resource=SimpleNamespace(resource_id='vol-001')
|
||||||
|
)
|
||||||
|
self.vnf_instance = SimpleNamespace(
|
||||||
|
id='vnf-1',
|
||||||
|
vnfd_id='vnfd-1',
|
||||||
|
instantiated_vnf_info=SimpleNamespace(
|
||||||
|
instance_id='stack-123',
|
||||||
|
flavour_id='flv',
|
||||||
|
vnfc_resource_info=[vnfc],
|
||||||
|
virtual_storage_resource_info=[vstorage],
|
||||||
|
additional_params=None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
from tacker.objects import vim_connection
|
||||||
|
self.vim_info = vim_connection.VimConnectionInfo(
|
||||||
|
vim_id='vim-1',
|
||||||
|
vim_type='openstack',
|
||||||
|
interface_info={},
|
||||||
|
access_info={'region': 'RegionOne'},
|
||||||
|
)
|
||||||
|
|
||||||
|
def _heal(self, *, default=None, req_val=None, custom_key=None):
|
||||||
|
if default is not None:
|
||||||
|
self.conf_fix.config(group='vnf_lcm',
|
||||||
|
heal_vnfc_block_storage=bool(default))
|
||||||
|
if custom_key is not None:
|
||||||
|
self.conf_fix.config(group='vnf_lcm',
|
||||||
|
heal_include_block_storage_key=custom_key)
|
||||||
|
key = custom_key or cfg.CONF.vnf_lcm.heal_include_block_storage_key
|
||||||
|
add_params = {} if req_val is None else {key: req_val}
|
||||||
|
heal_req = SimpleNamespace(vnfc_instance_id=['vnfc-1'],
|
||||||
|
cause=None,
|
||||||
|
additional_params=add_params)
|
||||||
|
self.recorded.clear()
|
||||||
|
self.driver.heal_vnf(None, self.vnf_instance, self.vim_info, heal_req)
|
||||||
|
return set(self.recorded)
|
||||||
|
|
||||||
|
def test_default_true_when_key_omitted(self):
|
||||||
|
marked = self._heal(default=True, req_val=None)
|
||||||
|
self.assertEqual({'VDU1', 'VDU1-volume'}, marked)
|
||||||
|
|
||||||
|
def test_default_false_when_key_omitted(self):
|
||||||
|
marked = self._heal(default=False, req_val=None)
|
||||||
|
self.assertEqual({'VDU1'}, marked)
|
||||||
|
|
||||||
|
def test_request_overrides_true(self):
|
||||||
|
marked = self._heal(default=False, req_val=True)
|
||||||
|
self.assertEqual({'VDU1', 'VDU1-volume'}, marked)
|
||||||
|
|
||||||
|
def test_request_overrides_false(self):
|
||||||
|
marked = self._heal(default=True, req_val=False)
|
||||||
|
self.assertEqual({'VDU1'}, marked)
|
||||||
|
|
||||||
|
def test_custom_key(self):
|
||||||
|
marked = self._heal(
|
||||||
|
default=False, req_val=True, custom_key='recreate_block')
|
||||||
|
self.assertEqual({'VDU1', 'VDU1-volume'}, marked)
|
||||||
@@ -54,7 +54,6 @@ from tacker.vnfm.lcm_user_data.constants import USER_DATA_TIMEOUT
|
|||||||
from tacker.vnfm.lcm_user_data import utils as user_data_utils
|
from tacker.vnfm.lcm_user_data import utils as user_data_utils
|
||||||
from toscaparser import tosca_template
|
from toscaparser import tosca_template
|
||||||
|
|
||||||
|
|
||||||
eventlet.monkey_patch(time=True)
|
eventlet.monkey_patch(time=True)
|
||||||
|
|
||||||
SCALING_GROUP_RESOURCE = "OS::Heat::AutoScalingGroup"
|
SCALING_GROUP_RESOURCE = "OS::Heat::AutoScalingGroup"
|
||||||
@@ -1495,12 +1494,15 @@ class OpenStack(abstract_driver.VnfAbstractDriver,
|
|||||||
vnfc_resource.compute_resource.resource_id}
|
vnfc_resource.compute_resource.resource_id}
|
||||||
vdu_resources.append(resource_details)
|
vdu_resources.append(resource_details)
|
||||||
|
|
||||||
# Get storage resources
|
if heal_vnf_request.additional_params.get(
|
||||||
for resource_name, resource_id in \
|
CONF.vnf_lcm.heal_include_block_storage_key,
|
||||||
_get_storage_resources(vnfc_resource):
|
CONF.vnf_lcm.heal_vnfc_block_storage):
|
||||||
resource_details = {"resource_name": resource_name,
|
# Get storage resources
|
||||||
"physical_resource_id": resource_id}
|
for resource_name, resource_id in \
|
||||||
vdu_resources.append(resource_details)
|
_get_storage_resources(vnfc_resource):
|
||||||
|
resource_details = {"resource_name": resource_name,
|
||||||
|
"physical_resource_id": resource_id}
|
||||||
|
vdu_resources.append(resource_details)
|
||||||
|
|
||||||
return vdu_resources
|
return vdu_resources
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user