def main():
    """
    Main function

    :returns: Firewall rule Information
    """
    module = AnsibleModule(argument_spec=dict(
        auth=dict(type='dict'),
        region=dict(default='na', type='str'),
        datacenter=dict(required=True, type='str'),
        name=dict(required=False, type='str'),
        network_domain=dict(required=True, type='str'),
        action=dict(default='ACCEPT_DECISIVELY',
                    choices=['ACCEPT_DECISIVELY', 'DROP']),
        version=dict(required=False, default='IPV4', choices=['IPV4', 'IPV6']),
        protocol=dict(default='TCP', choices=['TCP', 'UDP', 'IP', 'ICMP']),
        src_cidr=dict(required=False, type='str'),
        src_ip_list=dict(required=False, type='str'),
        dst_cidr=dict(required=False, type='str'),
        dst_ip_list=dict(required=False, type='str'),
        src_port_start=dict(required=False, default=None, type='str'),
        src_port_end=dict(required=False, default=None, type='str'),
        src_port_list=dict(required=False, default=None, type='str'),
        dst_port_start=dict(required=False, default=None, type='str'),
        dst_port_end=dict(required=False, default=None, type='str'),
        dst_port_list=dict(required=False, default=None, type='str'),
        enabled=dict(default=True, type='bool'),
        position=dict(default='LAST',
                      choices=['FIRST', 'LAST', 'BEFORE', 'AFTER']),
        position_to=dict(required=False, default=None, type='str'),
        state=dict(default='present', choices=['present', 'absent'])),
                           supports_check_mode=True)
    try:
        credentials = get_credentials(module)
    except ImportError as e:
        module.fail_json(msg='{0}'.format(e))
    fw_rule_exists = None
    name = module.params['name']
    network_domain_name = module.params['network_domain']
    datacenter = module.params['datacenter']
    state = module.params['state']
    src_cidr = dst_cidr = None

    # Check Imports
    if not HAS_IPADDRESS:
        module.fail_json(msg='Missing Python module: ipaddress')

    # Check the region supplied is valid
    regions = get_regions()
    if module.params.get('region') not in regions:
        module.fail_json(
            msg='Invalid region. Regions must be one of {0}'.format(regions))

    if credentials is False:
        module.fail_json(msg='Error: Could not load the user credentials')

    try:
        client = NTTMCPClient(credentials, module.params.get('region'))
    except NTTMCPAPIException as e:
        module.fail_json(msg=e.msg)

    # Check to see the CIDR provided is valid
    if module.params.get('src_cidr'):
        try:
            src_cidr = ip_net(unicode(module.params.get('src_cidr')))
        except (AddressValueError, ValueError) as e:
            module.fail_json(msg='Invalid source CIDR format {0}: {1}'.format(
                module.params.get('src_cidr'), e))
    if module.params.get('dst_cidr'):
        try:
            dst_cidr = ip_net(unicode(module.params.get('dst_cidr')))
        except (AddressValueError, ValueError) as e:
            module.fail_json(
                msg='Invalid destination CIDR format {0}: {1}'.format(
                    module.params.get('dst_cidr'), e))

    # Get the CND object based on the supplied name
    try:
        network = client.get_network_domain_by_name(datacenter=datacenter,
                                                    name=network_domain_name)
        network_domain_id = network.get('id')
    except (KeyError, IndexError, AttributeError, NTTMCPAPIException) as e:
        module.fail_json(
            msg='Failed to find the Cloud Network Domains - {0}'.format(e),
            exception=traceback.format_exc())

    # If a firewall rule name is provided try and locate the rule
    if name:
        try:
            fw_rule_exists = client.get_fw_rule_by_name(
                network_domain_id, name)
        except NTTMCPAPIException as e:
            module.fail_json(
                msg='Could not locate the existing firewall rule - {0}'.format(
                    e),
                exception=traceback.format_exc())

    try:
        if state == 'present':
            if fw_rule_exists:
                update_fw_rule(module, client, network_domain_id,
                               fw_rule_exists, src_cidr, dst_cidr)
            else:
                # Implement check_mode
                if module.check_mode:
                    module.exit_json(msg='This firewall rule will be created',
                                     data=module.params)
                create_fw_rule(module, client, network_domain_id, src_cidr,
                               dst_cidr)
        elif state == 'absent':
            if not fw_rule_exists:
                module.exit_json(
                    msg='The firewall rule {0} was not found'.format(name))
            # Implement check_mode
            if module.check_mode:
                module.exit_json(msg='This firewall rule will be removed',
                                 data=fw_rule_exists)
            delete_fw_rule(module, client, network_domain_id, name)
    except NTTMCPAPIException as e:
        module.fail_json(
            msg='Could not operate on the firewall rule - {0}'.format(e),
            exception=traceback.format_exc())
Exemple #2
0
def main():
    """
    Main function
    :returns: Ansible Gateway Host Information
    """
    module = AnsibleModule(
        argument_spec=dict(
            auth=dict(type='dict'),
            region=dict(default='na', type='str'),
            datacenter=dict(required=True, type='str'),
            network_domain=dict(required=True, type='str'),
            vlan=dict(required=True, type='str'),
            name=dict(required=False, default='ansible_gw', type='str'),
            password=dict(default=None, required=False, type='str'),
            image=dict(required=False, type='str'),
            ipv4=dict(default=None, required=False, type='str'),
            src_ip=dict(default='ANY', required=False, type='str'),
            src_prefix=dict(default=None, required=False, type='str'),
            state=dict(default='present', choices=['present', 'absent']),
            wait=dict(required=False, default=True, type='bool'),
            wait_time=dict(required=False, default=1200, type='int'),
            wait_poll_interval=dict(required=False, default=30, type='int')
        )
    )

    try:
        credentials = get_credentials(module)
    except ImportError as e:
        module.fail_json(msg='{0}'.format(e))
    name = module.params.get('name')
    datacenter = module.params.get('datacenter')
    state = module.params.get('state')
    network_domain_name = module.params.get('network_domain')
    vlan_name = module.params.get('vlan')
    vlan_id = ansible_gw = None
    return_data = {}
    changed = False

    # Check the region supplied is valid
    regions = get_regions()
    if module.params.get('region') not in regions:
        module.fail_json(msg='Invalid region. Regions must be one of {0}'.format(regions))

    if credentials is False:
        module.fail_json(msg='Error: Could not load the user credentials')

    client = NTTMCPClient(credentials, module.params['region'])

    # Get the CND object based on the supplied name
    try:
        network = client.get_network_domain_by_name(datacenter=datacenter, name=network_domain_name)
        network_domain_id = network.get('id')
    except (KeyError, IndexError, AttributeError, NTTMCPAPIException) as exc:
        module.fail_json(msg='Failed to find the Cloud Network Domain - {0}'.format(exc))

    # Get the VLAN object based on the supplied name
    try:
        vlan = client.get_vlan_by_name(datacenter=datacenter, network_domain_id=network_domain_id, name=vlan_name)
        vlan_id = vlan.get('id')
    except (KeyError, IndexError, AttributeError, NTTMCPAPIException) as exc:
        module.fail_json(msg='Failed to get a list of VLANs - {0}'.format(exc), exception=traceback.format_exc())

    # Check if the server exists based on the supplied name
    try:
        ansible_gw = client.get_server_by_name(datacenter, network_domain_id, vlan_id, name)
    except (KeyError, IndexError, AttributeError, NTTMCPAPIException) as exc:
        module.fail_json(msg='Failed attempting to locate any existing server - {0}'.format(exc))

    # Handle the case where the gateway already exists. This could mean a playbook re-run
    # If the server exists then we need to check:
    #   a public IP is allocated and if not get the next one
    #   the NAT rule is present and correct and if not update/create it
    #   the Firewall rule is present and correct and if not update/create it
    if state == 'present' and ansible_gw:
        try:
            ansible_gw_private_ipv4 = ansible_gw.get('networkInfo').get('primaryNic').get('privateIpv4')
            # Check if the NAT rule exists and if not create it
            nat_result = client.get_nat_by_private_ip(network_domain_id, ansible_gw.get('networkInfo').get('primaryNic').get('privateIpv4'))
            if nat_result:
                public_ipv4 = nat_result.get('externalIp')
            else:
                public_ipv4 = client.get_next_public_ipv4(network_domain_id).get('ipAddress')
                create_nat_rule(module, client, network_domain_id, ansible_gw_private_ipv4, public_ipv4)
                changed = True
            # Check if the Firewall rule exists and if not create it
            fw_result = client.get_fw_rule_by_name(network_domain_id, ACL_RULE_NAME)
            if fw_result:
                update_fw_rule(module, client, fw_result, network_domain_id, public_ipv4)
            else:
                create_fw_rule(module, client, network_domain_id, public_ipv4)
                changed = True
            return_data['server_id'] = ansible_gw.get('id')
            return_data['password'] = ansible_gw.get('password', None)
            return_data['internal_ipv4'] = ansible_gw.get('networkInfo').get('primaryNic').get('privateIpv4')
            return_data['ipv6'] = ansible_gw.get('networkInfo').get('primaryNic').get('ipv6')
            return_data['public_ipv4'] = public_ipv4
            module.exit_json(changed=changed, data=return_data)
        except (KeyError, IndexError, AttributeError) as e:
            module.fail_json(msg='Could not ascertain the current server state: {0}'.format(e))
    elif state == 'present' and not ansible_gw:
        try:
            ansible_gw = create_server(module, client, network_domain_id, vlan_id)
            changed = True
            ansible_gw_private_ipv4 = ansible_gw.get('networkInfo').get('primaryNic').get('privateIpv4')
            # Check if the NAT rule exists and if not create it
            nat_result = client.get_nat_by_private_ip(network_domain_id, ansible_gw_private_ipv4)
            if nat_result:
                public_ipv4 = nat_result.get('externalIp')
            else:
                public_ipv4 = client.get_next_public_ipv4(network_domain_id).get('ipAddress')
                create_nat_rule(module, client, network_domain_id, ansible_gw_private_ipv4, public_ipv4)
                changed = True
            # Check if the Firewall rule exists and if not create it
            fw_result = client.get_fw_rule_by_name(network_domain_id, ACL_RULE_NAME)
            if fw_result:
                update_fw_rule(module, client, fw_result, network_domain_id, public_ipv4)
            else:
                create_fw_rule(module, client, network_domain_id, public_ipv4)
                changed = True
            return_data['server_id'] = ansible_gw.get('id')
            return_data['password'] = ansible_gw.get('password')
            return_data['internal_ipv4'] = ansible_gw_private_ipv4
            return_data['ipv6'] = ansible_gw.get('networkInfo').get('primaryNic').get('ipv6')
            return_data['public_ipv4'] = public_ipv4
            sleep(10)
            module.exit_json(changed=changed, data=return_data)
        except (KeyError, IndexError, AttributeError, NTTMCPAPIException) as exc:
            module.fail_json(changed=changed, msg='Failed to create/update the Ansible gateway - {0}'.format(exc), exception=traceback.format_exc())
    elif state == 'absent':
        nat_result = public_ipv4 = None
        try:
            # Check if the server exists and remove it
            if ansible_gw:
                delete_server(module, client, ansible_gw)
            # Check if the Firewall rule exists and if not create it
            fw_result = client.get_fw_rule_by_name(network_domain_id, ACL_RULE_NAME)
            if fw_result:
                delete_fw_rule(module, client, network_domain_id, fw_result.get('name'))
            '''
            Cases may exist where the only either the NAT private or public address maybe know so
            two ensure we've checked all possible options we will search by both
            The private address can be found from the server/ansible_gw object but the public address
            can only be determined by the firewall rule desintation value
            '''
            if ansible_gw:
                ansible_gw_private_ipv4 = ansible_gw.get('networkInfo').get('primaryNic').get('privateIpv4')
                nat_result = client.get_nat_by_private_ip(network_domain_id, ansible_gw_private_ipv4)
                if nat_result:
                    public_ipv4 = nat_result.get('externalIp')
            elif fw_result:
                public_ipv4 = fw_result.get('destination').get('ip').get('address')
                nat_result = client.get_nat_by_public_ip(network_domain_id, public_ipv4)

            if nat_result:
                delete_nat_rule(module, client, nat_result.get('id'))
            if public_ipv4:
                public_ip_block = client.get_public_ipv4_by_ip(network_domain_id, public_ipv4)
                if public_ip_block:
                    if not client.check_public_block_in_use(network_domain_id, public_ip_block.get('baseIp')):
                        delete_public_ipv4(module, client, public_ip_block.get('id'))
        except (KeyError, IndexError, AttributeError, NTTMCPAPIException) as e:
            module.fail_json(changed=changed, msg='Failed to remove the Ansible gateway configuration - {0}'.format(e))

        module.exit_json(changed=True, msg='The Ansible gateway and associated NAT and firewall rules have been removed')
    else:
        module.exit_json(changed=False, msg='Nothing to remove')