Add FWaaS support

This adds all necessary FWaaS configuration for the Ocata version.
Both V1 and V2 versions can be enabled, however only V1 is operable
in this release.

PROD-13639
Change-Id: I432149c90011492c13b22813b96be65d84fa3229
diff --git a/.kitchen.yml b/.kitchen.yml
index b762e23..ba95941 100644
--- a/.kitchen.yml
+++ b/.kitchen.yml
@@ -63,6 +63,11 @@
       pillars-from-files:
         neutron.sls: tests/pillar/compute_dvr.sls
 
+  - name: compute_dvr_fwaas_v1
+    provisioner:
+      pillars-from-files:
+        neutron.sls: tests/pillar/compute_dvr_fwaas_v1.sls
+
   - name: compute_legacy
     provisioner:
       pillars-from-files:
@@ -104,11 +109,16 @@
       pillars-from-files:
         neutron.sls: tests/pillar/control_nodvr.sls
 
-  - name: control_lbaas_octavia.sls
+  - name: control_lbaas_octavia
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_lbaas_octavia.sls
 
+  - name: control_fwaas_v1
+    provisioner:
+      pillars-from-files:
+        neutron.sls: tests/pillar/control_fwaas_v1.sls
+
   - name: control_single
     provisioner:
       pillars-from-files:
@@ -134,4 +144,9 @@
       pillars-from-files:
         neutron.sls: tests/pillar/gateway_qos.sls
 
+  - name: gateway_legacy_fwaas_v1
+    provisioner:
+      pillars-from-files:
+        neutron.sls: tests/pillar/gateway_legacy_fwaas_v1.sls
+
 # vim: ft=yaml sw=2 ts=2 sts=2 tw=125
diff --git a/.travis.yml b/.travis.yml
index 3925301..779286f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -21,12 +21,17 @@
     - PLATFORM=trevorj/salty-whales:xenial SUITE=compute_dpdk
     - PLATFORM=trevorj/salty-whales:trusty SUITE=compute_dvr
     - PLATFORM=trevorj/salty-whales:xenial SUITE=compute_dvr
+    - PLATFORM=trevorj/salty-whales:xenial SUITE=compute_dvr_fwaas_v1
     - PLATFORM=trevorj/salty-whales:trusty SUITE=compute_legacy
     - PLATFORM=trevorj/salty-whales:xenial SUITE=compute_legacy
     - PLATFORM=trevorj/salty-whales:trusty SUITE=compute_nonexternal_dvr
     - PLATFORM=trevorj/salty-whales:xenial SUITE=compute_nonexternal_dvr
     - PLATFORM=trevorj/salty-whales:trusty SUITE=compute_sriov
     - PLATFORM=trevorj/salty-whales:xenial SUITE=compute_sriov
+    - PLATFORM=trevorj/salty-whales:trusty SUITE=compute_qos_sriov
+    - PLATFORM=trevorj/salty-whales:xenial SUITE=compute_qos_sriov
+    - PLATFORM=trevorj/salty-whales:trusty SUITE=compute_qos
+    - PLATFORM=trevorj/salty-whales:xenial SUITE=compute_qos
     - PLATFORM=trevorj/salty-whales:trusty SUITE=control_cluster
     - PLATFORM=trevorj/salty-whales:xenial SUITE=control_cluster
     - PLATFORM=trevorj/salty-whales:trusty SUITE=control_dvr
@@ -35,10 +40,17 @@
     - PLATFORM=trevorj/salty-whales:xenial SUITE=control_nodvr
     - PLATFORM=trevorj/salty-whales:trusty SUITE=control_single
     - PLATFORM=trevorj/salty-whales:xenial SUITE=control_single
+    - PLATFORM=trevorj/salty-whales:xenial SUITE=control_lbaas_octavia
+    - PLATFORM=trevorj/salty-whales:xenial SUITE=control_fwaas_v1
+    - PLATFORM=trevorj/salty-whales:trusty SUITE=control_qos
+    - PLATFORM=trevorj/salty-whales:xenial SUITE=control_qos
     - PLATFORM=trevorj/salty-whales:trusty SUITE=gateway_dvr
     - PLATFORM=trevorj/salty-whales:xenial SUITE=gateway_dvr
     - PLATFORM=trevorj/salty-whales:trusty SUITE=gateway_legacy
     - PLATFORM=trevorj/salty-whales:xenial SUITE=gateway_legacy
+    - PLATFORM=trevorj/salty-whales:trusty SUITE=gateway_qos
+    - PLATFORM=trevorj/salty-whales:xenial SUITE=gateway_qos
+    - PLATFORM=trevorj/salty-whales:xenial SUITE=gateway_legacy_fwaas_v1
 
 before_script:
   - set -o pipefail
diff --git a/README.rst b/README.rst
index 66b2299..e8ef14c 100644
--- a/README.rst
+++ b/README.rst
@@ -108,7 +108,21 @@
       lbaas:
         enabled: false
 
+
+Neutron FWaaSv1 enablement
+--------------------------
+
+.. code-block:: yaml
+
+  neutron:
+    fwaas:
+      enabled: true
+      version: ocata
+      api_version: v1
+
+
 Enable CORS parameters
+----------------------
 
 .. code-block:: yaml
 
diff --git a/metadata/service/fwaas/init.yml b/metadata/service/fwaas/init.yml
new file mode 100644
index 0000000..141af64
--- /dev/null
+++ b/metadata/service/fwaas/init.yml
@@ -0,0 +1,7 @@
+applications:
+  - neutron
+parameters:
+  neutron:
+    fwaas:
+      enabled: true
+      version: ${_param:neutron_version}
diff --git a/neutron/compute.sls b/neutron/compute.sls
index 9770b85..a4faa97 100644
--- a/neutron/compute.sls
+++ b/neutron/compute.sls
@@ -1,4 +1,4 @@
-{% from "neutron/map.jinja" import compute with context %}
+{% from "neutron/map.jinja" import compute, fwaas with context %}
 {%- if compute.enabled %}
 
 neutron_compute_packages:
@@ -46,6 +46,11 @@
 
 {% if compute.dvr %}
 
+{%- if fwaas.get('enabled', False) %}
+include:
+- neutron.fwaas
+{%- endif %}
+
 neutron_dvr_packages:
   pkg.installed:
   - names:
@@ -62,6 +67,9 @@
       - file: /etc/neutron/neutron.conf
       - file: /etc/neutron/l3_agent.ini
       - file: /etc/neutron/metadata_agent.ini
+      {%- if fwaas.get('enabled', False) %}
+      - file: /etc/neutron/fwaas_driver.ini
+      {%- endif %}
     - require:
       - pkg: neutron_dvr_packages
 
diff --git a/neutron/files/ocata/fwaas_driver.ini b/neutron/files/ocata/fwaas_driver.ini
new file mode 100644
index 0000000..40442a4
--- /dev/null
+++ b/neutron/files/ocata/fwaas_driver.ini
@@ -0,0 +1,25 @@
+{%- from "neutron/map.jinja" import fwaas with context %}
+
+[DEFAULT]
+
+[fwaas]
+
+#
+# From firewall.agent
+#
+
+# Name of the FWaaS Driver (string value)
+#driver =
+driver = {{ fwaas.get('driver', fwaas[fwaas.api_version].get('driver')) }}
+
+# Enable FWaaS (boolean value)
+#enabled = false
+enabled = {{ fwaas.get('enabled', 'False') }}
+
+# Firewall agent class (string value)
+#agent_version = v1
+agent_version = {{ fwaas.api_version }}
+
+# Name of the FWaaS Conntrack Driver (string value)
+#conntrack_driver = conntrack
+conntrack_driver = {{ fwaas.get('conntrack_driver', 'conntrack') }}
diff --git a/neutron/files/ocata/l3_agent.ini b/neutron/files/ocata/l3_agent.ini
index 41b87e6..7b386a5 100644
--- a/neutron/files/ocata/l3_agent.ini
+++ b/neutron/files/ocata/l3_agent.ini
@@ -3,6 +3,7 @@
 {%- else %}
 {%- from "neutron/map.jinja" import compute as neutron with context %}
 {%- endif %}
+{%- from "neutron/map.jinja" import fwaas with context %}
 
 [DEFAULT]
 
@@ -303,6 +304,9 @@
 
 # Extensions list to use (list value)
 #extensions =
+{%- if fwaas.get('enabled', False) %}
+extensions = {{ fwaas[fwaas.api_version]['l3_extension'] }}
+{%- endif %}
 
 
 [ovs]
diff --git a/neutron/files/ocata/neutron-server.conf.Debian b/neutron/files/ocata/neutron-server.conf.Debian
index 229d342..1b9d28c 100644
--- a/neutron/files/ocata/neutron-server.conf.Debian
+++ b/neutron/files/ocata/neutron-server.conf.Debian
@@ -1,4 +1,4 @@
-{%- from "neutron/map.jinja" import server with context %}
+{%- from "neutron/map.jinja" import fwaas, server with context %}
 [DEFAULT]
 
 #
@@ -45,6 +45,7 @@
 
 service_plugins =neutron.services.l3_router.l3_router_plugin.L3RouterPlugin,neutron.services.metering.metering_plugin.MeteringPlugin
 {%- if server.lbaas is defined -%},lbaasv2{%- endif -%}
+{%- if fwaas.get('enabled', False) -%},{{ fwaas[fwaas.api_version]['service_plugin'] }}{%- endif -%}
 {%- if server.get('qos', 'True') -%},neutron.services.qos.qos_plugin.QoSPlugin{%- endif -%}
 {%- if server.get('vlan_aware_vms', False) -%},trunk{%- endif -%}
 
diff --git a/neutron/fwaas.sls b/neutron/fwaas.sls
new file mode 100644
index 0000000..8b6f87d
--- /dev/null
+++ b/neutron/fwaas.sls
@@ -0,0 +1,18 @@
+{%- from "neutron/map.jinja" import compute, fwaas with context %}
+
+{%- if fwaas.get('enabled', False) %}
+
+neutron_fwaas_packages:
+  pkg.installed:
+  - names: {{ fwaas.pkgs }}
+
+{%- if pillar.neutron.gateway is defined or compute.get('enabled', False) and compute.dvr %}
+/etc/neutron/fwaas_driver.ini:
+  file.managed:
+  - source: salt://neutron/files/{{ fwaas.version }}/fwaas_driver.ini
+  - template: jinja
+  - require:
+    - pkg: neutron_fwaas_packages
+{%- endif %}
+
+{%- endif %}
diff --git a/neutron/gateway.sls b/neutron/gateway.sls
index 45e45e3..7871c9f 100644
--- a/neutron/gateway.sls
+++ b/neutron/gateway.sls
@@ -1,4 +1,9 @@
-{% from "neutron/map.jinja" import gateway with context %}
+{% from "neutron/map.jinja" import gateway, fwaas with context %}
+{%- if fwaas.get('enabled', False) %}
+include:
+- neutron.fwaas
+{%- endif %}
+
 {%- if gateway.enabled %}
 
 neutron_gateway_packages:
@@ -54,5 +59,8 @@
     - file: /etc/neutron/metadata_agent.ini
     - file: /etc/neutron/plugins/ml2/openvswitch_agent.ini
     - file: /etc/neutron/dhcp_agent.ini
+    {%- if fwaas.get('enabled', False) %}
+    - file: /etc/neutron/fwaas_driver.ini
+    {%- endif %}
 
 {%- endif %}
diff --git a/neutron/init.sls b/neutron/init.sls
index c12f434..811d852 100644
--- a/neutron/init.sls
+++ b/neutron/init.sls
@@ -1,5 +1,8 @@
 
 include:
+{% if pillar.neutron.fwaas is defined %}
+- neutron.fwaas
+{% endif %}
 {% if pillar.neutron.server is defined %}
 - neutron.server
 {% endif %}
diff --git a/neutron/map.jinja b/neutron/map.jinja
index 1dd5f2a..a4133d1 100644
--- a/neutron/map.jinja
+++ b/neutron/map.jinja
@@ -65,6 +65,24 @@
     },
 }, merge=pillar.neutron.get('client', {})) %}
 
+{% set fwaas = salt['grains.filter_by']({
+    'default': {
+        'v1': {
+            'driver': 'iptables',
+            'l3_extension': 'fwaas',
+            'service_plugin': 'firewall',
+        },
+        'v2': {
+            'driver': 'iptables_v2',
+            'l3_extension': 'fwaas_v2',
+            'service_plugin': 'firewall_v2',
+        },
+        'pkgs': ['python-neutron-fwaas'],
+        'api_version': 'v1',
+    },
+}, merge=pillar.neutron.get('fwaas', {}), base='default') %}
+
+
 {% set monitoring = salt['grains.filter_by']({
     'default': {
         'error_log_rate': 0.2,
diff --git a/neutron/server.sls b/neutron/server.sls
index 0b3a6be..904a18c 100644
--- a/neutron/server.sls
+++ b/neutron/server.sls
@@ -1,4 +1,9 @@
-{%- from "neutron/map.jinja" import server with context %}
+{%- from "neutron/map.jinja" import server, fwaas with context %}
+{%- if fwaas.get('enabled', False) %}
+include:
+- neutron.fwaas
+{%- endif %}
+
 {%- if server.get('enabled', False) %}
 
 {% if grains.os_family == 'Debian' %}
diff --git a/tests/pillar/compute_dvr_fwaas_v1.sls b/tests/pillar/compute_dvr_fwaas_v1.sls
new file mode 100644
index 0000000..a4b86d2
--- /dev/null
+++ b/tests/pillar/compute_dvr_fwaas_v1.sls
@@ -0,0 +1,28 @@
+neutron:
+  compute:
+    agent_mode: dvr
+    backend:
+      engine: ml2
+      tenant_network_types: "flat,vxlan"
+      mechanism:
+        ovs:
+          driver: openvswitch
+    dvr: true
+    enabled: true
+    external_access: true
+    local_ip: 10.1.0.105
+    message_queue:
+      engine: rabbitmq
+      host: 127.0.0.1
+      password: workshop
+      port: 5672
+      user: openstack
+      virtual_host: /openstack
+    metadata:
+      host: 127.0.0.1
+      password: password
+    version: ocata
+  fwaas:
+    enabled: true
+    version: ocata
+    api_version: v1
diff --git a/tests/pillar/control_fwaas_v1.sls b/tests/pillar/control_fwaas_v1.sls
new file mode 100644
index 0000000..5311d2f
--- /dev/null
+++ b/tests/pillar/control_fwaas_v1.sls
@@ -0,0 +1,56 @@
+neutron:
+  server:
+    backend:
+      engine: ml2
+      external_mtu: 1500
+      mechanism:
+        ovs:
+          driver: openvswitch
+      tenant_network_types: flat,vxlan
+    bind:
+      address: 172.16.10.101
+      port: 9696
+    compute:
+      host: 127.0.0.1
+      password: workshop
+      region: RegionOne
+      tenant: service
+      user: nova
+    database:
+      engine: mysql
+      host: 127.0.0.1
+      name: neutron
+      password: workshop
+      port: 3306
+      user: neutron
+    version: ocata
+    dns_domain: novalocal
+    dvr: false
+    enabled: true
+    global_physnet_mtu: 1500
+    identity:
+      engine: keystone
+      host: 127.0.0.1
+      password: workshop
+      port: 35357
+      region: RegionOne
+      tenant: service
+      user: neutron
+      endpoint_type: internal
+    l3_ha: false
+    message_queue:
+      engine: rabbitmq
+      host: 127.0.0.1
+      password: workshop
+      port: 5672
+      user: openstack
+      virtual_host: /openstack
+    plugin: ml2
+    policy:
+      create_subnet: 'rule:admin_or_network_owner'
+      'get_network:queue_id': 'rule:admin_only'
+      'create_network:shared':
+  fwaas:
+    enabled: true
+    version: ocata
+    api_version: v1
diff --git a/tests/pillar/gateway_legacy_fwaas_v1.sls b/tests/pillar/gateway_legacy_fwaas_v1.sls
new file mode 100644
index 0000000..34e921c
--- /dev/null
+++ b/tests/pillar/gateway_legacy_fwaas_v1.sls
@@ -0,0 +1,28 @@
+neutron:
+  gateway:
+    agent_mode: legacy
+    backend:
+      engine: ml2
+      tenant_network_types: "flat,vxlan"
+      mechanism:
+        ovs:
+          driver: openvswitch
+    dvr: false
+    enabled: true
+    external_access: True
+    local_ip: 10.1.0.110
+    message_queue:
+      engine: rabbitmq
+      host: 127.0.0.1
+      password: workshop
+      port: 5672
+      user: openstack
+      virtual_host: /openstack
+    metadata:
+      host: 127.0.0.1
+      password: password
+    version: ocata
+  fwaas:
+    enabled: true
+    version: ocata
+    api_version: v1