howler-api 2.10.0.dev65__tar.gz → 2.10.0.dev67__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/PKG-INFO +1 -1
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/collection.py +46 -25
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/howler_store.py +4 -4
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/pyproject.toml +1 -1
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/README.md +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/actions/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/actions/add_label.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/actions/add_to_bundle.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/actions/change_field.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/actions/demote.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/actions/example_plugin.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/actions/prioritization.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/actions/promote.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/actions/remove_from_bundle.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/actions/remove_label.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/actions/transition.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/base.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/socket.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/action.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/analytic.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/auth.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/borealis.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/configs.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/dossier.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/help.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/hit.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/notebook.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/overview.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/search.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/template.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/tool.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/user.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/utils/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/utils/etag.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/api/v1/view.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/app.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/README.md +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/classification.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/classification.yml +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/exceptions.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/hexdump.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/iprange.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/loader.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/logging/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/logging/audit.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/logging/format.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/net.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/net_static.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/random_user.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/common/swagger.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/config.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/cronjobs/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/cronjobs/retention.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/cronjobs/rules.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/README.md +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/bulk.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/constants.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/exceptions.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/migrations/fix_process.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/operations.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/schemas.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/store.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/support/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/support/build.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/support/schemas.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/types.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/error.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/external/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/external/generate_mitre.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/external/generate_sigma_rules.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/external/generate_tlds.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/external/reindex_data.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/external/wipe_databases.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/gunicorn_config.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/healthz.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/helper/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/helper/azure.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/helper/discover.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/helper/hit.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/helper/oauth.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/helper/search.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/helper/workflow.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/helper/ws.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/README.md +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/base.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/charter.txt +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/helper.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/howler_enum.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/action.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/analytic.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/assemblyline.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/aws.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/azure.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/cbs.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/config.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/dossier.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/agent.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/autonomous_system.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/client.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/cloud.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/code_signature.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/container.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/dns.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/egress.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/elf.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/email.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/error.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/event.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/faas.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/file.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/geo.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/group.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/hash.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/host.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/http.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/ingress.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/interface.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/network.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/observer.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/organization.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/os.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/pe.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/process.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/registry.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/related.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/rule.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/server.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/threat.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/tls.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/url.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/user.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/user_agent.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/vulnerability.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/gcp.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/hit.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/howler_data.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/lead.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/localized_label.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/overview.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/pivot.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/template.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/user.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/view.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/random_data.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/randomizer.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/patched.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/README.md +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/counters.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/events.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/hash.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/lock.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/queues/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/queues/comms.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/queues/multi.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/queues/named.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/queues/priority.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/set.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/user_quota_tracker.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/security/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/security/socket.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/security/utils.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/services/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/services/action_service.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/services/analytic_service.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/services/auth_service.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/services/config_service.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/services/dossier_service.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/services/event_service.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/services/hit_service.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/services/jwt_service.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/services/lucene_service.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/services/notebook_service.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/services/user_service.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/utils/__init__.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/utils/annotations.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/utils/chunk.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/utils/dict_utils.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/utils/isotime.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/utils/list_utils.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/utils/lucene.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/utils/path.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/utils/socket_utils.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/utils/str_utils.py +0 -0
- {howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/utils/uid.py +0 -0
|
@@ -57,7 +57,7 @@ if typing.TYPE_CHECKING:
|
|
|
57
57
|
|
|
58
58
|
TRANSPORT_TIMEOUT = int(environ.get("HWL_DATASTORE_TRANSPORT_TIMEOUT", "10"))
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
logger = logging.getLogger("howler.api.datastore")
|
|
61
61
|
ModelType = TypeVar("ModelType", bound=Model)
|
|
62
62
|
write_block_settings = {"settings": {"index.blocks.write": True}}
|
|
63
63
|
write_unblock_settings = {"settings": {"index.blocks.write": None}}
|
|
@@ -219,7 +219,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
219
219
|
if not ESCollection.IGNORE_ENSURE_COLLECTION:
|
|
220
220
|
self._ensure_collection()
|
|
221
221
|
else:
|
|
222
|
-
|
|
222
|
+
logger.warning("Skipping ensure collection! This is dangerous. Waiting five seconds before continuing.")
|
|
223
223
|
time.sleep(5)
|
|
224
224
|
|
|
225
225
|
self.stored_fields = {}
|
|
@@ -297,7 +297,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
297
297
|
ignore=(404,),
|
|
298
298
|
)
|
|
299
299
|
if not resp.get("succeeded", False):
|
|
300
|
-
|
|
300
|
+
logger.warning(
|
|
301
301
|
f"Could not clear scroll ID {scroll_id}, there is potential "
|
|
302
302
|
"memory leak in you Elastic cluster..."
|
|
303
303
|
)
|
|
@@ -319,7 +319,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
319
319
|
ret_val = func(*args, **kwargs)
|
|
320
320
|
|
|
321
321
|
if retries:
|
|
322
|
-
|
|
322
|
+
logger.info("Reconnected to elasticsearch!")
|
|
323
323
|
|
|
324
324
|
if updated:
|
|
325
325
|
ret_val["updated"] += updated
|
|
@@ -331,7 +331,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
331
331
|
except elasticsearch.exceptions.NotFoundError as e:
|
|
332
332
|
if "index_not_found_exception" in str(e):
|
|
333
333
|
time.sleep(min(retries, self.MAX_RETRY_BACKOFF))
|
|
334
|
-
|
|
334
|
+
logger.debug("The index does not exist. Trying to recreate it...")
|
|
335
335
|
self._ensure_collection()
|
|
336
336
|
self.datastore.connection_reset()
|
|
337
337
|
retries += 1
|
|
@@ -351,7 +351,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
351
351
|
retries += 1
|
|
352
352
|
|
|
353
353
|
except elasticsearch.exceptions.ConnectionTimeout:
|
|
354
|
-
|
|
354
|
+
logger.warning(
|
|
355
355
|
f"Elasticsearch connection timeout, server(s): "
|
|
356
356
|
f"{' | '.join(self.datastore.get_hosts(safe=True))}"
|
|
357
357
|
f", retrying {func.__name__}..."
|
|
@@ -366,7 +366,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
366
366
|
elasticsearch.exceptions.AuthenticationException,
|
|
367
367
|
) as e:
|
|
368
368
|
if not isinstance(e, SearchRetryException):
|
|
369
|
-
|
|
369
|
+
logger.warning(
|
|
370
370
|
f"No connection to Elasticsearch server(s): "
|
|
371
371
|
f"{' | '.join(self.datastore.get_hosts(safe=True))}"
|
|
372
372
|
f", because [{e}] retrying {func.__name__}..."
|
|
@@ -379,19 +379,19 @@ class ESCollection(Generic[ModelType]):
|
|
|
379
379
|
except elasticsearch.exceptions.TransportError as e:
|
|
380
380
|
err_code, msg, cause = e.args
|
|
381
381
|
if err_code == 503 or err_code == "503":
|
|
382
|
-
|
|
382
|
+
logger.warning(f"Looks like index {self.name} is not ready yet, retrying...")
|
|
383
383
|
time.sleep(min(retries, self.MAX_RETRY_BACKOFF))
|
|
384
384
|
self.datastore.connection_reset()
|
|
385
385
|
retries += 1
|
|
386
386
|
elif err_code == 429 or err_code == "429":
|
|
387
|
-
|
|
387
|
+
logger.warning(
|
|
388
388
|
"Elasticsearch is too busy to perform the requested " f"task on index {self.name}, retrying..."
|
|
389
389
|
)
|
|
390
390
|
time.sleep(min(retries, self.MAX_RETRY_BACKOFF))
|
|
391
391
|
self.datastore.connection_reset()
|
|
392
392
|
retries += 1
|
|
393
393
|
elif err_code == 403 or err_code == "403":
|
|
394
|
-
|
|
394
|
+
logger.warning(
|
|
395
395
|
"Elasticsearch cluster is preventing writing operations " f"on index {self.name}, retrying..."
|
|
396
396
|
)
|
|
397
397
|
time.sleep(min(retries, self.MAX_RETRY_BACKOFF))
|
|
@@ -445,7 +445,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
445
445
|
except elasticsearch.exceptions.TransportError as e:
|
|
446
446
|
err_code, _, _ = e.args
|
|
447
447
|
if err_code == 408 or err_code == "408":
|
|
448
|
-
|
|
448
|
+
logger.warning(f"Waiting for index {index} to get to status {min_status}...")
|
|
449
449
|
else:
|
|
450
450
|
raise
|
|
451
451
|
|
|
@@ -534,15 +534,12 @@ class ESCollection(Generic[ModelType]):
|
|
|
534
534
|
"acknowledged"
|
|
535
535
|
]
|
|
536
536
|
|
|
537
|
-
def fix_shards(self
|
|
537
|
+
def fix_shards(self):
|
|
538
538
|
"""This function should be overloaded to fix the shard configuration of the index of all the different hosts
|
|
539
539
|
specified in self.datastore.hosts.
|
|
540
540
|
|
|
541
541
|
:return: Should return True of the fix was successful on all hosts
|
|
542
542
|
"""
|
|
543
|
-
if logger is None:
|
|
544
|
-
logger = log
|
|
545
|
-
|
|
546
543
|
body = {"settings": self._get_index_settings()}
|
|
547
544
|
clone_body = {"settings": {"index.number_of_replicas": 0}}
|
|
548
545
|
clone_finish_settings = None
|
|
@@ -844,7 +841,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
844
841
|
key_list.remove(row["_id"])
|
|
845
842
|
add_to_output(row["_source"], row["_id"])
|
|
846
843
|
except ValueError:
|
|
847
|
-
|
|
844
|
+
logger.exception(f'MGet returned multiple documents for id: {row["_id"]}')
|
|
848
845
|
|
|
849
846
|
if key_list and error_on_missing:
|
|
850
847
|
raise MultiKeyError(key_list, out)
|
|
@@ -1221,15 +1218,15 @@ class ESCollection(Generic[ModelType]):
|
|
|
1221
1218
|
f"{res['_seq_no']}---{res['_primary_term']}",
|
|
1222
1219
|
)
|
|
1223
1220
|
except elasticsearch.NotFoundError as e:
|
|
1224
|
-
|
|
1221
|
+
logger.warning("Update - elasticsearch.NotFoundError: %s %s", e.message, e.info)
|
|
1225
1222
|
except elasticsearch.BadRequestError as e:
|
|
1226
|
-
|
|
1223
|
+
logger.warning("Update - elasticsearch.BadRequestError: %s %s", e.message, e.info)
|
|
1227
1224
|
return False
|
|
1228
1225
|
except VersionConflictException as e:
|
|
1229
|
-
|
|
1226
|
+
logger.warning("Update - elasticsearch.ConflictError: %s", e.message)
|
|
1230
1227
|
raise
|
|
1231
1228
|
except Exception as e:
|
|
1232
|
-
|
|
1229
|
+
logger.warning("Update - Generic Exception: %s", str(e))
|
|
1233
1230
|
return False
|
|
1234
1231
|
|
|
1235
1232
|
return False
|
|
@@ -2147,7 +2144,12 @@ class ESCollection(Generic[ModelType]):
|
|
|
2147
2144
|
if "total_fields" not in settings["index"]["mapping"]:
|
|
2148
2145
|
settings["index"]["mapping"]["total_fields"] = {}
|
|
2149
2146
|
|
|
2150
|
-
|
|
2147
|
+
limit = len(self.model_class.flat_fields()) + 500 if self.model_class else 1500
|
|
2148
|
+
if limit < 1500:
|
|
2149
|
+
limit = 1500
|
|
2150
|
+
else:
|
|
2151
|
+
logger.warning("ODM field size is larger than 1500 - set to %s", limit)
|
|
2152
|
+
settings["index"]["mapping"]["total_fields"]["limit"] = limit
|
|
2151
2153
|
|
|
2152
2154
|
return settings
|
|
2153
2155
|
|
|
@@ -2200,7 +2202,26 @@ class ESCollection(Generic[ModelType]):
|
|
|
2200
2202
|
|
|
2201
2203
|
missing = set(model.keys()) - set(fields.keys())
|
|
2202
2204
|
if missing:
|
|
2203
|
-
|
|
2205
|
+
# TODO: Bump mapping limit
|
|
2206
|
+
try:
|
|
2207
|
+
self._add_fields({key: model[key] for key in missing})
|
|
2208
|
+
except elasticsearch.BadRequestError as err:
|
|
2209
|
+
handled = False
|
|
2210
|
+
if err.body and isinstance(err.body, dict) and "error" in err.body and "reason" in err.body["error"]:
|
|
2211
|
+
reason: str = err.body["error"]["reason"]
|
|
2212
|
+
if reason.startswith("Limit of total fields"):
|
|
2213
|
+
current_count = int(re.sub(r".+\[(\d+)].+", r"\1", reason))
|
|
2214
|
+
logger.warning(
|
|
2215
|
+
"Current field cap %s is too low, increasing to %s", current_count, current_count + 500
|
|
2216
|
+
)
|
|
2217
|
+
self.with_retries(
|
|
2218
|
+
self.datastore.client.indices.put_settings,
|
|
2219
|
+
body={"settings": {"index.mapping.total_fields.limit": current_count + 500}},
|
|
2220
|
+
)
|
|
2221
|
+
self._add_fields({key: model[key] for key in missing})
|
|
2222
|
+
handled = True
|
|
2223
|
+
if not handled:
|
|
2224
|
+
raise
|
|
2204
2225
|
|
|
2205
2226
|
matching = set(fields.keys()) & set(model.keys())
|
|
2206
2227
|
for field_name in matching:
|
|
@@ -2224,7 +2245,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
2224
2245
|
"""
|
|
2225
2246
|
# Create HOT index
|
|
2226
2247
|
if not self.with_retries(self.datastore.client.indices.exists, index=self.name):
|
|
2227
|
-
|
|
2248
|
+
logger.debug(f"Index {self.name.upper()} does not exists. Creating it now...")
|
|
2228
2249
|
try:
|
|
2229
2250
|
self.with_retries(
|
|
2230
2251
|
self.datastore.client.indices.create,
|
|
@@ -2235,7 +2256,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
2235
2256
|
except elasticsearch.exceptions.RequestError as e:
|
|
2236
2257
|
if "resource_already_exists_exception" not in str(e):
|
|
2237
2258
|
raise
|
|
2238
|
-
|
|
2259
|
+
logger.warning(f"Tried to create an index template that already exists: {self.name.upper()}")
|
|
2239
2260
|
|
|
2240
2261
|
self.with_retries(
|
|
2241
2262
|
self.datastore.client.indices.put_alias,
|
|
@@ -2310,7 +2331,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
2310
2331
|
|
|
2311
2332
|
:return:
|
|
2312
2333
|
"""
|
|
2313
|
-
|
|
2334
|
+
logger.debug("Wipe operation started for collection: %s" % self.name.upper())
|
|
2314
2335
|
|
|
2315
2336
|
for index in self.index_list:
|
|
2316
2337
|
if self.with_retries(self.datastore.client.indices.exists, index=index):
|
|
@@ -5,7 +5,7 @@ import elasticapm
|
|
|
5
5
|
import elasticsearch
|
|
6
6
|
|
|
7
7
|
from howler.common.exceptions import HowlerAttributeError
|
|
8
|
-
from howler.datastore.collection import ESCollection,
|
|
8
|
+
from howler.datastore.collection import ESCollection, logger
|
|
9
9
|
from howler.odm.models.action import Action
|
|
10
10
|
from howler.odm.models.analytic import Analytic
|
|
11
11
|
from howler.odm.models.dossier import Dossier
|
|
@@ -106,7 +106,7 @@ class HowlerDatastore(object):
|
|
|
106
106
|
elasticsearch.exceptions.ConnectionTimeout,
|
|
107
107
|
elasticsearch.exceptions.AuthenticationException,
|
|
108
108
|
):
|
|
109
|
-
|
|
109
|
+
logger.warning(
|
|
110
110
|
f"No connection to Elasticsearch server(s): "
|
|
111
111
|
f"{' | '.join(self.ds.get_hosts(safe=True))}"
|
|
112
112
|
f", retrying..."
|
|
@@ -118,12 +118,12 @@ class HowlerDatastore(object):
|
|
|
118
118
|
except elasticsearch.exceptions.TransportError as e:
|
|
119
119
|
err_code, msg, cause = e.args
|
|
120
120
|
if err_code == 503 or err_code == "503":
|
|
121
|
-
|
|
121
|
+
logger.warning("Looks like index is not ready yet, retrying...")
|
|
122
122
|
time.sleep(min(retries, max_retry_backoff))
|
|
123
123
|
self.ds.connection_reset()
|
|
124
124
|
retries += 1
|
|
125
125
|
elif err_code == 429 or err_code == "429":
|
|
126
|
-
|
|
126
|
+
logger.warning(
|
|
127
127
|
"Elasticsearch is too busy to perform the requested task, " "we will wait a bit and retry..."
|
|
128
128
|
)
|
|
129
129
|
time.sleep(min(retries, max_retry_backoff))
|
|
@@ -147,7 +147,7 @@ suppress-none-returning = true
|
|
|
147
147
|
[tool.poetry]
|
|
148
148
|
package-mode = true
|
|
149
149
|
name = "howler-api"
|
|
150
|
-
version = "2.10.0.
|
|
150
|
+
version = "2.10.0.dev67"
|
|
151
151
|
description = "Howler - API server"
|
|
152
152
|
authors = [
|
|
153
153
|
"Canadian Centre for Cyber Security <howler@cyber.gc.ca>",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/datastore/migrations/fix_process.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/odm/models/ecs/autonomous_system.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/queues/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/queues/priority.py
RENAMED
|
File without changes
|
|
File without changes
|
{howler_api-2.10.0.dev65 → howler_api-2.10.0.dev67}/howler/remote/datatypes/user_quota_tracker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|