Repository: ansible/ansible-modules-core

Issue:
os_subnet does not support not having a Gateway IP
##### Issue Type:
- Bug Report
##### Ansible Version:

2.0.0
##### Ansible Configuration:

Valid clouds.yml
##### Environment:

N/A
##### Summary:

The [os_subnet module](https://github.com/ansible/ansible-modules-core/blob/devel/cloud/openstack/os_subnet.py) does not support creating / updating a neutron subnet without any gateway IP. This feature is necessary for creating a network that does not route to the outside world.
##### Steps To Reproduce:

```

---
- hosts: 127.0.0.1
  connection: local
  tasks:
    - name: create internal network
      os_network:
        name: "test-private"
        admin_state_up: yes
        shared: no
        cloud: "test"

    - name: add subnet to internal network
      os_subnet:
        name: "test-private-net"
        network_name: "test-private"
        cidr: "10.60.0.0/16"
        enable_dhcp: yes
        gateway_ip: null
        cloud: "test"
```
##### Expected Results:

I'd expect to be able to set some value for `gateway_ip` that results in the equivalent of `--no-gateway-ip`
in the [neutron CLI](http://docs.openstack.org/cli-reference/content/neutronclient_commands.html#neutronclient_subcommand_subnet-create). I check this by inspecting the created network in the Horizon UI and checking that the `Gateway IP` heading shows a dash `-`
##### Actual Results:

Currently, all I can do is leave out `gateway_ip` completely, which sets the gateway IP to the first valid IP in the subnet. I think that the underlying issue is that shade doesn't support `--no-gateway-ip`. I filed a bug for that issue.
https://github.com/openstack-infra/shade/blob/master/shade/__init__.py#L2719
https://storyboard.openstack.org/#!/story/2000328

Add no_gateway_ip option to os_subnet module
no_gateway_ip option can provide subnet that is not having a gateway.
fixes #1880



Discussion:
+1

Really need it!



Resolving patch:
diff --git a/cloud/openstack/os_subnet.py b/cloud/openstack/os_subnet.py
--- a/cloud/openstack/os_subnet.py
+++ b/cloud/openstack/os_subnet.py
@@ -71,6 +71,12 @@
         - The ip that would be assigned to the gateway for this subnet
      required: false
      default: None
+   no_gateway_ip:
+     description:
+        - The gateway IP would not be assigned for this subnet
+     required: false
+     default: false
+     version_added: "2.2"
    dns_nameservers:
      description:
         - List of DNS nameservers for this subnet.
@@ -188,6 +194,7 @@ def _needs_update(subnet, module, cloud):
     pool_start = module.params['allocation_pool_start']
     pool_end = module.params['allocation_pool_end']
     gateway_ip = module.params['gateway_ip']
+    no_gateway_ip = module.params['no_gateway_ip']
     dns = module.params['dns_nameservers']
     host_routes = module.params['host_routes']
     curr_pool = subnet['allocation_pools'][0]
@@ -209,6 +216,8 @@ def _needs_update(subnet, module, cloud):
         new_hr = sorted(host_routes, key=lambda t: t.keys())
         if sorted(curr_hr) != sorted(new_hr):
             return True
+    if no_gateway_ip and subnet['gateway_ip']:
+        return True
     return False
 
 
@@ -232,6 +241,7 @@ def main():
         ip_version=dict(default='4', choices=['4', '6']),
         enable_dhcp=dict(default='true', type='bool'),
         gateway_ip=dict(default=None),
+        no_gateway_ip=dict(default=False, type='bool'),
         dns_nameservers=dict(default=None, type='list'),
         allocation_pool_start=dict(default=None),
         allocation_pool_end=dict(default=None),
@@ -257,6 +267,7 @@ def main():
     enable_dhcp = module.params['enable_dhcp']
     subnet_name = module.params['name']
     gateway_ip = module.params['gateway_ip']
+    no_gateway_ip = module.params['no_gateway_ip']
     dns = module.params['dns_nameservers']
     pool_start = module.params['allocation_pool_start']
     pool_end = module.params['allocation_pool_end']
@@ -278,6 +289,9 @@ def main():
     else:
         pool = None
 
+    if no_gateway_ip and gateway_ip:
+        module.fail_json(msg='no_gateway_ip is not allowed with gateway_ip')
+
     try:
         cloud = shade.openstack_cloud(**module.params)
         if project is not None:
@@ -303,6 +317,7 @@ def main():
                                              enable_dhcp=enable_dhcp,
                                              subnet_name=subnet_name,
                                              gateway_ip=gateway_ip,
+                                             disable_gateway_ip=no_gateway_ip,
                                              dns_nameservers=dns,
                                              allocation_pools=pool,
                                              host_routes=host_routes,
@@ -316,6 +331,7 @@ def main():
                                         subnet_name=subnet_name,
                                         enable_dhcp=enable_dhcp,
                                         gateway_ip=gateway_ip,
+                                        disable_gateway_ip=no_gateway_ip,
                                         dns_nameservers=dns,
                                         allocation_pools=pool,
                                         host_routes=host_routes)


Test patch: