0

I'm somehow unable to came up with a solution after spending already few days on this. What I need to do:

  1. Iterate trough a large list of hosts in a .txt file to perform a request to the devices/queries/devices/v1 API endpoint for CrowdStrike to get a so called aid (agent id).

  2. Once I have the aid (there can be multiple aid's for a single host) I need to again iterate but this time over the aid's to the devices/entities/devices/v1 API endpoint to retrieve information such as hostname, last seen plus need to make another call, this time to the policy/combined/reveal-uninstall-token/v1 API endpoint, to get the uninstall token for each of the aid's.

The problem is that the bearer token that I'm generating initially is only valid for 30 minutes, and it needs to by provided with each subsequent request. My idea was to use the try except construct + I'm raising exceptions with Response raise for status as described in correct-way-to-try-except-using-python-requests-module. So I'm hoping that at any point I'm making a request, if it fails due to an HTTP error like 401 Client Error: Unauthorized for url: it would indicate that the token has expired and would call the login() function token = login() within except to make a call to request new a new token and assign it to the token variable and that would allow my to proceed with my for loop since the new token would be provided. The problem I now see, is that for the given host that I'm iterating over, when the token expires, it get's skipped right after the new token is generated (the loop basically continues for the next item within the list). How could I workaround this ?

PS. I know the code is far from perfect, but it's my first steps and would be really nice I someone could lead me here. Was looking and continue and break but continue seams to actually be doing exactly what I'm seeing as behavior with my code and break is not applicable for what I want to do.

    for host in host_list:
        try:
              '''
              1.Get agent id (aid) for each host (NOTE:can return multiple aid's for single host). 
              If the returned list is empty, that means the host is not in CS and skip the 
              processing of the remaining code.
              '''
            query_aid = requests.get(base_url+ 'devices/queries/devices/v1?limit=5000&filter=hostname:' + "'" + host + "'", headers = {"accept": "application/json", "authorization": "Bearer " +  token} )
            query_aid.raise_for_status()
            aux = json.loads(query_aid.text)
            aux2 = aux["resources"]
            if len(aux2) == 0:
                print(host + ' ; ' + 'not in CS')
            else:
                  ''' 
                  for whatever count of aid's returned iterate through each and make a call to the 
                  devices/entities/devices/v1 endpoint to pull hostname and last_seen information, 
                  and make for each aid a call to the policy/combined/reveal-uninstall-token/v1 
                  endpoint to pull the uninstall token for each
                  '''
                for aid in aux2:
                    host_details_request = requests.get(base_url + 'devices/entities/devices/v1?ids=' + aid , headers = {"accept": "application/json", "authorization": "Bearer " +  token})
                    host_details_request.raise_for_status()
                    aux = json.loads(host_details_request.text)
                    last_seen = re.search(r'\d{4}-\d{2}-\d{2}', aux["resources"][0]["last_seen"])
                    request_uninstall_token = requests.post(base_url + 'policy/combined/reveal-uninstall-token/v1', headers = {'Content-type': 'application/json',  "authorization": "Bearer " +  token }, json = { "audit_message": "test api ",  "device_id": aid })
                    request_uninstall_token.raise_for_status()
                    aux3 = json.loads(request_uninstall_token.text)
                    print(aux["resources"][0]["hostname"] + 'uninstall token: ' + aux3["resources"][0]["uninstall_token"] + ';' + last_seen.group(0))
        except requests.exceptions.HTTPError as err:
            print(err)
            token = login()
newby88
  • 27
  • 1
  • 6

1 Answers1

1

Create a function that handles your try code. Then call this function within your expect after the login call

for host in host_list:
    try:
        handle_host(host)
    except requests.exceptions.HTTPError as err:
        print(err)
        token = login()
        handle_host(host)
chatax
  • 990
  • 3
  • 17
  • Hi @chatax please allow me to ask further. Modified the code as you suggested and it works but there's a small "but". The list with aid's for a given host can contain one or even multiple aid's. So when I start to iterate over each of the aid's returned in `for aid in aux2:` what sometimes happens is that an HTTP error is being raised and as per the exception block I request a new token and call again the `handle_host(host)` func. So I en up with duplicate results returned, the one's prior to the HTTP error and by starting to run the code again for the same hostname. 1/2 – newby88 Jun 23 '21 at 09:39
  • Could you please provide some hints how could I potentially address this ? Thank you ! 2/2 – newby88 Jun 23 '21 at 09:39