Use tags instead of role names

Role names can be customized, yet in THT jinja2 we
have several places where conditions are based on
the role name. By using tag's such as 'storage',
'ceph' and 'ovsdpdk' we the role names become truly
customizable.

The depends-on change in TripleO common will
dynamically add tag's to role's based on role.name
for backward compatibility during deprecation
period.

Depends-On: https://review.opendev.org/758124
Change-Id: I5ab4e4a220294245f95d328391bfffec87781a09
This commit is contained in:
Harald Jensås 2020-10-12 12:56:24 +02:00 committed by Rabi Mishra
parent e9da1a2a71
commit ff4d1fbb66
43 changed files with 161 additions and 14 deletions

View File

@ -92,7 +92,7 @@ parameters:
interface. Set things like lacp=active and/or bond_mode=balance-slb interface. Set things like lacp=active and/or bond_mode=balance-slb
for OVS bonds or like mode=4 for Linux bonds using this option.' for OVS bonds or like mode=4 for Linux bonds using this option.'
type: string type: string
{%- if role.name == 'ComputeOvsDpdk' %} {%- if 'ovsdpdk' in role.tags %}
NumDpdkInterfaceRxQueues: NumDpdkInterfaceRxQueues:
description: Number of Rx Queues required for DPDK bond or DPDK ports description: Number of Rx Queues required for DPDK bond or DPDK ports
default: 1 default: 1
@ -191,7 +191,7 @@ resources:
routes: routes:
get_param: {{network.name}}InterfaceRoutes get_param: {{network.name}}InterfaceRoutes
{%- endfor %} {%- endfor %}
{%- if not role.name.startswith('ComputeOvsDpdk') %} {%- if not 'ovsdpdk' in role.tags %}
- type: ovs_bridge - type: ovs_bridge
name: {get_param: NeutronPhysicalBridge} name: {get_param: NeutronPhysicalBridge}
dns_servers: dns_servers:

View File

@ -89,7 +89,7 @@ parameters:
interface. Set things like lacp=active and/or bond_mode=balance-slb interface. Set things like lacp=active and/or bond_mode=balance-slb
for OVS bonds or like mode=4 for Linux bonds using this option.' for OVS bonds or like mode=4 for Linux bonds using this option.'
type: string type: string
{%- if role.name == 'ComputeOvsDpdk' %} {%- if 'ovsdpdk' in role.tags %}
NumDpdkInterfaceRxQueues: NumDpdkInterfaceRxQueues:
description: Number of Rx Queues required for DPDK bond or DPDK ports description: Number of Rx Queues required for DPDK bond or DPDK ports
default: 1 default: 1
@ -137,9 +137,9 @@ resources:
- get_param: ControlPlaneSubnetCidr - get_param: ControlPlaneSubnetCidr
routes: routes:
get_param: ControlPlaneStaticRoutes get_param: ControlPlaneStaticRoutes
{%- if not role.name.startswith('ComputeOvsDpdk') %} {%- if not 'ovsdpdk' in role.tags %}
- type: ovs_bridge - type: ovs_bridge
{%- if role.name.startswith('CephStorage') or role.name.startswith('ObjectStorage') or role.name.startswith('BlockStorage') %} {%- if 'ceph' in role.tags or 'storage' in role.tags %}
name: br-bond name: br-bond
{%- else %} {%- else %}
name: {get_param: NeutronPhysicalBridge} name: {get_param: NeutronPhysicalBridge}

View File

@ -93,7 +93,7 @@ parameters:
default: [] default: []
description: A list of DNS search domains to be added (in order) to resolv.conf. description: A list of DNS search domains to be added (in order) to resolv.conf.
type: comma_delimited_list type: comma_delimited_list
{%- if role.name == 'ComputeOvsDpdk' %} {%- if 'ovsdpdk' in role.tags %}
NumDpdkInterfaceRxQueues: NumDpdkInterfaceRxQueues:
description: Number of Rx Queues required for DPDK bond or DPDK ports description: Number of Rx Queues required for DPDK bond or DPDK ports
default: 1 default: 1
@ -184,7 +184,7 @@ resources:
{#- This hack gets around Jinja scope limitations to update nics_used within loop. #} {#- This hack gets around Jinja scope limitations to update nics_used within loop. #}
{%- set _ = nics_used.append(loop.index) %} {%- set _ = nics_used.append(loop.index) %}
{%- endfor %} {%- endfor %}
{%- if role.name == 'ComputeOvsDpdk' %} {%- if 'ovsdpdk' in role.tags %}
# Used as a provider network with external DHCP # Used as a provider network with external DHCP
- type: ovs_user_bridge - type: ovs_user_bridge
name: br-dpdk0 name: br-dpdk0

View File

@ -93,7 +93,7 @@ parameters:
default: [] default: []
description: A list of DNS search domains to be added (in order) to resolv.conf. description: A list of DNS search domains to be added (in order) to resolv.conf.
type: comma_delimited_list type: comma_delimited_list
{%- if role.name == 'ComputeOvsDpdk' %} {%- if 'ovsdpdk' in role.tags %}
NumDpdkInterfaceRxQueues: NumDpdkInterfaceRxQueues:
description: Number of Rx Queues required for DPDK bond or DPDK ports description: Number of Rx Queues required for DPDK bond or DPDK ports
default: 1 default: 1
@ -173,7 +173,7 @@ resources:
{#- This hack gets around Jinja scope limitations to update nics_used within loop. #} {#- This hack gets around Jinja scope limitations to update nics_used within loop. #}
{%- set _ = nics_used.append(loop.index) %} {%- set _ = nics_used.append(loop.index) %}
{%- endfor %} {%- endfor %}
{%- if role.name == 'ComputeOvsDpdk' %} {%- if 'ovsdpdk' in role.tags %}
# Used as a provider network with external DHCP # Used as a provider network with external DHCP
- type: ovs_user_bridge - type: ovs_user_bridge
name: br-dpdk0 name: br-dpdk0

View File

@ -117,7 +117,7 @@ resources:
value: value:
network_config: network_config:
- type: linux_bridge - type: linux_bridge
{%- if role.name.startswith('CephStorage') or role.name.startswith('ObjectStorage') or role.name.startswith('BlockStorage') %} {%- if 'ceph' in role.tags or 'storage' in role.tags %}
name: br-storage name: br-storage
{%- else %} {%- else %}
name: {get_param: NeutronPhysicalBridge} name: {get_param: NeutronPhysicalBridge}
@ -150,7 +150,7 @@ and network.name not in role.networks_skip_config|default([]) %}
get_param: {{network.name}}Mtu get_param: {{network.name}}Mtu
vlan_id: vlan_id:
get_param: {{network.name}}NetworkVlanID get_param: {{network.name}}NetworkVlanID
{%- if role.name.startswith('CephStorage') or role.name.startswith('ObjectStorage') or role.name.startswith('BlockStorage') %} {%- if 'ceph' in role.tags or 'storage' in role.tags %}
device: br-storage device: br-storage
{%- else %} {%- else %}
device: {get_param: NeutronPhysicalBridge} device: {get_param: NeutronPhysicalBridge}

View File

@ -113,7 +113,7 @@ resources:
value: value:
network_config: network_config:
- type: ovs_bridge - type: ovs_bridge
{%- if role.name.startswith('CephStorage') or role.name.startswith('ObjectStorage') or role.name.startswith('BlockStorage') %} {%- if 'ceph' in role.tags or 'storage' in role.tags %}
name: br-storage name: br-storage
{%- else %} {%- else %}
name: {get_param: NeutronPhysicalBridge} name: {get_param: NeutronPhysicalBridge}

View File

@ -93,7 +93,7 @@ parameters:
# We special-case the default ResolveNetwork and MetricsQdrNetwork for the Ceph roles # We special-case the default ResolveNetwork and MetricsQdrNetwork for the Ceph roles
# for backwards compatibility, all other roles default to internal_api # for backwards compatibility, all other roles default to internal_api
{%- for role in roles %} {%- for role in roles %}
{%- if role.name.startswith('Ceph') %} {%- if 'ceph' in role.tags|default([]) %}
{%- if 'Storage' in role.networks %} {%- if 'Storage' in role.networks %}
{{role.name}}HostnameResolveNetwork: {{ _service_nets.get('storage', 'ctlplane') }} {{role.name}}HostnameResolveNetwork: {{ _service_nets.get('storage', 'ctlplane') }}
{{role.name}}MetricsQdrNetwork: {{ _service_nets.get('storage', 'ctlplane') }} {{role.name}}MetricsQdrNetwork: {{ _service_nets.get('storage', 'ctlplane') }}

View File

@ -0,0 +1,22 @@
---
upgrade:
- |
Use of the role name in jinja2 tripleo heat templates has been replaced with
the use of role tags. Users of custom role data should update the tags for
their custom roles data file adding the relevant tags. The following tag
should be added, depending on the role:
* **Compute** roles: add the ``compute`` tag.
* **HciCeph** roles: add the ``compute`` tag.
* **DistributedCompute** roles: add the ``compute`` tag.
* **Ceph** roles: add the ``ceph`` and ``storage`` tag.
* **ObjectStorage** roles: add the ``storage`` tag.
* **BlockStorage** roles: add the ``storage`` tag.
* **ComputeOvsDpdk** roles: add the ``ovsdpdk`` tag.
deprecations:
- |
Use of the role name in jinja2 tripleo heat templates has been replaced
with the use of role tags. By using tags the role name become truly
customizable. To keep backward compatiblity tags will be added
automatically to roles based on the role name until the next release.

View File

@ -4,6 +4,8 @@
- name: BlockStorage - name: BlockStorage
description: | description: |
Cinder Block Storage node role Cinder Block Storage node role
tags:
- storage
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -4,6 +4,9 @@
- name: CephAll - name: CephAll
description: | description: |
Standalone Storage Full Role (OSD + MON + RGW + MDS + MGR + RBD Mirroring) Standalone Storage Full Role (OSD + MON + RGW + MDS + MGR + RBD Mirroring)
tags:
- ceph
- storage
networks: networks:
Storage: Storage:
subnet: storage_subnet subnet: storage_subnet

View File

@ -4,6 +4,9 @@
- name: CephFile - name: CephFile
description: | description: |
Standalone Scale-out File Role (OSD + MDS) Standalone Scale-out File Role (OSD + MDS)
tags:
- ceph
- storage
networks: networks:
Storage: Storage:
subnet: storage_subnet subnet: storage_subnet

View File

@ -4,6 +4,9 @@
- name: CephObject - name: CephObject
description: | description: |
Standalone Scale-out Object Role (OSD + RGW) Standalone Scale-out Object Role (OSD + RGW)
tags:
- ceph
- storage
networks: networks:
Storage: Storage:
subnet: storage_subnet subnet: storage_subnet

View File

@ -4,6 +4,9 @@
- name: CephStorage - name: CephStorage
description: | description: |
Ceph OSD Storage node role Ceph OSD Storage node role
tags:
- ceph
- storage
networks: networks:
Storage: Storage:
subnet: storage_subnet subnet: storage_subnet

View File

@ -7,6 +7,7 @@
CountDefault: 1 CountDefault: 1
# Create external Neutron bridge (unset if using ML2/OVS without DVR) # Create external Neutron bridge (unset if using ML2/OVS without DVR)
tags: tags:
- compute
- external_bridge - external_bridge
networks: networks:
InternalApi: InternalApi:

View File

@ -5,6 +5,8 @@
description: | description: |
Alternate Compute Node role Alternate Compute Node role
CountDefault: 0 CountDefault: 0
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -6,6 +6,7 @@
DVR enabled Compute Node role DVR enabled Compute Node role
CountDefault: 1 CountDefault: 1
tags: tags:
- compute
- external_bridge - external_bridge
networks: networks:
InternalApi: InternalApi:

View File

@ -4,6 +4,8 @@
- name: ComputeHCI - name: ComputeHCI
description: | description: |
Compute Node role hosting Ceph OSD too Compute Node role hosting Ceph OSD too
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -4,6 +4,9 @@
- name: ComputeHCIOvsDpdk - name: ComputeHCIOvsDpdk
description: | description: |
ComputeOvsDpdk Node role hosting Ceph OSD too ComputeOvsDpdk Node role hosting Ceph OSD too
tags:
- compute
- dpdk
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -4,6 +4,8 @@
- name: ComputeHCISriov - name: ComputeHCISriov
description: | description: |
Compute Node with SR-IOV role hosting Ceph OSD too Compute Node with SR-IOV role hosting Ceph OSD too
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -5,6 +5,8 @@
description: | description: |
Compute Instance HA Node role to be used with -e environments/compute-instanceha.yaml Compute Instance HA Node role to be used with -e environments/compute-instanceha.yaml
CountDefault: 1 CountDefault: 1
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -5,6 +5,8 @@
description: | description: |
Compute Node with Cavium Liquidio smart NIC Compute Node with Cavium Liquidio smart NIC
CountDefault: 1 CountDefault: 1
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -7,6 +7,7 @@
CountDefault: 0 CountDefault: 0
# Create external Neutron bridge (unset if using ML2/OVS without DVR) # Create external Neutron bridge (unset if using ML2/OVS without DVR)
tags: tags:
- compute
- external_bridge - external_bridge
networks: networks:
InternalApi: InternalApi:

View File

@ -5,6 +5,9 @@
description: | description: |
Compute OvS DPDK Role Compute OvS DPDK Role
CountDefault: 1 CountDefault: 1
tags:
- compute
- dpdk
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -5,6 +5,9 @@
description: | description: |
Compute OvS DPDK RealTime Role Compute OvS DPDK RealTime Role
CountDefault: 1 CountDefault: 1
tags:
- compute
- dpdk
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -5,6 +5,9 @@
description: | description: |
Compute role with OvS-DPDK and SR-IOV services Compute role with OvS-DPDK and SR-IOV services
CountDefault: 1 CountDefault: 1
tags:
- compute
- dpdk
networks: networks:
- InternalApi - InternalApi
- Tenant - Tenant

View File

@ -5,6 +5,9 @@
description: | description: |
Compute Realtime role with OvS-DPDK and SR-IOV services Compute Realtime role with OvS-DPDK and SR-IOV services
CountDefault: 1 CountDefault: 1
tags:
- compute
- dpdk
networks: networks:
- InternalApi - InternalApi
- Tenant - Tenant

View File

@ -5,6 +5,8 @@
description: | description: |
Basic Compute Node role for ppc64le servers Basic Compute Node role for ppc64le servers
CountDefault: 0 CountDefault: 0
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -7,6 +7,7 @@
CountDefault: 0 CountDefault: 0
# Create external Neutron bridge (unset if using ML2/OVS without DVR) # Create external Neutron bridge (unset if using ML2/OVS without DVR)
tags: tags:
- compute
- external_bridge - external_bridge
networks: networks:
InternalApi: InternalApi:

View File

@ -9,6 +9,8 @@
and NovaComputeCpuSharedSet are set according to the hardware of the and NovaComputeCpuSharedSet are set according to the hardware of the
real-time compute nodes. real-time compute nodes.
CountDefault: 1 CountDefault: 1
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -5,6 +5,8 @@
description: | description: |
Compute SR-IOV Role Compute SR-IOV Role
CountDefault: 1 CountDefault: 1
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -5,6 +5,8 @@
description: | description: |
Compute SR-IOV Infiniband Role Compute SR-IOV Infiniband Role
CountDefault: 1 CountDefault: 1
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -5,6 +5,8 @@
description: | description: |
Compute SR-IOV RealTime Role Compute SR-IOV RealTime Role
CountDefault: 1 CountDefault: 1
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -5,6 +5,8 @@
description: | description: |
Distributed Compute Node role with Glance. Distributed Compute Node role with Glance.
CountDefault: 1 CountDefault: 1
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -4,6 +4,8 @@
- name: DistributedComputeHCI - name: DistributedComputeHCI
description: | description: |
Distributed Compute Node role with Ceph, Cinder volume, and Glance. Distributed Compute Node role with Ceph, Cinder volume, and Glance.
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -4,6 +4,8 @@
- name: DistributedComputeHCIScaleOut - name: DistributedComputeHCIScaleOut
description: | description: |
Distributed Compute Node role with CephOSD and HAproxy for Glance. Distributed Compute Node role with CephOSD and HAproxy for Glance.
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -5,6 +5,8 @@
description: | description: |
Distributed Compute Node role with HAproxy for Glance. Distributed Compute Node role with HAproxy for Glance.
CountDefault: 1 CountDefault: 1
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -4,6 +4,8 @@
- name: HciCephAll - name: HciCephAll
description: | description: |
HCI Full Stack Role (OSD + MON + Nova + RGW + MDS + MGR + RBD Mirroring + Dashboard) HCI Full Stack Role (OSD + MON + Nova + RGW + MDS + MGR + RBD Mirroring + Dashboard)
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -4,6 +4,8 @@
- name: HciCephFile - name: HciCephFile
description: | description: |
HCI Scale-out File Role (OSD + Nova + MDS) HCI Scale-out File Role (OSD + Nova + MDS)
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -4,6 +4,8 @@
- name: HciCephMon - name: HciCephMon
description: | description: |
HCI Scale-out Block Full Role (OSD + MON + MGR + Nova) HCI Scale-out Block Full Role (OSD + MON + MGR + Nova)
tags:
- compute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -4,6 +4,8 @@
- name: HciCephObject - name: HciCephObject
description: | description: |
HCI Scale-out Object Role (OSD + Nova + RGW) HCI Scale-out Object Role (OSD + Nova + RGW)
tags:
- computecompute
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -4,6 +4,8 @@
- name: ObjectStorage - name: ObjectStorage
description: | description: |
Swift Object Storage node role Swift Object Storage node role
tags:
- storage
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet

View File

@ -196,6 +196,7 @@
CountDefault: 1 CountDefault: 1
# Create external Neutron bridge (unset if using ML2/OVS without DVR) # Create external Neutron bridge (unset if using ML2/OVS without DVR)
tags: tags:
- compute
- external_bridge - external_bridge
networks: networks:
InternalApi: InternalApi:
@ -273,6 +274,8 @@
- name: BlockStorage - name: BlockStorage
description: | description: |
Cinder Block Storage node role Cinder Block Storage node role
tags:
- storage
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet
@ -320,6 +323,8 @@
- name: ObjectStorage - name: ObjectStorage
description: | description: |
Swift Object Storage node role Swift Object Storage node role
tags:
- storage
networks: networks:
InternalApi: InternalApi:
subnet: internal_api_subnet subnet: internal_api_subnet
@ -374,6 +379,9 @@
- name: CephStorage - name: CephStorage
description: | description: |
Ceph OSD Storage node role Ceph OSD Storage node role
tags:
- ceph
- storage
networks: networks:
Storage: Storage:
subnet: storage_subnet subnet: storage_subnet

View File

@ -106,6 +106,47 @@ def _j2_render_to_file(j2_template, j2_data, outfile_name=None,
out_f.write(r_template) out_f.write(r_template)
def _set_tags_based_on_role_name(role_data):
for role in role_data:
role['tags'] = role.get('tags', [])
role_name = role.get('name', str())
if ((role_name.startswith('Compute') or role_name.startswith('HciCeph')
or role_name.startswith('DistributedCompute'))
and 'compute' not in role['tags']):
role['tags'].append('compute')
print("DEPRECATED: Role '%s' without the 'compute' tag "
"detected, the tag was added automatically. Please "
"add the 'compute' tag in roles data. The function to "
"automatically add tags based on role name will be "
"removed in the next release." % role_name)
if role_name.startswith('Ceph') and 'ceph' not in role['tags']:
role['tags'].append('ceph')
print("DEPRECATED: Role '%s' without the 'ceph' tag "
"detected, the tag was added automatically. Please "
"add the 'ceph' tag in roles data. The function to "
"automatically add tags based on role name will be "
"removed in the next release." % role_name)
if (role_name.startswith('ComputeOvsDpdk')
and 'ovsdpdk' not in role['tags']):
role['tags'].append('ovsdpdk')
print("DEPRECATED: Role '%s' without the 'ovsdpdk' tag "
"detected, the tag was added automatically. Please "
"add the 'ovsdpdk' tag in roles data. The function to "
"automatically add tags based on role name will be "
"removed in the next release." % role_name)
if ((role_name.startswith('ObjectStorage')
or role_name.startswith('BlockStorage')
or role_name.startswith('Ceph'))
and 'storage' not in role['tags']):
role['tags'].append('storage')
print("DEPRECATED: Role '%s' without the 'storage' tag "
"detected, the tag was added automatically. Please "
"add the 'storage' tag in roles data. The function to "
"automatically add tags based on role name will be "
"removed in the next release." % role_name)
def process_templates(template_path, role_data_path, output_dir, def process_templates(template_path, role_data_path, output_dir,
network_data_path, overwrite, dry_run): network_data_path, overwrite, dry_run):
@ -128,6 +169,10 @@ def process_templates(template_path, role_data_path, output_dir,
raise RuntimeError('Output dir %s is not a directory' % output_dir) raise RuntimeError('Output dir %s is not a directory' % output_dir)
os.mkdir(output_dir) os.mkdir(output_dir)
# TODO(hjensas): In next release remove the function to automatically add
# tags based on role name.
_set_tags_based_on_role_name(role_data)
role_names = [r.get('name') for r in role_data] role_names = [r.get('name') for r in role_data]
r_map = {} r_map = {}
for r in role_data: for r in role_data:
@ -204,7 +249,8 @@ def process_templates(template_path, role_data_path, output_dir,
'.yaml')]) '.yaml')])
out_f_path = os.path.join(out_dir, out_f) out_f_path = os.path.join(out_dir, out_f)
if ('network/config' in file_path and if ('network/config' in file_path and
r_map[role].get('deprecated_nic_config_name')): r_map[role].get(
'deprecated_nic_config_name')):
d_name = r_map[role].get( d_name = r_map[role].get(
'deprecated_nic_config_name') 'deprecated_nic_config_name')
out_f_path = os.path.join(out_dir, d_name) out_f_path = os.path.join(out_dir, d_name)