For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

rathid's avatar
rathid
Icon for Nimbostratus rankNimbostratus
Aug 09, 2017

Customer persistence profiles

So in our company we have few of application using custom persistence profile but I can get only get persistence timeout value for standard one which are included in f5 sdk those are ssls, cookies dest_addrs etc etc

 

Is there a way in Python f5 SDK to get those value as well ..

 

Any help.is appreciated

 

Thanks in advance

 

3 Replies

  • Can you expand on what you mean by 'custom persistence profile'? Is this not a custom profile built off methods such as source-address, destination-address, universal, etc?

     

  • A sample code below does something similar to that of tmsh list ltm persistence cookie all-properties.

     

    from sys import argv
    from f5.bigip import ManagementRoot
    
     Management IP, user name, and password
    mgmt = ManagementRoot("127.0.0.1", "admin", "secret")
    
    cookies = mgmt.tm.ltm.persistence.cookies.get_collection()
    print(' of cookie persitence profiles: {}'.format(len(cookies)))
    for c in cookies:
        print('---- {}'.format(c.name))
        for key, value in c.raw.iteritems():
            print('{} = {}'.format(key, value))
    

     

    Sample output (partial). The "cookie-test" is a custom cookie persistence profile, inherited from cookie.

     

    ---- cookie-test
        selfLink = https://localhost/mgmt/tm/ltm/persistence/cookie/~Common~cookie-test?ver=13.0.0
        secure = enabled
        generation = 234
        matchAcrossServices = disabled
        defaultsFromReference = {u'link': u'https://localhost/mgmt/tm/ltm/persistence/cookie/~Common~cookie?ver=13.0.0'}
        cookieName = mycookie
        defaultsFrom = /Common/cookie
        mirror = disabled
        hashLength = 0
        description = none
        method = insert
        _meta_data = {'reduction_forcing_pairs': [('enabled', 'disabled'), ('online', 'offline'), ('vlansEnabled', 'vlansDisabled')], 'container': , 'exclusive_attributes': [], 'allowed_commands': [], 'read_only_attributes': [], 'allowed_lazy_attributes': [], 'uri': u'https://192.168.226.148:443/mgmt/tm/ltm/persistence/cookie/~Common~cookie-test/', 'required_json_kind': 'tm:ltm:persistence‌🍪‌cookiestate', 'bigip': , 'icontrol_version': '', 'required_command_parameters': set([]), 'icr_session': , 'required_load_parameters': set(['name']), 'required_creation_parameters': set(['name']), 'creation_uri_frag': '', 'object_has_stats': True, 'creation_uri_qargs': {u'ver': [u'13.0.0']}, 'minimum_version': '11.5.0'}
        appService = none
        matchAcrossPools = disabled
        alwaysSend = disabled
        fullPath = /Common/cookie-test
        overrideConnectionLimit = disabled
        kind = tm:ltm:persistence‌🍪‌cookiestate
        name = cookie-test
        cookieEncryption = disabled
        partition = Common
        matchAcrossVirtuals = disabled
        expiration = 0
        timeout = 180
        hashOffset = 0
        httponly = enabled
    

     

    If you want the universal persistence profile(s), change the cookies part to universals (note the last "s"). Try other persistence profiles in the similar manner.

  • rathid's avatar
    rathid
    Icon for Nimbostratus rankNimbostratus

    from flask import Flask,render_template,request from flask_cors import CORS, cross_origin import requests import json import re

     

    app=Flask(__name__) help determine the root path CORS(app)

     

    @app.route('/') / means root @also means a decorator connect a return value to a url def index(): from import ManagementRoot from import UnnamedResource requests.packages.urllib3.disable_warnings() devices=['F5 boxes'] devices = ['] count=0 vs=[] for i in range(0,len(devices)): try: b = ManagementRoot(devices[i], 'username', 'password') vs+=b.tm.ltm.virtuals.get_collection(requests_params={'params':'$select=destination'}) for j in range(count,len(vs)): vs[j]['destination'] += "~~" + devices[i] adding the host name to the json file contents so that they can be accessed later count=len(vs) print "success on ",devices[i] except: print "failure on ", devices[i] print "returning json now..." return json.dumps(vs)

     

    @app.route('/myFetch/') def myFetch(myDest): data = {} match = re.search("~~(.*)", myDest) index = match.start() machine = myDest[index+2:] myDest = myDest[0:index]

     

     

    Separation of the machine name
    myDest="/Common/"+myDest
    print "added common which gives:-",myDest
    print "machine is",machine
    
    from f5.bigip import ManagementRoot
    requests.packages.urllib3.disable_warnings()
    mgmt = ManagementRoot(machine, 'username','Password')
    pools = mgmt.tm.ltm.pools.get_collection()
    b = ManagementRoot(machine, 'username','Password')
    
    MAPPING OF DESTINATION TO NAME
    vs = b.tm.ltm.virtuals.get_collection(requests_params={'params': '$select=destination,name'})
    for i in vs:
        if i['destination']==myDest:
            myName=i['name']
            break
    MAPPING OF DESTINATION TO NAME
    requests.packages.urllib3.disable_warnings()
    
    vs = b.tm.ltm.virtuals.virtual.load(partition='Common', name=myName)
    
    data['machine']=machine
    
    clientssl = vs.profiles_s.get_collection()
    data['cert']="NA"
    data['key']="NA"
    data['expiration']="NA"
    for i in range(0,len(clientssl)-1):
         print "this context ",clientssl[i].context, "in this name",clientssl[i].name
        print"checking for ",clientssl[i].name
        if clientssl[i].context == "clientside":
            try:
                print "here",clientssl[i].context,"== clientside for", clientssl[i].name
                certname = clientssl[i].name
                certificate = b.tm.ltm.profile.client_ssls.client_ssl.load(partition='Common', name=certname)
                data['cert']=certificate.certKeyChain[0]['cert']
                data['key']=certificate.certKeyChain[0]['key']
                certexpiration=b.tm.sys.file.ssl_certs.ssl_cert.load(partition='Common',name=strRemover(data['cert']))
                data['expiration']= certexpiration.expirationString
                break
            except:
                data['cert'] = "NA"
                data['key'] = "NA"
                data['expiration'] = "NA"
    
    if hasattr(vs,'persist'):
        vspersisttype = vs.persist[0]['name']
        print "persist type is",vspersisttype
        cookiespersist = b.tm.ltm.persistence.cookies.get_collection(requests_params={'params':'$select=name,timeout'})
        dest_addrspersist = b.tm.ltm.persistence.dest_addrs.get_collection(requests_params={'params': '$select=name,timeout'})
        source_addrspersist = b.tm.ltm.persistence.source_addrs.get_collection(requests_params={'params': '$select=name,timeout'})
        hashspersist = b.tm.ltm.persistence.hashs.get_collection(requests_params={'params': '$select=name,timeout'})
        sipspersist = b.tm.ltm.persistence.sips.get_collection(requests_params={'params': '$select=name,timeout'})
        msrdpspersist = b.tm.ltm.persistence.ssls.get_collection(requests_params={'params': '$select=name,timeout'})
        universalspersist = b.tm.ltm.persistence.universals.get_collection(requests_params={'params': '$select=name,timeout'})
        persist_array=[cookiespersist,dest_addrspersist,source_addrspersist,hashspersist,sipspersist,msrdpspersist,universalspersist]
        data['timeout'] = "cookie isn't configured"
        for j in range(0,len(persist_array)):
            for p in persist_array[j]:
                if p['name']==vspersisttype:
                    data['timeout'] = p['timeout']
    else:
        data['timeout'] = "Persistence isn't configured."
    
    data['name'] = vs.name
    
    persistProfilevalue= vs.persist[0]['name']
    
    if hasattr(vs, 'destination'):
        data['destination'] = strRemover(vs.destination)
    else:
        data['destination'] = "NA"
    
    if hasattr(vs, 'rules'):
        data['rules'] = vs.rules
    else:
        data['rules'] = "NA"
    
    if hasattr(vs, 'pool'):
        for pool in pools:
            if (vs.pool == pool.fullPath):
                data['pool_name'] = pool.name
                data['load_balancing_method'] = pool.loadBalancingMode
    
                if hasattr(pool, 'session'):
                    data['session'] = pool.session
    
                if hasattr(pool, 'state'):
                    data['session'] = pool.state
    
                test = []
    
                for member in pool.members_s.get_collection():
                    test.append(member.name)
                    test.append(member.address)
                    test.append(member.state)
                    test.append(member.session)
                    each = pool.members_s.members.load(partition='Common', name=member.name)
                    currentStats = each.stats.load(partition='Common', name=member.name)
                    test.append(currentStats.entries.get('status.statusReason')['description'])
                    test.append(currentStats.entries.get('serverside.curConns')['value'])
    
                data['member_name'] = test
                if hasattr(pool, 'monitor'):
                    data['monitor'] = strRemover(pool.monitor)
    else:
        data['pool_name'] = "NA"
        data['load_balancing_method'] = "NA"
        data['session'] = "NA"
        data['member_name'] = "NA"
        data['monitor'] = "NA"
    data['error']=0
    json_data = json.dumps(data)
    return json_data
    

     

    def strRemover(str): if str.startswith('/Common/'): return str[8:] else: return str

     

    def colonRemover(str): return re.sub(r":\d+",'', str)

     

    if name == "__main__": only run the line below when this file is run directly app.run(threaded=True) this means that start this web server