Forum Discussion

touriel's avatar
touriel
Icon for Nimbostratus rankNimbostratus
Feb 07, 2024

Issue with a simple Bash Script for adding an iRule to a list of Virtual Servers.

Hello Community, 

I am having an issue with a bash script for an F5 BIG-IP Load Balancer, intended to read and iterate over a .txt list of Virtual Server names, look up the partition for a given VS, and add an iRule to it. When running the script I am only hitting the outermost 'else' statement for being unable to find the partition and VS name. My script logic is based on F5 Support solution K41961653:

 

<p>
#!/bin/bash

# Prompt the user for the iRule name and read it into the 'new' variable
echo "Please enter the iRule name:"
read new

noneRules='rules none'

while IFS= read -r vs_name; do
  # Retrieve the partition and virtual server name
  full_vs_info=$(tmsh -c "cd /; list ltm virtual recursive" | grep "$vs_name" | grep -m1 "^ltm virtual")
  echo "Full VS Info Debug: $full_vs_info"

  # Extract the partition and virtual server name from the retrieved information
  if [[ $full_vs_info =~ ltm\ virtual\ (.+)/(.+) ]]; then
    partition="${BASH_REMATCH[1]}"
    vs_name="${BASH_REMATCH[2]}"
    
    # Format the tmsh command to include the partition
    rule=$(tmsh list ltm virtual /$partition/$vs_name rules | egrep -v "\{|\}" | xargs)
    
    if [[ "$rule" == "$noneRules" ]]; then
      tmsh modify ltm virtual /$partition/$vs_name rules { $new }
      echo "iRule $new was added to $vs_name in partition $partition"
    else#
      tmsh modify ltm virtual /$partition/$vs_name rules { $rule $new }
      echo "iRules $rule were conserved and added $new to $vs_name in partition $partition"
    fi
  else
    echo "Could not find partition and virtual server name for $vs_name"
  fi
done < /shared/tmp/test_list.txt

tmsh save sys config
</p>

 

As far as I was able to troubleshoot, the problem I am encountering appears to be with line 11 of my script where I attempt to assign the string "ltm virtual SomePartition/VS_Example.com {" to the "full_vs_info" variable using:

full_vs_info=$(tmsh -c "cd /; list ltm virtual recursive" | grep "$vs_name" | grep -m1 "^ltm virtual")

When I run the tmsh command [tmsh -c "cd /; list ltm virtual recursive" | grep "VS_Example.com" | grep -m1 "^ltm virtual"] on its own, from the F5's Bash shell, I am getting the output I expect:

"ltm virtual SomePartition/VS_Example.com {"

However, when I run the script with the debug echo , it only outputs "Full VS Info Debug:", and ends the script with "Could not find partition and virtual server name for $vs_name" and a sys config save.

I am attempting to run this on a BIG-IP, version 15.1.10.2, build 0.44.2. 

I am quite new to both Bash scripting and F5 LBs. All feedback and criticism is highly appreciated! Thanks in advance!

2 Replies

  • It looks like your regex is a little too greedy and is matching the ending curly brace of the vs name.

    One universal "how to make simple regexes" approach is to avoid using (.+) which tends to match too much stuff, and using this sort of thing instead: ([^ ]). The square brackets mean "characters in the set of" and caret means "not", so ([^ ]+) means "capture one or more characters that are not a space". This is a safe way to match a value where you know the delimiter beforehand: VSs won't have a space and will always be followed by a space.

    So your regex becomes: 

      if [[ $full_vs_info =~ ltm\ virtual\ ([^\/]+)/([^ ]+) ]]; then
    

     

    A few other things:

    • You can pass an "-p" to get read to give the user a prompt which will make it a little easier to use
    • TMSH has a "one-line" argument that tells it to list each config object in its own line to make the kind of text processing you're doing here easier, for example "tmsh list /ltm virtual recursive one-line"

       

  • Use echo statements to debug. Many example scripts are “broken” because they don’t take into account partitions. Most of the time assumption is that everything is in the shared /Common partition. So, you need to make sure all object names are “fully qualified” with the proper partition name.

    Also, my preference is to use the RESTfull APIs using python scripts. Way of the future especially as things transition to NEXT.