From ce5cb10481eea4d9a2538a0d750a9da9e390fcca Mon Sep 17 00:00:00 2001
From: Micah Anderson <micah@riseup.net>
Date: Tue, 29 Jun 2021 15:41:12 -0400
Subject: [PATCH] Handle case where gateway_address6 is not set.

If a gateway does not have ipv6, it should not be setting a gateway_address6 in
the hosts.yml. If it does, then it will get rendered in the eip-service.json and
clients will attempt to contact it.

If you simply removed that configuration from the gateway in hosts.yml, then it
would get rendered in the eip-service.json as `gateway_address6: null` which
would also cause clients to attempt to contact that malformed address.

This commit will strip out any nulls (but not False) from the eip-service.json
and the provider.json.
---
 hosts.yml                   |  1 -
 plugins/action/simplevpn.py | 17 ++++++++++++++---
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/hosts.yml b/hosts.yml
index 8897ec70..f640eb06 100644
--- a/hosts.yml
+++ b/hosts.yml
@@ -15,7 +15,6 @@ hosts:
     ip: 37.218.242.216
     ip_vpn0: 172.16.1.3
     gateway_address: 37.218.242.191
-    gateway_address6: 2001:db8:123::1
     location: Amsterdam
   gateway2:
     ansible_host: 204.13.164.252
diff --git a/plugins/action/simplevpn.py b/plugins/action/simplevpn.py
index 0b44bee5..850043d3 100644
--- a/plugins/action/simplevpn.py
+++ b/plugins/action/simplevpn.py
@@ -27,6 +27,17 @@ def patchObfs4Cert(transports, cert):
     return transports
 
 
+def no_nulls(d):
+    if isinstance(d, dict):
+        return dict(
+            (k, no_nulls(v))
+            for k, v in d.items() if v is not None)
+    elif isinstance(d, list):
+        return [no_nulls(x) for x in d if x]
+    else:
+        return d
+
+
 def produceEipConfig(config, obfs4_state_dir, public_domain, transports):
     if obfs4_state_dir:
         obfs4_cert = open(
@@ -52,11 +63,11 @@ def produceEipConfig(config, obfs4_state_dir, public_domain, transports):
         } for v in config.gateways],
         "openvpn_configuration": config.openvpn,
     }
-        
+
     # Instead of calling the template here, we just return the
     # 'config' object so that Ansible can use it with its own template
     # module.
-    return eip_config
+    return no_nulls(eip_config)
 
 
 def produceProviderConfig(public_domain, provider_api_uri, ca_cert_uri, ca_public_crt):
@@ -104,7 +115,7 @@ def produceProviderConfig(public_domain, provider_api_uri, ca_cert_uri, ca_publi
     # Instead of calling the template here, we just return the
     # 'config' object so that Ansible can use it with its own template
     # module.
-    return provider_config
+    return no_nulls(provider_config)
 
 class ActionModule(ActionBase):
 
-- 
GitLab