Install simulated fabric and test client on the compute node

Change-Id: I8bd88561064f1309f1779e4666ba655bcad56bfa
diff --git a/roles/maas-simulate-fabric/defaults/main.yml b/roles/maas-simulate-fabric/defaults/main.yml
new file mode 100755
index 0000000..c86c5ee
--- /dev/null
+++ b/roles/maas-simulate-fabric/defaults/main.yml
@@ -0,0 +1,36 @@
+---
+# maas-simulate-fabric/defaults/main.yml
+
+simfabric_bridges:
+  - name: databr
+    addresses:
+      - "10.168.0.1/24"
+      - "10.168.1.1/24"
+    interfaces:
+      - veth0
+
+simfabric_links:
+  - type: veth
+    dev: veth0
+    peer: fabric
+    mac: "02:42:0a:a8:00:01"
+
+# see note in playbook, won't apply until ansible gets module support
+simfabric_iptables:
+  - table: nat
+    chain: POSTROUTING
+    source: "10.168.0.0/16"
+    dest: "! 10.168.0.0/16"
+    jump: MASQUERADE
+
+simfabric_sysctl:
+  - name: net.ipv4.ip_forward
+    value: 1
+  - name: net.ipv4.conf.all.send_redirects
+    value: 0
+  - name: net.ipv4.conf.default.send_redirects
+    value: 0
+  - name: net.ipv4.conf.eth0.send_redirects
+    value: 0
+  - name: net.ipv4.conf.databr.send_redirects
+    value: 0
diff --git a/roles/maas-simulate-fabric/tasks/main.yml b/roles/maas-simulate-fabric/tasks/main.yml
new file mode 100755
index 0000000..08cbafe
--- /dev/null
+++ b/roles/maas-simulate-fabric/tasks/main.yml
@@ -0,0 +1,83 @@
+---
+- name: Install prerequisites
+  apt:
+    name={{ item }}
+    update_cache=yes
+    cache_valid_time=3600
+  become: yes
+  register: result
+  until: result | success
+  retries: 15
+  delay: 60
+  with_items:
+   - bridge-utils
+
+- name: Create bridges
+  when: "ansible_{{ item.name }} is not defined"
+  command: brctl addbr "{{ item.name }}"
+  with_items: "{{ simfabric_bridges }}"
+
+# note, not idempotent if failed between prior step and this step
+- name: Set IP addresses to bridges
+  when: "ansible_{{ item.0.name }} is not defined"
+  command: "ip addr add {{ item.1 }} dev {{ item.0.name }}"
+  with_subelements:
+   - "{{ simfabric_bridges }}"
+   - addresses
+
+- name: Run setup again to obtain bridge info
+  setup:
+
+- name: Start bridges
+  when: "not ansible_{{ item.name }}.active"
+  command: "ip link set dev {{ item.name }} up"
+  with_items: "{{ simfabric_bridges }}"
+
+- name: Create ip links
+  when: "ansible_{{ item.dev }} is not defined"
+  command: "ip link add dev {{ item.dev }} address {{ item.mac }} type {{ item.type }} peer name {{ item.peer }}"
+  with_items: "{{ simfabric_links }}"
+
+- name: Run setup again to obtain link info
+  setup:
+
+- name: Start interfaces
+  when: "not ansible_{{ item }}.active"
+  command: "ip link set dev {{ item }} up"
+  with_items:
+  - "{{ simfabric_links | map(attribute='dev') | list }}"
+  - "{{ simfabric_links | map(attribute='peer') | list }}"
+
+- name: Add interfaces to bridges
+  when: "not item.1 in ansible_{{ item.0.name }}.interfaces"
+  command: "brctl addif {{ item.0.name }} {{ item.1 }}"
+  with_subelements:
+   - "{{ simfabric_bridges }}"
+   - interfaces
+
+- name: Check for iptables rule
+  command: "iptables -t nat -C POSTROUTING -s 10.168.0.0/16 ! -d 10.168.0.0/16 -j MASQUERADE"
+  register: iptables_check
+  failed_when: "iptables_check|failed and 'No chain/target/match by that name' not in iptables_check.stderr"
+  tags:
+    - skip_ansible_lint # FIXME: should use iptables module when it supports inversion of ranges
+
+- name: Create iptables rule
+  when: "iptables_check.rc != 0"
+  command: "iptables -t nat -A POSTROUTING -s 10.168.0.0/16 ! -d 10.168.0.0/16 -j MASQUERADE"
+
+# the below will likely work when this pull makes it into ansible:
+# https://github.com/ansible/ansible-modules-extras/pull/1685
+#   - name: Configure iptables
+#     iptables: "table={{ item.table }} chain={{ item.chain }} source={{ item.source }} destination={{ item.dest }} jump={{ item.jump }}"
+#     with_items: "{{ simfabric_iptables }}"
+
+- name: Set kernel sysctl values
+  sysctl:
+    name="{{ item.name }}"
+    value="{{ item.value }}"
+    sysctl_set=yes
+    state=present
+    reload=yes
+  with_items: "{{ simfabric_sysctl }}"
+