From 91e763f748e098b6c1fc13dc63fb1e612b36a64f Mon Sep 17 00:00:00 2001
From: Robert Collins <rbtcollins@hp.com>
Date: Mon, 30 Jun 2014 16:53:25 +1200
Subject: [PATCH] Expose public_interface_tag support.

Proper VLAN support requires adding the IP address to a new device,
rather than br-ex/br-ctlplane. This is added in the
tripleo-image-elements change https://review.openstack.org/103449
(I3f77f72ac623792e844dbb4d501b6ab269141f8e) and here we just expose
it with appropriate glue to get the IP address from Neutron.

With this we can now describe a VLAN public interface scenario
to the undercloud and overcloud control planes.

Change-Id: I4d2194fc813aebb0708d6fddf4f05bae5f091fd8
---
 .gitignore                |  1 +
 Makefile                  | 11 +++++++++--
 overcloud-source.yaml     | 12 ++++++++++++
 overcloud-vlan-port.yaml  | 38 ++++++++++++++++++++++++++++++++++++++
 undercloud-source.yaml    | 15 ++++++++++++++-
 undercloud-vlan-port.yaml | 36 ++++++++++++++++++++++++++++++++++++
 6 files changed, 110 insertions(+), 3 deletions(-)
 create mode 100644 overcloud-vlan-port.yaml
 create mode 100644 undercloud-vlan-port.yaml

diff --git a/.gitignore b/.gitignore
index ae03b0393d..3035c9e5ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ overcloud-with-block-storage-nfs.yaml
 undercloud-bm.yaml
 undercloud-vm.yaml
 undercloud-vm-ironic.yaml
+undercloud-vm-ironic-vlan.yaml
 
 *.py[cod]
 
diff --git a/Makefile b/Makefile
index ad8dc99b6f..349a07787a 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,8 @@ generated_templates =                         \
         overcloud-with-block-storage-nfs.yaml \
         undercloud-vm.yaml                    \
         undercloud-bm.yaml                    \
-        undercloud-vm-ironic.yaml
+        undercloud-vm-ironic.yaml             \
+        undercloud-vm-ironic-vlan.yaml
 
 # Files included in overcloud-source.yaml via FileInclude
 overcloud_source_deps = nova-compute-instance.yaml
@@ -14,8 +15,10 @@ validate-all: $(VALIDATE)
 $(VALIDATE):
 	heat template-validate -f $(subst validate-,,$@)
 
+# set CONTROLEXTRA to overcloud-vlan-port.yaml to activate the VLAN
+# auto-assignment from Neutron.
 overcloud.yaml: overcloud-source.yaml block-storage.yaml swift-deploy.yaml swift-source.yaml swift-storage-source.yaml ssl-source.yaml nova-compute-config.yaml $(overcloud_source_deps)
-	python ./tripleo_heat_merge/merge.py --hot --scale NovaCompute=$${COMPUTESCALE:-'1'} --scale controller=$${CONTROLSCALE:-'1'} --scale SwiftStorage=$${SWIFTSTORAGESCALE:-'0'} --scale BlockStorage=$${BLOCKSTORAGESCALE:-'0'} overcloud-source.yaml block-storage.yaml swift-source.yaml swift-storage-source.yaml ssl-source.yaml swift-deploy.yaml nova-compute-config.yaml > $@.tmp
+	python ./tripleo_heat_merge/merge.py --hot --scale NovaCompute=$${COMPUTESCALE:-'1'} --scale controller=$${CONTROLSCALE:-'1'} --scale SwiftStorage=$${SWIFTSTORAGESCALE:-'0'} --scale BlockStorage=$${BLOCKSTORAGESCALE:-'0'} overcloud-source.yaml block-storage.yaml swift-source.yaml swift-storage-source.yaml ssl-source.yaml swift-deploy.yaml nova-compute-config.yaml ${CONTROLEXTRA} > $@.tmp
 	mv $@.tmp $@
 
 overcloud-with-block-storage-nfs.yaml: overcloud-source.yaml block-storage-nfs.yaml nfs-server-source.yaml swift-source.yaml swift-storage-source.yaml ssl-source.yaml $(overcloud_source_deps)
@@ -36,6 +39,10 @@ undercloud-vm-ironic.yaml: undercloud-source.yaml undercloud-vm-ironic-config.ya
 	python ./tripleo_heat_merge/merge.py --hot $^ > $@.tmp
 	mv $@.tmp $@
 
+undercloud-vm-ironic-vlan.yaml: undercloud-source.yaml undercloud-vm-ironic-config.yaml undercloud-vm-ironic-deploy.yaml undercloud-vlan-port.yaml
+	python ./tripleo_heat_merge/merge.py --hot $^ > $@.tmp
+	mv $@.tmp $@
+
 check: test
 
 test:
diff --git a/overcloud-source.yaml b/overcloud-source.yaml
index 4929de8641..071335ae03 100644
--- a/overcloud-source.yaml
+++ b/overcloud-source.yaml
@@ -181,6 +181,16 @@ parameters:
     default: ''
     description: A custom IP address to put onto the NeutronPublicInterface.
     type: string
+  NeutronPublicInterfaceTag:
+    default: ''
+    description: |
+      VLAN tag for creating a public VLAN. The tag will be used to
+      create an access port on the exterior bridge for each control plane node,
+      and that port will be given the IP address returned by neutron from the
+      public network. Set CONTROLEXTRA=overcloud-vlan-port.yaml when compiling
+      overcloud.yaml to include the deployment of VLAN ports to the control
+      plane.
+    type: string
   NeutronPublicInterfaceRawDevice:
     default: ''
     description: If set, the public interface is a vlan with this device as the raw device.
@@ -506,6 +516,8 @@ resources:
               get_param: NeutronPublicInterfaceRawDevice
             public_interface_route:
               get_param: NeutronPublicInterfaceDefaultRoute
+            public_interface_tag:
+              get_param: NeutronPublicInterfaceTag
             physical_bridge: br-ex
             tenant_network_type: gre
           ovs_db:
diff --git a/overcloud-vlan-port.yaml b/overcloud-vlan-port.yaml
new file mode 100644
index 0000000000..e962e7a06d
--- /dev/null
+++ b/overcloud-vlan-port.yaml
@@ -0,0 +1,38 @@
+outputs:
+  controller0PublicIP:
+    description: Address for registering endpoints in the cloud.
+    value: {get_attr: [controller0VLANPort, fixed_ips, 0, ip_address]}
+resources:
+  # Override the main template which can also supply a static route.
+  controller0_99_VLANPort:
+    type: OS::Heat::StructuredDeployment
+    properties:
+      config: {get_resource: ControllerVLANPortConfig}
+      server: {get_resource: controller0}
+      signal_transport: NO_SIGNAL
+      input_values:
+        vlan_port:
+          list_join:
+          - '/'
+          - - {get_attr: [controller0_VLANPort, fixed_ips, 0, ip_address]}
+            # This should also be pulled out of the subnet. May need a
+            # neutron fix too - XXX make into a parameter and feed it
+            # in via _overcloud.sh for now.
+            - '24'
+        # Tell the instance to apply the default route.
+        # Reinstate when https://bugs.launchpad.net/heat/+bug/1336656 is
+        # sorted
+        # public_interface_route:
+        #   get_attr: [controller0_VLANPort, fixed_ips, 0, subnet, gateway_ip]
+  ControllerVLANPortConfig:
+    type: OS::Heat::StructuredConfig
+    properties:
+      config:
+        neutron:
+          ovs:
+            public_interface_tag_ip: {get_input: vlan_port}
+  controller0_VLANPort:
+    type: OS::Neutron::Port
+    properties:
+      name: controller0_vlan
+      network: public
diff --git a/undercloud-source.yaml b/undercloud-source.yaml
index e09b3db5cc..40dbd8903c 100644
--- a/undercloud-source.yaml
+++ b/undercloud-source.yaml
@@ -134,7 +134,18 @@ parameters:
     type: string
   NeutronPublicInterfaceIP:
     default: ''
-    description: A custom IP address to put onto the NeutronPublicInterface.
+    description: |
+      A custom IP address to put onto the NeutronPublicInterface bridge.
+      See also NeutronPublicInterfaceTagIP for adding a VLAN tagging IP.
+      NeutronPublicInterfaceIP is deprecated in the context of deploying
+      underclouds - its only needed for the seed bootstrap process.
+    type: string
+  NeutronPublicInterfaceTag:
+    default: ''
+    description: |
+      VLAN tag for creating a public VLAN. The tag will be used to
+      create an access port on the exterior bridge, and that port will be
+      given the IP address returned by neutron from the public network.
     type: string
   NeutronPublicInterfaceRawDevice:
     default: ''
@@ -280,6 +291,8 @@ resources:
               get_param: NeutronPublicInterfaceRawDevice
             public_interface_route:
               get_param: NeutronPublicInterfaceDefaultRoute
+            public_interface_tag:
+              get_param: NeutronPublicInterfaceTag
             physical_bridge: br-ctlplane
             physical_network: ctlplane
             network_vlan_ranges: ctlplane
diff --git a/undercloud-vlan-port.yaml b/undercloud-vlan-port.yaml
new file mode 100644
index 0000000000..8231f49d29
--- /dev/null
+++ b/undercloud-vlan-port.yaml
@@ -0,0 +1,36 @@
+outputs:
+  PublicIP:
+    description: Address for registering endpoints in the cloud.
+    value: {get_attr: [undercloud_VLANPort, fixed_ips, 0, ip_address]}
+resources:
+  # Override the main template which can also supply a static route.
+  undercloud_99VLANPort:
+    type: OS::Heat::StructuredDeployment
+    properties:
+      config: {get_resource: undercloudVLANPortConfig}
+      server: {get_resource: undercloud}
+      signal_transport: NO_SIGNAL
+  undercloudVLANPortConfig:
+    type: OS::Heat::StructuredConfig
+    properties:
+      config:
+        neutron:
+          ovs:
+            public_interface_tag_ip:
+              Fn::Join:
+              - '/'
+              - - {get_attr: [undercloud_VLANPort, fixed_ips, 0, ip_address]}
+                - '24'
+                # This should also be pulled out of the subnet. May need a
+                # neutron fix too - XXX make into a parameter and feed it
+                # in via _undercloud.sh for now.
+            # Tell the instance to apply the default route.
+            # Reinstate when https://bugs.launchpad.net/heat/+bug/1336656 is
+            # sorted
+            # public_interface_route:
+            #   get_attr: [undercloud_VLANPort, fixed_ips, 0, subnet, gateway_ip]
+  undercloud_VLANPort:
+    type: OS::Neutron::Port
+    properties:
+      name: undercloud_vlan
+      network: public