Allow for usage of pre-allocated IPs for the controller nodes
authorGiulio Fidente <gfidente@redhat.com>
Wed, 9 Dec 2015 12:07:32 +0000 (13:07 +0100)
committerGiulio Fidente <gfidente@redhat.com>
Tue, 15 Dec 2015 11:44:19 +0000 (12:44 +0100)
This change adds a new *_from_pool.yaml meant to return an IP from
a list instead of allocating a Neutron port, useful to pick an IP
from a pre-defined list and making it possible to configure, for
example an external balancer in advance (or dns), with the future
IPs of the controller nodes.

The list of IPs is provided via parameter_defaults (in the
ControllerIPs struct) using ControllerIPs param.

Also some additional VipPort types are created for the *VirtualIP
resources. The VIPs were previously created using the same port
resource used by the nodes, but when deploying with an external
balancer we want the VIP resource to be nooped instead.

Change-Id: Id3d4f12235501ae77200430a2dc022f378dce336

20 files changed:
environments/external-loadbalancer-vip.yaml
environments/network-isolation.yaml
network/ports/ctlplane_vip.yaml
network/ports/external.yaml
network/ports/external_from_pool.yaml [new file with mode: 0644]
network/ports/from_service.yaml [new file with mode: 0644]
network/ports/internal_api.yaml
network/ports/internal_api_from_pool.yaml [new file with mode: 0644]
network/ports/net_vip_map_external.yaml
network/ports/noop.yaml
network/ports/storage.yaml
network/ports/storage_from_pool.yaml [new file with mode: 0644]
network/ports/storage_mgmt.yaml
network/ports/storage_mgmt_from_pool.yaml [new file with mode: 0644]
network/ports/tenant.yaml
network/ports/tenant_from_pool.yaml [new file with mode: 0644]
network/ports/vip.yaml
overcloud-resource-registry-puppet.yaml
overcloud.yaml
puppet/controller.yaml

index 47d5bd9..1cf5982 100644 (file)
@@ -1,14 +1,37 @@
 resource_registry:
   OS::TripleO::Network::Ports::NetVipMap: ../network/ports/net_vip_map_external.yaml
+  OS::TripleO::Network::Ports::ExternalVipPort: ../network/ports/noop.yaml
+  OS::TripleO::Network::Ports::InternalApiVipPort: ../network/ports/noop.yaml
+  OS::TripleO::Network::Ports::StorageVipPort: ../network/ports/noop.yaml
+  OS::TripleO::Network::Ports::StorageMgmtVipPort: ../network/ports/noop.yaml
+  OS::TripleO::Network::Ports::RedisVipPort: ../network/ports/from_service.yaml
+  OS::TripleO::Controller::Ports::ExternalPort: ../network/ports/external_from_pool.yaml
+  OS::TripleO::Controller::Ports::InternalApiPort: ../network/ports/internal_api_from_pool.yaml
+  OS::TripleO::Controller::Ports::StoragePort: ../network/ports/storage_from_pool.yaml
+  OS::TripleO::Controller::Ports::StorageMgmtPort: ../network/ports/storage_mgmt_from_pool.yaml
+  OS::TripleO::Controller::Ports::TenantPort: ../network/ports/tenant_from_pool.yaml
 
 parameter_defaults:
   # When using an external loadbalancer set the following in parameter_defaults
   # to control your VIPs (currently one per network)
   # NOTE: we will eventually move to one VIP per service
   #
-  # ControlNetworkVip:
-  # ExternalNetworkVip:
-  # InternalApiNetworkVip:
-  # StorageNetworkVip:
-  # StorageMgmtNetworkVip:
-  EnableLoadBalancer: false
\ No newline at end of file
+  ControlPlaneIP: 192.0.2.251
+  ExternalNetworkVip: 10.0.0.251
+  InternalApiNetworkVip: 172.16.2.251
+  StorageNetworkVip: 172.16.1.251
+  StorageMgmtNetworkVip: 172.16.3.251
+  ServiceVips:
+    redis: 172.16.2.252
+  ControllerIPs:
+    external:
+    - 10.0.0.253
+    internal_api:
+    - 172.16.2.253
+    storage:
+    - 172.16.1.253
+    storage_mgmt:
+    - 172.16.3.253
+    tenant:
+    - 172.16.0.253
+  EnableLoadBalancer: false
index 937931d..efe2929 100644 (file)
@@ -8,6 +8,13 @@ resource_registry:
   OS::TripleO::Network::Storage: ../network/storage.yaml
   OS::TripleO::Network::Tenant: ../network/tenant.yaml
 
+  # Port assignments for the VIPs
+  OS::TripleO::Network::Ports::ExternalVipPort: ../network/ports/external.yaml
+  OS::TripleO::Network::Ports::InternalApiVipPort: ../network/ports/internal_api.yaml
+  OS::TripleO::Network::Ports::StorageVipPort: ../network/ports/storage.yaml
+  OS::TripleO::Network::Ports::StorageMgmtVipPort: ../network/ports/storage_mgmt.yaml
+  OS::TripleO::Network::Ports::RedisVipPort: ../network/ports/vip.yaml
+
   # Port assignments for the controller role
   OS::TripleO::Controller::Ports::ExternalPort: ../network/ports/external.yaml
   OS::TripleO::Controller::Ports::InternalApiPort: ../network/ports/internal_api.yaml
@@ -33,6 +40,3 @@ resource_registry:
   OS::TripleO::BlockStorage::Ports::InternalApiPort: ../network/ports/internal_api.yaml
   OS::TripleO::BlockStorage::Ports::StoragePort: ../network/ports/storage.yaml
   OS::TripleO::BlockStorage::Ports::StorageMgmtPort: ../network/ports/storage_mgmt.yaml
-
-  # Port assignments for service virtual IPs for the controller role
-  OS::TripleO::Controller::Ports::RedisVipPort: ../network/ports/vip.yaml
index ab6b18f..7a7043b 100644 (file)
@@ -5,6 +5,10 @@ description: >
   The IP address will be chosen automatically if FixedIPs is empty.
 
 parameters:
+  ServiceName: # Here for compatibility with from_service.yaml
+    description: Name of the service to lookup
+    default: ''
+    type: string
   NetworkName:
     description: # Here for compatibility with isolated networks
     default: ctlplane
index 4180a22..7624eb9 100644 (file)
@@ -27,6 +27,12 @@ parameters:
         [{'ip_address':'1.2.3.4'}]
     default: []
     type: json
+  IPPool: # Here for compatibility with from_pool.yaml
+    default: {}
+    type: json
+  NodeIndex: # Here for compatibility with from_pool.yaml
+    default: 0
+    type: number
 
 resources:
 
diff --git a/network/ports/external_from_pool.yaml b/network/ports/external_from_pool.yaml
new file mode 100644 (file)
index 0000000..8e9dc7c
--- /dev/null
@@ -0,0 +1,45 @@
+heat_template_version: 2015-04-30
+
+description: >
+  Returns an IP from a network mapped list of IPs
+
+parameters:
+  ExternalNetName:
+    description: Name of the external network
+    default: external
+    type: string
+  PortName:
+    description: Name of the port
+    default: ''
+    type: string
+  ControlPlaneIP: # Here for compatability with noop.yaml
+    description: IP address on the control plane
+    default: ''
+    type: string
+  IPPool:
+    default: {}
+    description: A network mapped list of IPs
+    type: json
+  NodeIndex:
+    default: 0
+    description: Index of the IP to get from Pool
+    type: number
+  ExternalNetCidr:
+    default: '10.0.0.0/24'
+    description: Cidr for the external network.
+    type: string
+
+outputs:
+  ip_address:
+    description: external network IP
+    value: {get_param: [IPPool, {get_param: ExternalNetName}, {get_param: NodeIndex}]}
+  ip_subnet:
+    # FIXME: this assumes a 2 digit subnet CIDR (need more heat functions?)
+    description: IP/Subnet CIDR for the external network IP
+    value:
+      list_join:
+      - ''
+      - - {get_param: [IPPool, {get_param: ExternalNetName}, {get_param: NodeIndex}]}
+        - '/'
+        - {get_param: [ExternalNetCidr, -2]}
+        - {get_param: [ExternalNetCidr, -1]}
diff --git a/network/ports/from_service.yaml b/network/ports/from_service.yaml
new file mode 100644 (file)
index 0000000..6b669f4
--- /dev/null
@@ -0,0 +1,34 @@
+heat_template_version: 2015-04-30
+
+description: >
+  Returns an IP from a service mapped list of IPs
+
+parameters:
+  ServiceName:
+    description: Name of the service to lookup
+    default: ''
+    type: string
+  NetworkName: # Here for compatability with ctlplane_vip.yaml
+    description: Name of the network where the VIP will be created
+    default: ctlplane
+    type: string
+  PortName: # Here for compatability with ctlplane_vip.yaml
+    description: Name of the port
+    default: ''
+    type: string
+  ControlPlaneIP: # Here for compatability with ctlplane_vip.yaml
+    description: IP address on the control plane
+    default: ''
+    type: string
+  ControlPlaneNetwork: # Here for compatability with ctlplane_vip.yaml
+    description: The name of the undercloud Neutron control plane
+    default: ctlplane
+    type: string
+  ServiceVips:
+    default: {}
+    type: json
+
+outputs:
+  ip_address:
+    description: network IP
+    value: {get_param: [ServiceVips, {get_param: ServiceName}]}
index 01cdfe9..f84e8f7 100644 (file)
@@ -22,6 +22,12 @@ parameters:
         [{'ip_address':'1.2.3.4'}]
     default: []
     type: json
+  IPPool: # Here for compatibility with from_pool.yaml
+    default: {}
+    type: json
+  NodeIndex: # Here for compatibility with from_pool.yaml
+    default: 0
+    type: number
 
 resources:
 
diff --git a/network/ports/internal_api_from_pool.yaml b/network/ports/internal_api_from_pool.yaml
new file mode 100644 (file)
index 0000000..b98e1fb
--- /dev/null
@@ -0,0 +1,45 @@
+heat_template_version: 2015-04-30
+
+description: >
+  Returns an IP from a network mapped list of IPs
+
+parameters:
+  InternalApiNetName:
+    description: Name of the internal API network
+    default: internal_api
+    type: string
+  PortName:
+    description: Name of the port
+    default: ''
+    type: string
+  ControlPlaneIP: # Here for compatability with noop.yaml
+    description: IP address on the control plane
+    default: ''
+    type: string
+  IPPool:
+    default: {}
+    description: A network mapped list of IPs
+    type: json
+  NodeIndex:
+    default: 0
+    description: Index of the IP to get from Pool
+    type: number
+  InternalApiNetCidr:
+    default: '172.16.2.0/24'
+    description: Cidr for the internal API network.
+    type: string
+
+outputs:
+  ip_address:
+    description: internal API network IP
+    value: {get_param: [IPPool, {get_param: InternalApiNetName}, {get_param: NodeIndex}]}
+  ip_subnet:
+    # FIXME: this assumes a 2 digit subnet CIDR (need more heat functions?)
+    description: IP/Subnet CIDR for the internal API network IP
+    value:
+      list_join:
+      - ''
+      - - {get_param: [IPPool, {get_param: InternalApiNetName}, {get_param: NodeIndex}]}
+        - '/'
+        - {get_param: [InternalApiNetCidr, -2]}
+        - {get_param: [InternalApiNetCidr, -1]}
index 36426b3..23e1f99 100644 (file)
@@ -2,7 +2,7 @@ heat_template_version: 2015-04-30
 
 parameters:
   # Set these via parameter defaults to configure external VIPs
-  ControlNetworkVip:
+  ControlPlaneIP:
     default: ''
     type: string
   ExternalNetworkVip:
@@ -43,7 +43,7 @@ outputs:
       A Hash containing a mapping of network names to assigned IPs
       for a specific machine.
     value:
-      ctlplane: {get_param: ControlNetworkVip}
+      ctlplane: {get_param: ControlPlaneIP}
       external: {get_param: ExternalNetworkVip}
       internal_api: {get_param: InternalApiNetworkVip}
       storage: {get_param: StorageNetworkVip}
index 028624f..ac946cd 100644 (file)
@@ -4,6 +4,10 @@ description: >
   Returns the control plane port (provisioning network) as the ip_address.
 
 parameters:
+  ServiceName: # Here for compatibility with from_service.yaml
+    description: Name of the service to lookup
+    default: ''
+    type: string
   ControlPlaneIP:
     description: IP address on the control plane
     type: string
@@ -27,6 +31,14 @@ parameters:
     default: '24'
     description: The subnet CIDR of the control plane network.
     type: string
+  IPPool: # Here for compatibility with from_pool.yaml
+    default: {}
+    description: A network mapped list of IPs
+    type: json
+  NodeIndex: # Here for compatibility with from_pool.yaml
+    default: 0
+    description: Index of the IP to get from Pool
+    type: number
 
 outputs:
   ip_address:
index 1d2384c..a07e5a4 100644 (file)
@@ -22,6 +22,12 @@ parameters:
         [{'ip_address':'1.2.3.4'}]
     default: []
     type: json
+  IPPool: # Here for compatibility with from_pool.yaml
+    default: {}
+    type: json
+  NodeIndex: # Here for compatibility with from_pool.yaml
+    default: 0
+    type: number
 
 resources:
 
diff --git a/network/ports/storage_from_pool.yaml b/network/ports/storage_from_pool.yaml
new file mode 100644 (file)
index 0000000..668bc6f
--- /dev/null
@@ -0,0 +1,45 @@
+heat_template_version: 2015-04-30
+
+description: >
+  Returns an IP from a network mapped list of IPs
+
+parameters:
+  StorageNetName:
+    description: Name of the storage network
+    default: storage
+    type: string
+  PortName:
+    description: Name of the port
+    default: ''
+    type: string
+  ControlPlaneIP: # Here for compatability with noop.yaml
+    description: IP address on the control plane
+    default: ''
+    type: string
+  IPPool:
+    default: {}
+    description: A network mapped list of IPs
+    type: json
+  NodeIndex:
+    default: 0
+    description: Index of the IP to get from Pool
+    type: number
+  StorageNetCidr:
+    default: '172.16.1.0/24'
+    description: Cidr for the storage network.
+    type: string
+
+outputs:
+  ip_address:
+    description: storage network IP
+    value: {get_param: [IPPool, {get_param: StorageNetName}, {get_param: NodeIndex}]}
+  ip_subnet:
+    # FIXME: this assumes a 2 digit subnet CIDR (need more heat functions?)
+    description: IP/Subnet CIDR for the storage network IP
+    value:
+      list_join:
+      - ''
+      - - {get_param: [IPPool, {get_param: StorageNetName}, {get_param: NodeIndex}]}
+        - '/'
+        - {get_param: [StorageNetCidr, -2]}
+        - {get_param: [StorageNetCidr, -1]}
index f10e358..4890bf5 100644 (file)
@@ -22,6 +22,12 @@ parameters:
         [{'ip_address':'1.2.3.4'}]
     default: []
     type: json
+  IPPool: # Here for compatibility with from_pool.yaml
+    default: {}
+    type: json
+  NodeIndex: # Here for compatibility with from_pool.yaml
+    default: 0
+    type: number
 
 resources:
 
diff --git a/network/ports/storage_mgmt_from_pool.yaml b/network/ports/storage_mgmt_from_pool.yaml
new file mode 100644 (file)
index 0000000..bea8710
--- /dev/null
@@ -0,0 +1,45 @@
+heat_template_version: 2015-04-30
+
+description: >
+  Returns an IP from a network mapped list of IPs
+
+parameters:
+  StorageMgmtNetName:
+    description: Name of the storage MGMT network
+    default: storage_mgmt
+    type: string
+  PortName:
+    description: Name of the port
+    default: ''
+    type: string
+  ControlPlaneIP: # Here for compatability with noop.yaml
+    description: IP address on the control plane
+    default: ''
+    type: string
+  IPPool:
+    default: {}
+    description: A network mapped list of IPs
+    type: json
+  NodeIndex:
+    default: 0
+    description: Index of the IP to get from Pool
+    type: number
+  StorageMgmtNetCidr:
+    default: '172.16.3.0/24'
+    description: Cidr for the storage MGMT network.
+    type: string
+
+outputs:
+  ip_address:
+    description: storage MGMT network IP
+    value: {get_param: [IPPool, {get_param: StorageMgmtNetName}, {get_param: NodeIndex}]}
+  ip_subnet:
+    # FIXME: this assumes a 2 digit subnet CIDR (need more heat functions?)
+    description: IP/Subnet CIDR for the storage MGMT network IP
+    value:
+      list_join:
+      - ''
+      - - {get_param: [IPPool, {get_param: StorageMgmtNetName}, {get_param: NodeIndex}]}
+        - '/'
+        - {get_param: [StorageMgmtNetCidr, -2]}
+        - {get_param: [StorageMgmtNetCidr, -1]}
index ccdc57e..86c58f2 100644 (file)
@@ -22,6 +22,12 @@ parameters:
         [{'ip_address':'1.2.3.4'}]
     default: []
     type: json
+  IPPool: # Here for compatibility with from_pool.yaml
+    default: {}
+    type: json
+  NodeIndex: # Here for compatibility with from_pool.yaml
+    default: 0
+    type: number
 
 resources:
 
diff --git a/network/ports/tenant_from_pool.yaml b/network/ports/tenant_from_pool.yaml
new file mode 100644 (file)
index 0000000..29303bb
--- /dev/null
@@ -0,0 +1,45 @@
+heat_template_version: 2015-04-30
+
+description: >
+  Returns an IP from a network mapped list of IPs
+
+parameters:
+  TenantNetName:
+    description: Name of the tenant network
+    default: tenant
+    type: string
+  PortName:
+    description: Name of the port
+    default: ''
+    type: string
+  ControlPlaneIP: # Here for compatability with noop.yaml
+    description: IP address on the control plane
+    default: ''
+    type: string
+  IPPool:
+    default: {}
+    description: A network mapped list of IPs
+    type: json
+  NodeIndex:
+    default: 0
+    description: Index of the IP to get from Pool
+    type: number
+  TenantNetCidr:
+    default: '172.16.0.0/24'
+    description: Cidr for the tenant network.
+    type: string
+
+outputs:
+  ip_address:
+    description: tenant network IP
+    value: {get_param: [IPPool, {get_param: TenantNetName}, {get_param: NodeIndex}]}
+  ip_subnet:
+    # FIXME: this assumes a 2 digit subnet CIDR (need more heat functions?)
+    description: IP/Subnet CIDR for the tenant network IP
+    value:
+      list_join:
+      - ''
+      - - {get_param: [IPPool, {get_param: TenantNetName}, {get_param: NodeIndex}]}
+        - '/'
+        - {get_param: [TenantNetCidr, -2]}
+        - {get_param: [TenantNetCidr, -1]}
index ab6cd2c..9bb6cde 100644 (file)
@@ -5,6 +5,10 @@ description: >
   The IP address will be chosen automatically if FixedIPs is empty.
 
 parameters:
+  ServiceName: # Here for compatibility with from_service.yaml
+    description: Name of the service to lookup
+    default: ''
+    type: string
   NetworkName:
     description: Name of the network where the VIP will be created
     default: internal_api
index c072c29..ab2782f 100644 (file)
@@ -63,6 +63,13 @@ resource_registry:
   OS::TripleO::Network::Ports::NetIpSubnetMap: network/ports/net_ip_subnet_map.yaml
   OS::TripleO::Network::Ports::NetIpListMap: network/ports/net_ip_list_map.yaml
 
+  # Port assignments for the VIPs
+  OS::TripleO::Network::Ports::ExternalVipPort: network/ports/noop.yaml
+  OS::TripleO::Network::Ports::InternalApiVipPort: network/ports/noop.yaml
+  OS::TripleO::Network::Ports::StorageVipPort: network/ports/noop.yaml
+  OS::TripleO::Network::Ports::StorageMgmtVipPort: network/ports/noop.yaml
+  OS::TripleO::Network::Ports::RedisVipPort: network/ports/ctlplane_vip.yaml
+
   # Port assignments for the controller role
   OS::TripleO::Controller::Ports::ExternalPort: network/ports/noop.yaml
   OS::TripleO::Controller::Ports::InternalApiPort: network/ports/noop.yaml
@@ -89,9 +96,6 @@ resource_registry:
   OS::TripleO::BlockStorage::Ports::StoragePort: network/ports/noop.yaml
   OS::TripleO::BlockStorage::Ports::StorageMgmtPort: network/ports/noop.yaml
 
-  # Port assignments for service virtual IPs for the controller role
-  OS::TripleO::Controller::Ports::RedisVipPort: network/ports/ctlplane_vip.yaml
-
   # Service Endpoint Mappings
   OS::TripleO::Endpoint: network/endpoints/endpoint.yaml
   OS::TripleO::EndpointMap: network/endpoints/endpoint_map.yaml
index b1eb62a..f4bcb78 100644 (file)
@@ -1201,17 +1201,18 @@ resources:
 
   RedisVirtualIP:
     depends_on: Networks
-    type: OS::TripleO::Controller::Ports::RedisVipPort
+    type: OS::TripleO::Network::Ports::RedisVipPort
     properties:
       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
       ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
       PortName: redis_virtual_ip
       NetworkName: {get_param: [ServiceNetMap, RedisNetwork]}
+      ServiceName: redis
 
   # The public VIP is on the External net, falls back to ctlplane
   PublicVirtualIP:
     depends_on: Networks
-    type: OS::TripleO::Controller::Ports::ExternalPort
+    type: OS::TripleO::Network::Ports::ExternalVipPort
     properties:
       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
       ControlPlaneNetwork: {get_param: NeutronControlPlaneID}
@@ -1220,21 +1221,21 @@ resources:
 
   InternalApiVirtualIP:
     depends_on: Networks
-    type: OS::TripleO::Controller::Ports::InternalApiPort
+    type: OS::TripleO::Network::Ports::InternalApiVipPort
     properties:
       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
       PortName: internal_api_virtual_ip
 
   StorageVirtualIP:
     depends_on: Networks
-    type: OS::TripleO::Controller::Ports::StoragePort
+    type: OS::TripleO::Network::Ports::StorageVipPort
     properties:
       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
       PortName: storage_virtual_ip
 
   StorageMgmtVirtualIP:
     depends_on: Networks
-    type: OS::TripleO::Controller::Ports::StorageMgmtPort
+    type: OS::TripleO::Network::Ports::StorageMgmtVipPort
     properties:
       ControlPlaneIP: {get_attr: [ControlVirtualIP, fixed_ips, 0, ip_address]}
       PortName: storage_management_virtual_ip
index 5d39462..65dd535 100644 (file)
@@ -90,6 +90,15 @@ parameters:
     description: |
       Controller specific hiera configuration data to inject into the cluster.
     type: json
+  ControllerIPs:
+    default: {}
+    description: >
+      A network mapped list of IPs to assign to Controllers in the following form:
+      {
+        "internal_api": ["a.b.c.d", "e.f.g.h"],
+        ...
+      }
+    type: json
   ControlVirtualInterface:
     default: 'br-ex'
     description: Interface where virtual ip will be assigned.
@@ -689,26 +698,36 @@ resources:
   ExternalPort:
     type: OS::TripleO::Controller::Ports::ExternalPort
     properties:
+      IPPool: {get_param: ControllerIPs}
+      NodeIndex: {get_param: NodeIndex}
       ControlPlaneIP: {get_attr: [Controller, networks, ctlplane, 0]}
 
   InternalApiPort:
     type: OS::TripleO::Controller::Ports::InternalApiPort
     properties:
+      IPPool: {get_param: ControllerIPs}
+      NodeIndex: {get_param: NodeIndex}
       ControlPlaneIP: {get_attr: [Controller, networks, ctlplane, 0]}
 
   StoragePort:
     type: OS::TripleO::Controller::Ports::StoragePort
     properties:
+      IPPool: {get_param: ControllerIPs}
+      NodeIndex: {get_param: NodeIndex}
       ControlPlaneIP: {get_attr: [Controller, networks, ctlplane, 0]}
 
   StorageMgmtPort:
     type: OS::TripleO::Controller::Ports::StorageMgmtPort
     properties:
+      IPPool: {get_param: ControllerIPs}
+      NodeIndex: {get_param: NodeIndex}
       ControlPlaneIP: {get_attr: [Controller, networks, ctlplane, 0]}
 
   TenantPort:
     type: OS::TripleO::Controller::Ports::TenantPort
     properties:
+      IPPool: {get_param: ControllerIPs}
+      NodeIndex: {get_param: NodeIndex}
       ControlPlaneIP: {get_attr: [Controller, networks, ctlplane, 0]}
 
   NetIpMap: