diff --git a/lib/ansible/modules/cloud/openstack/os_router.py b/lib/ansible/modules/cloud/openstack/os_router.py index f5964b2246f..767d1da183f 100644 --- a/lib/ansible/modules/cloud/openstack/os_router.py +++ b/lib/ansible/modules/cloud/openstack/os_router.py @@ -30,7 +30,9 @@ short_description: Create or Delete routers from OpenStack extends_documentation_fragment: openstack version_added: "1.10" description: - - Create or Delete routers from OpenStack + - Create or Delete routers from OpenStack. Although Neutron allows + routers to share the same name, this module enforces name uniqueness + to be more user friendly. options: state: description: @@ -43,7 +45,7 @@ options: required: true admin_state_up: description: - - desired admin state of the created router . + - Desired admin state of the created router. required: false default: true requirements: ["shade"] @@ -51,75 +53,82 @@ requirements: ["shade"] EXAMPLES = ''' # Creates a router for tenant admin -- os_router: state=present - username=admin - password=admin - project_name=admin - name=router1" +- os_router: + state=present + name=router1 + admin_state_up=True ''' -def _get_router_id(module, neutron): - kwargs = { - 'name': module.params['name'], - } - try: - routers = neutron.list_routers(**kwargs) - except Exception, 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 _create_router(module, neutron): - router = { - 'name': module.params['name'], - 'admin_state_up': module.params['admin_state_up'], - } - try: - new_router = neutron.create_router(dict(router=router)) - except Exception, e: - module.fail_json( msg = "Error in creating router: %s" % e.message) - return new_router['router']['id'] +def _needs_update(router, admin_state_up): + """Decide if the given router needs an update. -def _delete_router(module, neutron, router_id): - try: - neutron.delete_router(router_id) - except: - module.fail_json("Error in deleting the router") - return True + The only attribute of the router that we allow to change is the value + of admin_state_up. Name changes are not supported here. + """ + if router['admin_state_up'] != admin_state_up: + return True + return False + +def _system_state_change(module, router): + """Check if the system state would be changed.""" + state = module.params['state'] + if state == 'absent' and router: + return True + if state == 'present': + if not router: + return True + return _needs_update(router, module.params['admin_state_up']) + return False def main(): argument_spec = openstack_full_argument_spec( - name = dict(required=True), - state = dict(default='present', choices=['absent', 'present']), - admin_state_up = dict(type='bool', default=True), + name=dict(required=True), + admin_state_up=dict(type='bool', default=True), + state=dict(default='present', choices=['absent', 'present']), ) + module_kwargs = openstack_module_kwargs() - module = AnsibleModule(argument_spec, **module_kwargs) + module = AnsibleModule(argument_spec, + supports_check_mode=True, + **module_kwargs) if not HAS_SHADE: module.fail_json(msg='shade is required for this module') + name = module.params['name'] + admin_state_up = module.params['admin_state_up'] + state = module.params['state'] + try: cloud = shade.openstack_cloud(**module.params) - neutron = cloud.neutron_client + router = cloud.get_router(name) + if module.check_mode: + module.exit_json(changed=_system_state_change(module, router)) - if module.params['state'] == 'present': - router_id = _get_router_id(module, neutron) - if not router_id: - router_id = _create_router(module, neutron) - module.exit_json(changed=True, result="Created", id=router_id) + if state == 'present': + if not router: + router = cloud.create_router(name, admin_state_up) + module.exit_json(changed=True, result="created", + id=router['id']) else: - module.exit_json(changed=False, result="success" , id=router_id) + if _needs_update(router, admin_state_up): + cloud.update_router(router['id'], + admin_state_up=admin_state_up) + module.exit_json(changed=True, result="updated", + id=router['id']) + else: + module.exit_json(changed=False, result="success", + id=router['id']) - else: - router_id = _get_router_id(module, neutron) - if not router_id: + elif state == 'absent': + if not router: module.exit_json(changed=False, result="success") else: - _delete_router(module, neutron, router_id) + cloud.delete_router(name) module.exit_json(changed=True, result="deleted") + except shade.OpenStackCloudException as e: module.fail_json(msg=e.message)