Skip to content

KeyError raised from OktaCollection.is_formed() after calling okta_client.list_network_zones() #448

@tjobarow

Description

@tjobarow

Within my environment, when I call okta_client.list_network_zones(), I see a KeyError is raised:

  File "<redacted>/.venv/lib/python3.12/site-packages/okta/okta_collection.py", line 10, in form_list
    if not OktaCollection.is_formed(collection[index], data_type):
                                    ~~~~~~~~~~^^^^^^^
KeyError: 0

This error is not handled and propagates back up to the original okta_client.list_network_zones() function call

It seems the error itself is initially raised here:

@staticmethod
def form_list(collection: list, data_type: type):
    if not collection:
        # If empty list or None
        return []
    for index in range(len(collection)):
        if not OktaCollection.is_formed(collection[index], data_type):
            collection[index] = data_type(collection[index])
    return collection

Upon further investigation, it raises back to the following call starting on line 49 of the __init__ function of NetworkZone:

self.asns = OktaCollection.form_list(
    config["asns"] if "asns"\
        in config else [],
    str
)

After examining the API response, this seems to occur under a very specific condition - when a network zone in said response contains an asns attribute that is unexpectedly a dictionary, not a list, as form_list(collection: list, data_type: type) expects.

Here is the network zone JSON that leads to the error being raised. I have redacted certain information, except the name, as I believe that it is a built-in zone everyone has.

'{
    "type": "DYNAMIC_V2",
    "id": "redacted",
    "name": "DefaultEnhancedDynamicZone",
    "status": "INACTIVE",
    "usage": "BLOCKLIST",
    "created": "redacted",
    "lastUpdated": "redacted",
    "system": true,
    "locations": {
        "include": [],
        "exclude": []
    },
    "ipServiceCategories": {
        "include": [
            "ALL_ANONYMIZERS"
        ],
        "exclude": []
    },
    "asns": {
        "include": [],
        "exclude": []
    },
    "links": {
        "activate": {
            "href": "redacted",
            "hints": {
                "allow": [
                    "POST"
                ]
            }
        },
        "self": {
            "href": "redacted",
            "hints": {
                "allow": [
                    "GET",
                    "PUT",
                    "DELETE"
                ]
            }
        }
    }
}'

You can see here, the type of attribute asns is dict not list.

config.get('asns')
PyDev console: starting.
{'include': [], 'exclude': []}
type(config.get('asns'))
<class 'dict'>

This leads to the following situation within OktaCollection.form_list (see comments):

@staticmethod
def form_list(collection: list, data_type: type):
# Collection is not None - is a dictionary, though
    if not collection:
        return []
# The range(len(collection)) is valid and returns range(0,2)
    for index in range(len(collection)):
# However the code then tries to treat collection as a list and reference an integer index by calling collection[0]
# Leading to a KeyError: 0, as the collection is a dictionary without a key '0'.
# This error is not handled and propagates back up to the original okta_client.list_network_zones() function call
        if not OktaCollection.is_formed(collection[index], data_type):
            collection[index] = data_type(collection[index])
    return collection

I am unsure if the asns attribute is always of type dict, but the code needs to handle when it is.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions