From c4eb9688d758f2a89e8d118b4ef8507fc765d986 Mon Sep 17 00:00:00 2001
From: James Slagle <jslagle@redhat.com>
Date: Wed, 13 Feb 2019 14:00:59 -0500
Subject: [PATCH] Add external_resource_id properties to network_data.yaml

Adds the ability to set external_resource_id for the network,
external_resource_subnet_id for the subnet(s), and
external_resource_segment_id for the segment(s) to network_data.yaml.

When setting these properties, the external_id attribute will be set on
the corresponding Heat resources. This causes Heat to not re-create
these resources and instead adopt them from outside the stack.

When using network isolation with multiple stacks (e.g.,
split-controlplane), this allows for re-using some of the same
networks and resources from the non-control plane stacks.

Change-Id: I6652ef8a5105843f4b2cdec54062bd25a57809a0
---
 network/network.j2 | 15 +++++++++++++++
 network_data.yaml  | 13 ++++++++++++-
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/network/network.j2 b/network/network.j2
index 92c303105f..0c8136267d 100644
--- a/network/network.j2
+++ b/network/network.j2
@@ -131,6 +131,9 @@ parameters:
 resources:
   {{network.name}}Network:
     type: OS::Neutron::Net
+{%- if network.external_resource_network_id|default('') %}
+    external_id: {{ network.external_resource_network_id }}
+{%- endif %}
     properties:
       admin_state_up: {get_param: {{network.name}}NetAdminStateUp}
       name: {get_param: {{network.name}}NetName}
@@ -142,6 +145,9 @@ resources:
 
   {{network.name}}Subnet:
     type: OS::Neutron::Subnet
+{%- if network.external_resource_subnet_id|default('') %}
+    external_id: {{ network.external_resource_subnet_id }}
+{%- endif %}
     properties:
 {%- if ":" in network.ip_subnet or network.ipv6 or ipv6_override %}
       ip_version: 6
@@ -160,20 +166,29 @@ resources:
       # All networks have an implicit network segment when created, map this subnet to that segment.
       segment: {get_attr: [{{network.name}}Network, segments, 0, id]}
 {%- endif %}
+
 {% for subnet in network.subnets|default({}) if network.subnets[subnet].enabled|default(true) %}
   {{network.name}}Segment_{{subnet}}:
     type: OS::Neutron::Segment
     # NOTE(hjensas): Depends-On here to ensure we always create the base subnet
     #   first. We can only set the segment for existing subnet if there is only
     #   one segment and only one existing subnet on the network.
+{%- if subnet.external_resource_segment_id|default('') %}
+    external_id: {{ subnet.external_resource_segment_id }}
+{%- else %}
     depends_on: {{network.name}}Subnet
+{%- endif %}
     properties:
       name: {{network.name_lower}}_{{subnet}}
       network: {get_resource: {{network.name}}Network}
       network_type: flat
       physical_network: {{network.name_lower}}_{{subnet}}
+
   {{network.name}}Subnet_{{subnet}}:
     type: OS::Neutron::Subnet
+{%- if subnet.external_resource_subnet_id|default('') %}
+    external_id: {{ subnet.external_resource_subnet_id }}
+{%- endif %}
     properties:
 {%- if ":" in network.ip_subnet or network.ipv6 or ipv6_override %}
       ip_version: 6
diff --git a/network_data.yaml b/network_data.yaml
index 158ff8339f..a40598c0e6 100644
--- a/network_data.yaml
+++ b/network_data.yaml
@@ -9,6 +9,15 @@
 #             to original default (optional).  This field is only necessary when
 #             changing the default network names, not when adding a new custom network.
 # enabled: Is the network enabled (optional, defaults to true)
+# external_resource_network_id: Optional. If set, it should be the UUID of an existing already
+#                       created Neutron network that will be used in place of creating a
+#                       new network.
+# external_resource_subnet_id: Optional. If set, it should be the UUID of an existing already
+#                              created Neutron subnet that will be used in place of creating a
+#                              new subnet for the network.
+# external_resource_segment_id: Optional. If set, it should be the UUID of an existing already
+#                               created Neutron segment that will be used in place of creating a
+#                               new segment for the network.
 # NOTE: False will use noop.yaml for unused legacy networks to support upgrades.
 # vlan: vlan for the network (optional)
 # vip: Enable creation of a virtual IP on this network
@@ -46,7 +55,9 @@
 #                                 'ipv6_subnet': '<IPv6/CIDR>',
 #                                 'ipv6_allocation_pools': '<IPv6 range list>',
 #                                 'gateway_ipv6': '<IPv6 gateway>',
-#                                 'routes_ipv6': '<Routes list>'}}
+#                                 'routes_ipv6': '<Routes list>',
+#                                 'external_resource_subnet_id': '<Existing subnet UUID (optional)>'}}
+#                                 'external_resource_segment_id': '<Existing segment UUID (optional)>'}}
 #
 # Example:
 # - name Example