duo-labs / cloudmapper

CloudMapper helps you analyze your Amazon Web Services (AWS) environments.
BSD 3-Clause "New" or "Revised" License
5.96k stars 800 forks source link

"Cannot iterate over null" (common.py, line 161, in get_regions) #747

Closed christophetd closed 4 years ago

christophetd commented 4 years ago

I've been trying out CloudMapper on multiple unrelated AWS accounts and I always get the same error:

Traceback (most recent call last):
  File "cloudmapper.py", line 72, in <module>
    main()
  File "cloudmapper.py", line 66, in main
    commands[command].run(arguments)
  File "/home/christophetd/workspace/aws/cloudmapper/commands/report.py", line 471, in run
    report(accounts, config, args)
  File "/home/christophetd/workspace/aws/cloudmapper/commands/report.py", line 91, in report
    "collection_date": get_collection_date(account)[:10],
  File "/home/christophetd/workspace/aws/cloudmapper/shared/common.py", line 331, in get_collection_date
    account_struct, "iam-get-credential-report", get_us_east_1(account_struct)
  File "/home/christophetd/workspace/aws/cloudmapper/shared/common.py", line 305, in get_us_east_1
    for region_json in get_regions(account):
  File "/home/christophetd/workspace/aws/cloudmapper/shared/common.py", line 161, in get_regions
    regions = pyjq.all(".Regions[]{}".format(region_filter), region_data)
  File "/home/christophetd/workspace/aws/cloudmapper/venv/lib/python3.6/site-packages/pyjq.py", line 49, in all
    return compile(script, vars, library_paths).all(_get_value(value, url, opener))
  File "_pyjq.pyx", line 209, in _pyjq.Script.all (_pyjq.c:2561)
_pyjq.ScriptRuntimeError: Cannot iterate over null (null)

This seems to be because pyjq.all(".Regions[]{}".format(region_filter), region_data) in common.py fails. If I replace the JSON filter with .Regions[]?{}, another exception is thrown:

File "/home/christophetd/workspace/aws/cloudmapper/shared/common.py", line 310, in get_us_east_1
    raise Exception("us-east-1 not found")
Exception: us-east-1 not found

Which is weird because running aws ec2 describe-regions returns:

{
    "Regions": [
        ...
        {                                                                                                                                                                                     
            "OptInStatus": "opt-in-not-required",                                                                                                                                             
            "Endpoint": "ec2.us-east-1.amazonaws.com",                                                                                                                                        
            "RegionName": "us-east-1"                                                                                                                                                         
        }
        ....
    ]
}

After some additional debugging, it appears that region_data returned by query_aws(account, "describe-regions") is an empty dictionary.

Any idea how to solve this? Setup: Python 3.6.9 inside a venv on Ubuntu 18.04 LTS

Thank you!

christophetd commented 4 years ago

Got the solution! In query.py, query_aws is trying to use the account name ("test") to access the JSON file, while apparently it's stored with the account ID. Using the account ID as the account name in config.json seems to do the trick.

Not sure if I did something wrong?

Anyway, thanks for the great tool!

shederman commented 4 years ago

I'm getting this too, and that solution did not work

ghost commented 3 years ago

No solution

sewalton commented 3 years ago

I ran the config.json through jq to get proper formatting and then overwrote the original. That appears to have worked for me.