CSV to Address External Datagroup File

Code is community submitted, community supported, and recognized as ‘Use At Your Own Risk’.

Short Description

I was today years old when I found out you could upload external data-group files to the GUI.

I couldn't figure out the format, however, until John_Alam pointed me to the K73862425 knowledge article

Problem solved by this Code Snippet

This script takes a CSV file of IPs and/or networks keys, with or without values, and transforms it into an acceptable format for upload to the GUI.

How to use this Code Snippet

python dg_format.py

Code Snippet Meta Information

  1. Version: .1
  2. Coding Language: python 3.11

Full Code Snippet

"""
Source File CSV Contents:
10.10.10.10,
10.10.10.11,hi there
10.10.11.0/24,
10.10.12.0/24,/url/path/here
10.10.13.0/24,

Output File Txt Contents:
host 10.10.10.10,
host 10.10.10.11 := hi there,
network 10.10.11.0/24,
network 10.10.12.0/24 := /url/path/here,
network 10.10.13.0/24,
"""

import csv

with open('dg_ipaddrs.csv', mode='r', encoding='utf-8-sig') as f:
    reader = csv.reader(f)
    ipaddrs = list(reader)


f_out = open('dg_formatted.txt', 'w')

for addr in ipaddrs:
    print(addr)
    if "/" in addr[0] or "mask" in addr[0] or "prefexlen" in addr[0]:
        if addr[1] == '':
            f_out.write(f'network {addr[0]},\n')
        else:
            value = addr[1].split('\n')[0]
            f_out.write(f'network {addr[0]} := {value},\n')
    else:
        if addr[1] == '':
            f_out.write(f'host {addr[0]},\n')
        else:
            value = addr[1].split('\n')[0]
            f_out.write(f'host {addr[0]} := {value},\n')

f_out.close()

 

Published Mar 18, 2023
Version 1.0
  • Thanks Jason! You always seem to find a smart fix for an annoying problem 🙂

    For the minority which doesn't master Python yet (like me 😋) I have concocted a Bash version of it:

    #!/bin/bash
    
    # read IP addresses from CSV file into array
    mapfile -t ipaddrs < dg_ipaddrs.csv
    
    # loop through array and format each IP address
    for addr in "${ipaddrs[@]}"; do
      # remove any leading/trailing whitespace
      addr="$(echo -e "${addr}" | tr -d '[:space:]')"
    
      # split line into fields on comma delimiter
      IFS=',' read -ra fields <<< "$addr"
    
      # check if first field contains a network mask or prefix length. The ${fields[0],,} syntax is used to convert the contents of the fields[0] variable to lowercase.
      if [[ "${fields[0]}" == */* ]] || [[ "${fields[0],,}" == *"mask"* ]] || [[ "${fields[0],,}" == *"prefixlen"* ]]; then
        # check if second field is empty
        if [[ -z "${fields[1]}" ]]; then
          echo "network ${fields[0]},"
        else
          value="${fields[1]}"
          echo "network ${fields[0]} := ${value},"
        fi
      else
        # check if second field is empty
        if [[ -z "${fields[1]}" ]]; then
          echo "host ${fields[0]},"
        else
          value="${fields[1]}"
          echo "host ${fields[0]} := ${value},"
        fi
      fi
    done > dg_formatted.txt
    

     

     

  • I do not know if there is an article but with icall script and getting the data from url like the one for office 365 and scheduling the icall to run every hour will make the solution dynamic:

     

    https://github.com/f5devcentral/f5-office365-ip-url-automation

     

     

    edit:

     

    Also external automation system can use the API to upload the cvs file and then an API for the icall script to trigger the python script as a way to update the files:

     

    https://my.f5.com/manage/s/article/K41763344

    https://clouddocs.f5.com/api/icontrol-rest/APIRef_tm_sys_icall.html