Improve bastion setup

 * Use a single control socket.
   - Use the bastion hostname in proxy commands instead of IP
   - CI agents which need bastions don't start an extra control socket

 * Avoid using a relative ./ssh.cfg file
   - Instead users can include it in their `~/.ssh/config` file
   - Now it is possible to ssh in without having to be in the source directory
diff --git a/README.md b/README.md
index 1604aaa..1702311 100644
--- a/README.md
+++ b/README.md
@@ -56,6 +56,7 @@
 
 1. Provision the VM using https://cloud.ibm.com
 2. Run `./tools/gen-config`
+2. Include the generated `ssh.cfg` in `~/.ssh/config` file
 3. Run `ansible-playbook bastions.yml`
 
 Bastion names should follow this pattern:
@@ -123,16 +124,18 @@
 Useful Commands:
 ---
 
+(Assuming the generated `ssh.cfg` was included in `~/.ssh/config`)
+
 If you want to ssh directly to a node, you can do:
 
 ```bash
-$ ssh -F ssh.cfg $hostname
+$ ssh $hostname
 ```
 
 I.e.,
 
 ```bash
-$ ssh -F ssh.cfg couchdb-worker-x86-64-debian-dal-1-01
+$ ssh couchdb-worker-x86-64-debian-dal-1-01
 ```
 
 
diff --git a/production b/production
index 323cc27..26d206d 100644
--- a/production
+++ b/production
@@ -30,7 +30,8 @@
             vpc: s922
             zone: none
           ip_addrs:
-            bastion: null
+            bastion_host: null
+            bastion_ip: null
             private: 192.168.151.219
             public: 158.175.162.219
           system:
@@ -47,7 +48,8 @@
             vpc: couchdb-ci-farm-vpc
             zone: us-south-1
           ip_addrs:
-            bastion: 169.48.153.153
+            bastion_host: couchdb-bastion-x86-64-debian-dal-1-01
+            bastion_ip: 169.48.153.153
             private: 10.240.0.16
             public: null
           system:
@@ -64,7 +66,8 @@
             vpc: couchdb-ci-farm-vpc
             zone: us-south-1
           ip_addrs:
-            bastion: 169.48.153.153
+            bastion_host: couchdb-bastion-x86-64-debian-dal-1-01
+            bastion_ip: 169.48.153.153
             private: 10.240.0.15
             public: null
           system:
@@ -81,7 +84,8 @@
             vpc: couchdb-ci-farm-vpc
             zone: us-south-1
           ip_addrs:
-            bastion: 169.48.153.153
+            bastion_host: couchdb-bastion-x86-64-debian-dal-1-01
+            bastion_ip: 169.48.153.153
             private: 10.240.0.14
             public: null
           system:
@@ -98,7 +102,8 @@
             vpc: couchdb-ci-farm-vpc
             zone: us-south-1
           ip_addrs:
-            bastion: 169.48.153.153
+            bastion_host: couchdb-bastion-x86-64-debian-dal-1-01
+            bastion_ip: 169.48.153.153
             private: 10.240.0.13
             public: null
           system:
@@ -115,7 +120,8 @@
             vpc: couchdb-ci-farm-vpc
             zone: us-south-1
           ip_addrs:
-            bastion: 169.48.153.153
+            bastion_host: couchdb-bastion-x86-64-debian-dal-1-01
+            bastion_ip: 169.48.153.153
             private: 10.240.0.12
             public: null
           system:
@@ -132,7 +138,8 @@
             vpc: couchdb-ci-farm-vpc
             zone: us-south-1
           ip_addrs:
-            bastion: 169.48.153.153
+            bastion_host: couchdb-bastion-x86-64-debian-dal-1-01
+            bastion_ip: 169.48.153.153
             private: 10.240.0.10
             public: null
           system:
@@ -149,7 +156,8 @@
             vpc: couchdb-ci-farm-vpc
             zone: us-south-1
           ip_addrs:
-            bastion: 169.48.153.153
+            bastion_host: couchdb-bastion-x86-64-debian-dal-1-01
+            bastion_ip: 169.48.153.153
             private: 10.240.0.8
             public: null
           system:
@@ -166,7 +174,8 @@
             vpc: couchdb-ci-farm-vpc
             zone: us-south-1
           ip_addrs:
-            bastion: 169.48.153.153
+            bastion_host: couchdb-bastion-x86-64-debian-dal-1-01
+            bastion_ip: 169.48.153.153
             private: 10.240.0.4
             public: null
           system:
@@ -179,7 +188,8 @@
             name: couchdb01
             subnet: null
           ip_addrs:
-            bastion: null
+            bastion_host: null
+            bastion_ip: null
             public: 148.100.113.138
           system:
             arch: s390x
diff --git a/ssh.cfg b/ssh.cfg
index af1ba3a..f53d64d 100644
--- a/ssh.cfg
+++ b/ssh.cfg
@@ -20,74 +20,42 @@
   Hostname 10.240.0.16
   User root
   StrictHostKeyChecking no
-  ProxyCommand /usr/bin/ssh -F ./ssh.cfg -W %h:%p -q root@169.48.153.153
-  ControlMaster auto
-  ControlPath /tmp/ansible-%r@%h:%p
-  ControlPersist 30m
-
+  ProxyCommand /usr/bin/ssh -W %h:%p -q root@couchdb-bastion-x86-64-debian-dal-1-01
 Host couchdb-worker-x86-64-debian-dal-1-02
   Hostname 10.240.0.15
   User root
   StrictHostKeyChecking no
-  ProxyCommand /usr/bin/ssh -F ./ssh.cfg -W %h:%p -q root@169.48.153.153
-  ControlMaster auto
-  ControlPath /tmp/ansible-%r@%h:%p
-  ControlPersist 30m
-
+  ProxyCommand /usr/bin/ssh -W %h:%p -q root@couchdb-bastion-x86-64-debian-dal-1-01
 Host couchdb-worker-x86-64-debian-dal-1-03
   Hostname 10.240.0.14
   User root
   StrictHostKeyChecking no
-  ProxyCommand /usr/bin/ssh -F ./ssh.cfg -W %h:%p -q root@169.48.153.153
-  ControlMaster auto
-  ControlPath /tmp/ansible-%r@%h:%p
-  ControlPersist 30m
-
+  ProxyCommand /usr/bin/ssh -W %h:%p -q root@couchdb-bastion-x86-64-debian-dal-1-01
 Host couchdb-worker-x86-64-debian-dal-1-04
   Hostname 10.240.0.13
   User root
   StrictHostKeyChecking no
-  ProxyCommand /usr/bin/ssh -F ./ssh.cfg -W %h:%p -q root@169.48.153.153
-  ControlMaster auto
-  ControlPath /tmp/ansible-%r@%h:%p
-  ControlPersist 30m
-
+  ProxyCommand /usr/bin/ssh -W %h:%p -q root@couchdb-bastion-x86-64-debian-dal-1-01
 Host couchdb-worker-x86-64-debian-dal-1-05
   Hostname 10.240.0.12
   User root
   StrictHostKeyChecking no
-  ProxyCommand /usr/bin/ssh -F ./ssh.cfg -W %h:%p -q root@169.48.153.153
-  ControlMaster auto
-  ControlPath /tmp/ansible-%r@%h:%p
-  ControlPersist 30m
-
+  ProxyCommand /usr/bin/ssh -W %h:%p -q root@couchdb-bastion-x86-64-debian-dal-1-01
 Host couchdb-worker-x86-64-debian-dal-1-06
   Hostname 10.240.0.10
   User root
   StrictHostKeyChecking no
-  ProxyCommand /usr/bin/ssh -F ./ssh.cfg -W %h:%p -q root@169.48.153.153
-  ControlMaster auto
-  ControlPath /tmp/ansible-%r@%h:%p
-  ControlPersist 30m
-
+  ProxyCommand /usr/bin/ssh -W %h:%p -q root@couchdb-bastion-x86-64-debian-dal-1-01
 Host couchdb-worker-x86-64-debian-dal-1-07
   Hostname 10.240.0.8
   User root
   StrictHostKeyChecking no
-  ProxyCommand /usr/bin/ssh -F ./ssh.cfg -W %h:%p -q root@169.48.153.153
-  ControlMaster auto
-  ControlPath /tmp/ansible-%r@%h:%p
-  ControlPersist 30m
-
+  ProxyCommand /usr/bin/ssh -W %h:%p -q root@couchdb-bastion-x86-64-debian-dal-1-01
 Host couchdb-worker-x86-64-debian-dal-1-08
   Hostname 10.240.0.4
   User root
   StrictHostKeyChecking no
-  ProxyCommand /usr/bin/ssh -F ./ssh.cfg -W %h:%p -q root@169.48.153.153
-  ControlMaster auto
-  ControlPath /tmp/ansible-%r@%h:%p
-  ControlPersist 30m
-
+  ProxyCommand /usr/bin/ssh -W %h:%p -q root@couchdb-bastion-x86-64-debian-dal-1-01
 Host couchdb01
   Hostname 148.100.113.138
   User ubuntu
diff --git a/tools/gen-config b/tools/gen-config
index 2af4933..b60d117 100755
--- a/tools/gen-config
+++ b/tools/gen-config
@@ -230,7 +230,8 @@
             "subnet": net_iface["subnet"]["name"]
         },
         "ip_addrs": {
-            "bastion": None,
+            "bastion_ip": None,
+            "bastion_host": None,
             "public": None,
             "private": get_private_ip(instance)
         },
@@ -262,7 +263,8 @@
             "subnet" : None
         },
         "ip_addrs": {
-            "bastion": None,
+            "bastion_ip": None,
+            "bastion_host": None,
             "public": instance["addresses"][0]["externalIP"],
             "private": instance["addresses"][0]["ip"]
         },
@@ -287,7 +289,8 @@
             "subnet": None
         },
         "ip_addrs": {
-            "bastion": None,
+            "bastion_ip": None,
+            "bastion_host": None,
             "public": instance["ip_addr"]
         },
         "system": instance["system"]
@@ -312,14 +315,16 @@
         subnet = bastion["instance"]["subnet"]
         ip_addr = bastion["ip_addrs"]["public"]
         assert subnet not in subnets
-        subnets[subnet] = ip_addr
+        subnets[subnet] = (ip_addr, host)
     for (host, ci_agent) in ci_agents.items():
         if ci_agent["system"]["arch"] in ["power", "s390x"]:
             # Power & s390x an external IP without bastions
             continue
         subnet = ci_agent["instance"]["subnet"]
         assert subnet in subnets
-        ci_agent["ip_addrs"]["bastion"] = subnets[subnet]
+        (bastion_ip, bastion_host) = subnets[subnet]
+        ci_agent["ip_addrs"]["bastion_ip"] = bastion_ip
+        ci_agent["ip_addrs"]["bastion_host"] = bastion_host
 
 
 def write_inventory(fname, bastions, ci_agents):
@@ -355,11 +360,7 @@
           Hostname {ip_addr}
           User {user}
           StrictHostKeyChecking no
-          ProxyCommand /usr/bin/ssh -F ./ssh.cfg -W %h:%p -q root@{bastion_ip}
-          ControlMaster auto
-          ControlPath /tmp/ansible-%r@%h:%p
-          ControlPersist 30m
-
+          ProxyCommand /usr/bin/ssh -W %h:%p -q root@{bastion_host}
         """)
     with open(filename, "w") as handle:
         for host, info in sorted(bastions.items()):
@@ -380,11 +381,14 @@
                 }
                 entry = bastion_tmpl.format(**args)
             else:
+                bastion_ip =  info["ip_addrs"]["bastion_ip"]
+                bastion_host = info["ip_addrs"]["bastion_host"]
                 args = {
                     "user": "root",
                     "host": host,
                     "ip_addr": info["ip_addrs"]["private"],
-                    "bastion_ip": info["ip_addrs"]["bastion"]
+                    "bastion_ip": bastion_ip,
+                    "bastion_host": bastion_host
                 }
                 entry = ci_agent_tmpl.format(**args)
             handle.write(entry)
@@ -430,7 +434,10 @@
     assign_bastions(bastions, ci_agents)
 
     write_inventory(args.inventory, bastions, ci_agents)
-    write_ssh_cfg(args.ssh_cfg, bastions, ci_agents)
+    sshf = args.ssh_cfg
+    write_ssh_cfg(sshf, bastions, ci_agents)
+    sshf_full = os.path.abspath(os.path.expanduser(os.path.expandvars(sshf)))
+    print("Add 'Include %s' to your ~/.ssh/config file" % sshf_full)
 
 
 if __name__ == "__main__":