Forum Discussion

FrankG's avatar
3 years ago
Solved

Confusing requirements and output get_admin_list using the SDK - Guidance requested

Hello all,

I'm trying to gather a list of users (role agnostic) and include only a specific set of fields in my output, filtered by a last_login_on timeframe.  When I attempt to do this through the API via requests.get(url) via a python script (aka without invoking the SDK) it works just fine with no extra required fields in the output.  However, when using the SDK API Class, I am required to include 'role,username,password,email' otherwise I receive an error.  To make matters more confusing, when I add the required fields, the output then doesn't include just those specified fields, it includes all fields and ignores what I'm asking for.

This leads me to two questions:

  • Am I missing something regarding the SDK's logic or use? ... paraphrased... Why can't I only request the fields I care about like with the regular requests.get API calls?
  • What benefit is there to requiring field for a "get"?

Thanks for your responses in advance,
Frank

https://www.logicmonitor.com/support-files/rest-api-developers-guide/sdks/docs/#api-LM-getAdminList doc (for reference and websearchability)

From the above link - 


 

  • Anonymous's avatar
    Anonymous
    3 years ago

    Here you go. This uses my lmwrapper helper script, so if you're not using that, you'd need to setup the api object manually. Just set the month, day, and year variables to the date you'd want. 

    from lm import lm
    from datetime import datetime
    
    #datetime before which to consider users inactive
    month = 10
    day = 1
    year = 2021
    inactivedate = datetime(year,month,day,0,0,0)
    
    #these next few variables are for use in pagination
    size = 1000
    offset = 0
    results = []
    endfound = False
    while not endfound:
        users = lm.get_admin_list(size=size, offset=offset).items #fetch a page
        results.extend(users) #add the fetched data to the tally
        offset += size #figure out the next page range
        endfound = len(users) < size #check to see if we fetched an incomplete page (e.g. we're done)
    
    for user in results:
        lastlogin = datetime.utcfromtimestamp(user.last_login_on) #convert the string to a datetime object so we can compare it to our inactivedate
        if lastlogin < inactivedate and user.status != 'suspended':
            print(f"Disabling {user.username} (id={user.id}), last login time: {lastlogin.strftime('%Y-%m-%d')}")
            response = lm.patch_admin_by_id(user.id, body={'status':'suspended'})
            print(f"{user.username} (id={user.id}) is now {response.status}")

     

14 Replies

  • On 2/7/2022 at 9:58 AM, FrankG said:

    Amazingly done.  Very straightforward now that I'm looking at it.  Seemed like more work than that, but this is why you're the master.  I see your note about the filtering returning an extra unrelated entry for some reason.  I see that when using the API directly also.  Strangeness.

    I'll have to fold that bit in and give it a test.  I've also done some enhancements from this end that may be useful for others (excluding certain users with specific role assignments, usernames, or API Only users).  I'll do the needful, decruft, and share shortly.  Thanks again Stuart!


    DISREGARD THIS POST - I FOUND A TYPO 
    Seeing some strange behavior from that audit log {log.happened_on} > comparison.  I added some code to output the test result.  As the output from the 

    filter="_all~\"Add a new account\"

      - was also squirrelly from the API, I'm very glad I checked.  Screenshot attached below.  It seems like it can't compare epoch times correctly, but it's intermittent at first before failing completely beyond a certain user.  Very strange - any ideas?

  • Anonymous's avatar
    Anonymous

    You might try casting them both to integers, it's probable that log.happened_on is coming in as a string. Python should recast it, but you can't go wrong making sure.

    Also, there may be some timezone funkiness going on there. I only had a handful of users in the portal i tested against. You might try outputting the human readable log.happened_on as compared to the human readable inactivedate value. That's where i'd start.

  • 21 hours ago, Stuart Weenig said:

    You might try casting them both to integers, it's probable that log.happened_on is coming in as a string. Python should recast it, but you can't go wrong making sure.

    Also, there may be some timezone funkiness going on there. I only had a handful of users in the portal i tested against. You might try outputting the human readable log.happened_on as compared to the human readable inactivedate value. That's where i'd start.

    It is sorted out now.  I made a typo at some point that didn't cause the script to fail and it basically made the comparison not work correctly.  Thanks again for your stellar help @Stuart Weenig

  • Anonymous's avatar
    Anonymous

    Oh right, I didn't think my code was buggy...

    I Know Of Course GIF by Yevbel