quantum_router_gateway 7.27 KB
Newer Older
bennojoy committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
#!/usr/bin/python
#coding: utf-8 -*-

# (c) 2013, Benno Joy <benno@ansibleworks.com>
#
# This module is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this software.  If not, see <http://www.gnu.org/licenses/>.

try:
    from quantumclient.quantum import client
    from keystoneclient.v2_0 import client as ksclient
except ImportError:
    print("failed=True msg='quantumclient and keystone client are required'")
DOCUMENTATION = '''
---
module: quantum_router_gateway
short_description: set/unset a gateway interface for the router with the specified external network
description:
   - Creates/Removes a gateway interface from the router, used to associate a external network with a router to route external traffic.
options:
   login_username:
     description:
        - login username to authenticate to keystone
     required: true
     default: admin
   login_password:
     description:
        - Password of login user
     required: true
Michael DeHaan committed
40
     default: 'yes'
bennojoy committed
41 42 43 44
   login_tenant_name:
     description:
        - The tenant name of the login user
     required: true
Michael DeHaan committed
45
     default: 'yes'
bennojoy committed
46 47
   auth_url:
     description:
48
        - The keystone URL for authentication
bennojoy committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
     required: false
     default: 'http://127.0.0.1:35357/v2.0/'
   region_name:
     description:
        - Name of the region
     required: false
     default: None
   state:
     description:
        - Indicate desired state of the resource
     choices: ['present', 'absent']
     default: present
   router_name:
     description:
        - Name of the router to which the gateway should be attached.
     required: true
     default: None
   network_name:
     description:
        - Name of the external network which should be attached to the router.
     required: true
     default: None
requirements: ["quantumclient", "keystoneclient"]
'''

74 75 76 77 78 79 80
EXAMPLES = '''
# Attach an external network with a router to allow flow of external traffic
- quantum_router_gateway: state=present login_username=admin login_password=admin
                          login_tenant_name=admin router_name=external_router
                          network_name=external_network
'''

bennojoy committed
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
_os_keystone = None
def _get_ksclient(module, kwargs):
    try:
        kclient = ksclient.Client(username=kwargs.get('login_username'),
                                 password=kwargs.get('login_password'),
                                 tenant_name=kwargs.get('login_tenant_name'),
                                 auth_url=kwargs.get('auth_url'))
    except Exception as e:   
        module.fail_json(msg = "Error authenticating to the keystone: %s " % e.message)
    global _os_keystone 
    _os_keystone = kclient
    return kclient 
 

def _get_endpoint(module, ksclient):
    try:
        endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL')
    except Exception as e:
        module.fail_json(msg = "Error getting endpoint for glance: %s" % e.message)
    return endpoint

def _get_quantum_client(module, kwargs):
    _ksclient = _get_ksclient(module, kwargs)
    token = _ksclient.auth_token
    endpoint = _get_endpoint(module, _ksclient)
    kwargs = {
            'token': token,
108
            'endpoint_url': endpoint
bennojoy committed
109 110
    }
    try:
111
        quantum = client.Client('2.0', **kwargs)
bennojoy committed
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
    except Exception as e:
        module.fail_json(msg = "Error in connecting to quantum: %s " % e.message)
    return quantum

def _get_router_id(module, quantum):
    kwargs = {
            'name': module.params['router_name'],
    }
    try:
        routers = quantum.list_routers(**kwargs)
    except Exception as e:
        module.fail_json(msg = "Error in getting the router list: %s " % e.message)
    if not routers['routers']:
            return None
    return routers['routers'][0]['id']

def _get_net_id(quantum, module):
    kwargs = {
Michael DeHaan committed
130 131
        'name':            module.params['network_name'],
        'router:external': True
bennojoy committed
132 133 134 135 136 137 138 139 140 141 142
    }
    try:
        networks = quantum.list_networks(**kwargs)
    except Exception as e:
        module.fail_json("Error in listing quantum networks: %s" % e.message)
    if not networks['networks']:
        return None
    return networks['networks'][0]['id']

def _get_port_id(quantum, module, router_id, network_id):
    kwargs = {
Michael DeHaan committed
143 144
        'device_id': router_id,
        'network_id': network_id,
bennojoy committed
145 146
    }
    try:
147
        ports = quantum.list_ports(**kwargs)
bennojoy committed
148
    except Exception as e:
149
        module.fail_json( msg = "Error in listing ports: %s" % e.message)
bennojoy committed
150
    if not ports['ports']:
151
        return None
bennojoy committed
152 153 154 155
    return ports['ports'][0]['id']

def _add_gateway_router(quantum, module, router_id, network_id):
    kwargs = {
Michael DeHaan committed
156
        'network_id': network_id
bennojoy committed
157 158
    }
    try:
159
        quantum.add_gateway_router(router_id, kwargs)
bennojoy committed
160
    except Exception as e:
161
        module.fail_json(msg = "Error in adding gateway to router: %s" % e.message)
bennojoy committed
162
    return True
163
                
bennojoy committed
164 165 166 167
def  _remove_gateway_router(quantum, module, router_id):
    try:
        quantum.remove_gateway_router(router_id)
    except Exception as e:
Michael DeHaan committed
168
        module.fail_json(msg = "Error in removing gateway to router: %s" % e.message)
bennojoy committed
169
    return True
170
        
bennojoy committed
171 172 173
def main():
    
    module = AnsibleModule(
Michael DeHaan committed
174 175 176 177 178 179 180 181 182
        argument_spec          = dict(
            login_username     = dict(default='admin'),
            login_password     = dict(required=True),
            login_tenant_name  = dict(required='True'),
            auth_url           = dict(default='http://127.0.0.1:35357/v2.0/'),
            region_name        = dict(default=None),
            router_name        = dict(required=True),
            network_name       = dict(required=True),
            state              = dict(default='present', choices=['absent', 'present']),
bennojoy committed
183 184
        ),
    )
185
                
bennojoy committed
186 187
    quantum = _get_quantum_client(module, module.params)
    router_id = _get_router_id(module, quantum)
Michael DeHaan committed
188

bennojoy committed
189
    if not router_id:
Michael DeHaan committed
190 191
        module.fail_json(msg="failed to get the router id, please check the router name")

192
    network_id = _get_net_id(quantum, module)   
bennojoy committed
193
    if not network_id:
Michael DeHaan committed
194
        module.fail_json(msg="failed to get the network id, please check the network name and make sure it is external")
195
                
bennojoy committed
196
    if module.params['state'] == 'present':
197 198
        port_id = _get_port_id(quantum, module, router_id, network_id)
        if not port_id:
Michael DeHaan committed
199 200 201 202
            _add_gateway_router(quantum, module, router_id, network_id)
            module.exit_json(changed=True, result="created")
        module.exit_json(changed=False, result="success")

bennojoy committed
203
    if module.params['state'] == 'absent':
204 205
        port_id = _get_port_id(quantum, module, router_id, network_id)
        if not port_id:
Michael DeHaan committed
206
            module.exit_json(changed=False, result="Success")
207
        _remove_gateway_router(quantum, module, router_id)
Michael DeHaan committed
208
        module.exit_json(changed=True, result="Deleted")
bennojoy committed
209 210 211 212 213

# this is magic, see lib/ansible/module.params['common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
main()