Forum Discussion

Sean_Ellis_9378's avatar
Sean_Ellis_9378
Icon for Nimbostratus rankNimbostratus
Dec 09, 2014

How to parse data group entries using TMSH script

I have a data group where the keys are HTTP paths and the values are a destination URL and a pool. Unfortunately, a group used incorrect pool names and I need to make a mass alteration. My script steps through the pools, finding ones not fitting the nomenclature. I want to create a new pool using the incorrectly-named pool's members, then delete the old pool. Somewhere in that loop I need to update the data group entries.

 

For example: pool.x-service.80 members { 1.1.1.1:5000 {} 2.2.2.2:5000 {} }
Should become: pool.x-service.5000 members { 1.1.1.1:5000 {} 2.2.2.2:5000 {} }

I have that code in place and working. But, there are data group entries like this:

 

ltm data-group class.x-service {
  records {
    /1/ { data this-server.domain.tld:5000/path/1/ pool.x-service.80 }
    /2/ { data that-server.domain.tld:5000/path/2/ pool.y-service.80 }
  }
}

I cannot figure out how to cycle through the data group. I can grab the data group using tmsh::get_config /ltm data-group class.x-service, but not sure how to step through it entry by entry. For pools and pool members, I am doing the following:

 

proc script::run {} {
  foreach {pool} [tmsh::get_config /ltm pool] {
    set poolName [tmsh::get_name ${pool}]
    if {${poolName} ends_with ".80"} {
       Assume the pool is correctly named
      set poolBad 0
      foreach poolMemberInfo [tmsh::get_status /ltm pool ${poolName} detail] {
        foreach poolMember [tmsh::get_field_value $poolMemberInfo members] {
          if {[tmsh::get_field_value ${poolMember} port] != "80"} {
            set poolBad 1
            set goodPort [tmsh::get_field_value ${poolMember} port]
            break
          }
        }
      }
      if {$poolBad} {
         Pool bad - create new pool"
        set newPool [string map {".80" ${goodPort}} ${poolName}]
         puts "no-tmsh create /ltm pool ${newPool} { monitor tcp_half_open }"
        foreach poolMemberInfo [tmsh::get_status /ltm pool ${poolName} detail] {
          foreach poolMember [tmsh::get_field_value $poolMemberInfo members] {
             puts "no-tmsh modify /ltm pool ${newPool} { members add { [tmsh::get_field_value ${poolMember} addr]:[tmsh::get_field_value ${poolMember} port] {} } }"
          }
        }
         edit data group entries referring to the wrong pool
        set datagroup [tmsh::get_config /ltm data-group class.x-service]
        
        puts "no-tmsh delete /ltm pool ${poolName}"
      }
    }
  }
  set datagroup [tmsh::get_config /ltm data-group x-service]
  foreach dataGroupEntry [tmsh::get_field_value $datagroup records] {
    puts "dg: ${dataGroupEntry}"
  }
}

Any assistance appreciated.

 

1 Reply

  • The way I understand this is going to be an 1 time activity. If the of entries are not too large... you can list out the datagroup to a file. Make edits and merge the file back in:

     

    tmsh list ltm data-group internal dgname > /tmp/dgname.contents Edit the /tmp/dgname.contents. Using vi some mass replacements will be easier. tmsh load sys config merge file /tmp/dgname.contents tmsh save sys config