howler-api 4.0.0.dev1308__tar.gz → 4.0.0.dev1311__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-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/PKG-INFO +1 -1
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/collection.py +92 -22
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/external/reindex_data.py +1 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/random_data.py +5 -1
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/pyproject.toml +1 -1
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/README.md +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/actions/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/actions/add_label.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/actions/add_to_bundle.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/actions/add_to_case.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/actions/change_field.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/actions/demote.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/actions/example_plugin.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/actions/prioritization.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/actions/promote.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/actions/remove_from_bundle.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/actions/remove_label.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/actions/transition.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/base.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/socket.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/action.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/analytic.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/auth.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/clue.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/configs.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/dossier.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/help.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/hit.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/notebook.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/overview.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/search.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/template.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/tool.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/user.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/utils/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/utils/etag.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/utils/params.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v1/view.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v2/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v2/case.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v2/fuzzy.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v2/ingest.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/api/v2/search.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/app.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/README.md +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/classification.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/classification.yml +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/exceptions.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/loader.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/logging/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/logging/audit.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/logging/format.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/net.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/net_static.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/random_user.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/common/swagger.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/config.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/cronjobs/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/cronjobs/action_queue_worker.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/cronjobs/correlation.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/cronjobs/retention.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/cronjobs/view_cleanup.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/README.md +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/bulk.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/constants.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/exceptions.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/howler_store.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/migrations/fix_process.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/operations.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/schemas.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/store.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/support/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/support/build.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/support/schemas.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/datastore/types.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/error.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/external/README.md +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/external/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/external/generate_mitre.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/external/generate_sigma_rules.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/external/generate_tlds.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/external/wipe_databases.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/gunicorn_config.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/healthz.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/helper/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/helper/azure.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/helper/discover.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/helper/hit.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/helper/oauth.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/helper/search.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/helper/workflow.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/helper/ws.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/README.md +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/base.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/charter.txt +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/constants.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/helper.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/howler_enum.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/mixins.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/action.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/analytic.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/assemblyline.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/aws.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/azure.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/case.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/cbs.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/clue.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/config.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/dossier.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/agent.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/autonomous_system.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/client.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/cloud.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/code_signature.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/container.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/dns.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/egress.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/elf.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/email.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/error.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/event.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/faas.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/file.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/geo.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/group.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/hash.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/host.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/http.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/ingress.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/interface.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/network.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/observer.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/organization.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/os.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/pe.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/process.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/registry.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/related.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/rule.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/server.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/threat.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/tls.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/url.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/user.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/user_agent.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/vulnerability.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/event.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/gcp.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/hit.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/howler_data.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/lead.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/localized_label.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/overview.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/pivot.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/record.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/template.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/user.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/view.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/randomizer.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/patched.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/plugins/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/plugins/config.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/README.md +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/counters.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/events.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/hash.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/lock.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/queues/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/queues/comms.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/queues/multi.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/queues/named.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/queues/priority.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/set.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/user_quota_tracker.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/security/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/security/socket.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/security/utils.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/action_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/analytic_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/auth_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/bundle_compat_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/case_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/comms_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/config_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/correlation_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/docs_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/dossier_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/event_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/fuzzy_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/hit_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/jwt_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/lucene_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/notebook_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/overview_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/search_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/template_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/user_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/viewer_service.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/telemetry.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/__init__.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/annotations.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/chunk.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/compat.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/constants.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/dict_utils.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/indexes.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/isotime.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/list_utils.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/lucene.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/net_utils.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/path.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/socket_utils.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/str_utils.py +0 -0
- {howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/utils/uid.py +0 -0
|
@@ -252,19 +252,50 @@ class ESCollection(Generic[ModelType]):
|
|
|
252
252
|
|
|
253
253
|
@property
|
|
254
254
|
def index_list_full(self):
|
|
255
|
+
"""Return every physical index for this collection, newest ILM index first.
|
|
256
|
+
|
|
257
|
+
Maintenance operations that must visit historical rollover indexes should use this
|
|
258
|
+
property. The active index is included even when no ILM rollover index exists.
|
|
259
|
+
"""
|
|
255
260
|
if not self._index_list:
|
|
256
|
-
self._index_list =
|
|
261
|
+
self._index_list = self._get_ilm_index_names()
|
|
257
262
|
|
|
258
|
-
return [self.index_name
|
|
263
|
+
return list(dict.fromkeys([self.index_name, *sorted(self._index_list, reverse=True)]))
|
|
259
264
|
|
|
260
265
|
@property
|
|
261
266
|
def index_list(self):
|
|
262
|
-
"""
|
|
267
|
+
"""Return the active physical write index for this collection.
|
|
263
268
|
|
|
264
|
-
|
|
269
|
+
Historical ILM rollover indexes are intentionally excluded. Bulk plans use this
|
|
270
|
+
list for default write, update, and delete targets, and widening it would fan those
|
|
271
|
+
operations out across historical indexes.
|
|
265
272
|
"""
|
|
266
273
|
return [self.index_name]
|
|
267
274
|
|
|
275
|
+
def _get_ilm_index_names(self) -> list[str]:
|
|
276
|
+
"""Return physical ILM rollover indexes, excluding temporary maintenance indexes."""
|
|
277
|
+
try:
|
|
278
|
+
indices = self.datastore.client.indices.get(
|
|
279
|
+
index=f"{self.name}-0*",
|
|
280
|
+
ignore_unavailable=True,
|
|
281
|
+
)
|
|
282
|
+
except elasticsearch.exceptions.NotFoundError:
|
|
283
|
+
return []
|
|
284
|
+
|
|
285
|
+
index_pattern = re.compile(rf"^{re.escape(self.name)}-\d{{6}}$")
|
|
286
|
+
return sorted(index for index in indices if index_pattern.fullmatch(index))
|
|
287
|
+
|
|
288
|
+
def _refresh_ilm_index_name(self):
|
|
289
|
+
"""Set ``index_name`` to the latest existing ILM index, when one exists."""
|
|
290
|
+
if not self.ilm_config:
|
|
291
|
+
return
|
|
292
|
+
|
|
293
|
+
ilm_indices = self._get_ilm_index_names()
|
|
294
|
+
|
|
295
|
+
if ilm_indices:
|
|
296
|
+
self._index_list = ilm_indices
|
|
297
|
+
self.index_name = ilm_indices[-1]
|
|
298
|
+
|
|
268
299
|
def scan_with_retry(
|
|
269
300
|
self,
|
|
270
301
|
query,
|
|
@@ -730,7 +761,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
730
761
|
def reindex(self, allow_failures: bool = False, request_timeout: int = 60):
|
|
731
762
|
"""Reindex all the data of the collection into a freshly mapped index.
|
|
732
763
|
|
|
733
|
-
For every index in ``self.
|
|
764
|
+
For every physical index in ``self.index_list_full`` the data is copied into a temporary
|
|
734
765
|
``__reindex`` index that uses the current mappings/settings. Writes to the source
|
|
735
766
|
index are blocked while the copy runs so the reindex result and document counts can
|
|
736
767
|
be validated before the original index is deleted. The temporary index is only
|
|
@@ -750,7 +781,8 @@ class ESCollection(Generic[ModelType]):
|
|
|
750
781
|
operation can be recovered with :meth:`reindex_cleanup`.
|
|
751
782
|
"""
|
|
752
783
|
logger.warning("Beginning Reindex")
|
|
753
|
-
|
|
784
|
+
self._refresh_ilm_index_name()
|
|
785
|
+
for index in self.index_list_full:
|
|
754
786
|
new_name = f"{index}__reindex"
|
|
755
787
|
index_data = None
|
|
756
788
|
source_count = None
|
|
@@ -798,7 +830,7 @@ class ESCollection(Generic[ModelType]):
|
|
|
798
830
|
self.datastore.client.indices.create,
|
|
799
831
|
index=new_name,
|
|
800
832
|
mappings=self._get_index_mappings(),
|
|
801
|
-
settings=self.
|
|
833
|
+
settings=self._get_reindex_settings(index_data),
|
|
802
834
|
)
|
|
803
835
|
|
|
804
836
|
# Reindex data into target
|
|
@@ -847,12 +879,10 @@ class ESCollection(Generic[ModelType]):
|
|
|
847
879
|
)
|
|
848
880
|
|
|
849
881
|
alias_actions = []
|
|
850
|
-
aliases = index_data.get("aliases", {})
|
|
882
|
+
aliases = index_data.get("aliases", {})
|
|
851
883
|
for alias, alias_data in aliases.items():
|
|
852
884
|
alias_action = {"index": index, "alias": alias}
|
|
853
885
|
alias_action.update(alias_data)
|
|
854
|
-
if alias == self.name or alias_data.get("is_write_index", False):
|
|
855
|
-
alias_action["is_write_index"] = True
|
|
856
886
|
alias_actions.append({"add": alias_action})
|
|
857
887
|
alias_actions.append({"remove_index": {"index": new_name}})
|
|
858
888
|
self.with_retries(self.datastore.client.indices.update_aliases, actions=alias_actions)
|
|
@@ -880,6 +910,14 @@ class ESCollection(Generic[ModelType]):
|
|
|
880
910
|
|
|
881
911
|
return True
|
|
882
912
|
|
|
913
|
+
def _get_reindex_settings(self, index_data: dict) -> dict:
|
|
914
|
+
"""Build settings for a reindex target without dropping ILM lifecycle metadata."""
|
|
915
|
+
settings = self._get_index_settings()
|
|
916
|
+
lifecycle = index_data.get("settings", {}).get("index", {}).get("lifecycle")
|
|
917
|
+
if lifecycle:
|
|
918
|
+
settings["index"]["lifecycle"] = deepcopy(lifecycle)
|
|
919
|
+
return settings
|
|
920
|
+
|
|
883
921
|
def _validate_reindex_result(self, index, new_name, reindex_result, allow_failures):
|
|
884
922
|
"""Validate the result of an Elasticsearch reindex task.
|
|
885
923
|
|
|
@@ -956,17 +994,18 @@ class ESCollection(Generic[ModelType]):
|
|
|
956
994
|
def reindex_cleanup(self):
|
|
957
995
|
"""Recover from a failed or interrupted :meth:`reindex` run.
|
|
958
996
|
|
|
959
|
-
For every index that still has a leftover ``__reindex`` index, restore the source
|
|
960
|
-
index
|
|
961
|
-
|
|
962
|
-
|
|
997
|
+
For every physical index that still has a leftover ``__reindex`` index, restore the source
|
|
998
|
+
index's original aliases and delete the orphaned ``__reindex`` index. If the source
|
|
999
|
+
index is missing, raise an error instead of deleting ``__reindex`` because it may
|
|
1000
|
+
be the only remaining copy of the data.
|
|
963
1001
|
|
|
964
1002
|
Write blocks set during reindexing are cleared so the collection is usable again.
|
|
965
1003
|
|
|
966
1004
|
:return: ``True`` when cleanup completed on all indexes
|
|
967
1005
|
"""
|
|
968
1006
|
logger.warning("Beginning reindex cleanup")
|
|
969
|
-
|
|
1007
|
+
self._refresh_ilm_index_name()
|
|
1008
|
+
for index in self.index_list_full:
|
|
970
1009
|
new_name = f"{index}__reindex"
|
|
971
1010
|
|
|
972
1011
|
if not self.with_retries(self.datastore.client.indices.exists, index=new_name):
|
|
@@ -987,17 +1026,13 @@ class ESCollection(Generic[ModelType]):
|
|
|
987
1026
|
reindex_aliases = new_index_data.get("aliases", {})
|
|
988
1027
|
|
|
989
1028
|
alias_actions = []
|
|
990
|
-
for alias in sorted(set(source_aliases) | set(reindex_aliases)
|
|
1029
|
+
for alias in sorted(set(source_aliases) | set(reindex_aliases)):
|
|
991
1030
|
source_alias_data = source_aliases.get(alias, {})
|
|
992
1031
|
reindex_alias_data = reindex_aliases.get(alias, {})
|
|
993
1032
|
|
|
994
1033
|
add_alias_data = {"index": index, "alias": alias}
|
|
995
1034
|
add_alias_data.update(source_alias_data)
|
|
996
|
-
if (
|
|
997
|
-
alias == self.name
|
|
998
|
-
or source_alias_data.get("is_write_index", False)
|
|
999
|
-
or reindex_alias_data.get("is_write_index", False)
|
|
1000
|
-
):
|
|
1035
|
+
if source_alias_data.get("is_write_index", False) or reindex_alias_data.get("is_write_index", False):
|
|
1001
1036
|
add_alias_data["is_write_index"] = True
|
|
1002
1037
|
|
|
1003
1038
|
alias_actions.append({"add": add_alias_data})
|
|
@@ -2905,7 +2940,42 @@ class ESCollection(Generic[ModelType]):
|
|
|
2905
2940
|
if existing_ilm_indices:
|
|
2906
2941
|
# ILM already bootstrapped — ensure the alias exists
|
|
2907
2942
|
latest = sorted(existing_ilm_indices)[-1]
|
|
2908
|
-
|
|
2943
|
+
legacy_hot_index = f"{self.name}_hot"
|
|
2944
|
+
if self.with_retries(self.datastore.client.indices.exists_alias, name=self.name):
|
|
2945
|
+
alias_indices = self.with_retries(self.datastore.client.indices.get_alias, name=self.name)
|
|
2946
|
+
alias_actions = []
|
|
2947
|
+
for alias_index, alias_index_data in alias_indices.items():
|
|
2948
|
+
alias_data = alias_index_data.get("aliases", {}).get(self.name, {})
|
|
2949
|
+
if alias_index == legacy_hot_index:
|
|
2950
|
+
alias_actions.append({"remove": {"index": alias_index, "alias": self.name}})
|
|
2951
|
+
elif alias_index != latest and alias_data.get("is_write_index", False):
|
|
2952
|
+
alias_actions.append(
|
|
2953
|
+
{
|
|
2954
|
+
"add": {
|
|
2955
|
+
"index": alias_index,
|
|
2956
|
+
"alias": self.name,
|
|
2957
|
+
**alias_data,
|
|
2958
|
+
"is_write_index": False,
|
|
2959
|
+
}
|
|
2960
|
+
}
|
|
2961
|
+
)
|
|
2962
|
+
|
|
2963
|
+
latest_alias_data = alias_indices.get(latest, {}).get("aliases", {}).get(self.name, {})
|
|
2964
|
+
if not latest_alias_data.get("is_write_index", False):
|
|
2965
|
+
alias_actions.append(
|
|
2966
|
+
{
|
|
2967
|
+
"add": {
|
|
2968
|
+
"index": latest,
|
|
2969
|
+
"alias": self.name,
|
|
2970
|
+
**latest_alias_data,
|
|
2971
|
+
"is_write_index": True,
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
)
|
|
2975
|
+
|
|
2976
|
+
if alias_actions:
|
|
2977
|
+
self.with_retries(self.datastore.client.indices.update_aliases, actions=alias_actions)
|
|
2978
|
+
else:
|
|
2909
2979
|
# Find the latest index to set as write index
|
|
2910
2980
|
self.with_retries(
|
|
2911
2981
|
self.datastore.client.indices.put_alias,
|
|
@@ -867,8 +867,12 @@ def wipe_actions(ds: HowlerDatastore):
|
|
|
867
867
|
def create_dossiers(ds: HowlerDatastore, num_dossiers: int = 5):
|
|
868
868
|
"Create random dossiers"
|
|
869
869
|
users = ds.user.search("*:*")["items"]
|
|
870
|
-
for
|
|
870
|
+
for index in range(num_dossiers):
|
|
871
871
|
dossier = generate_useful_dossier(users)
|
|
872
|
+
if index == 0:
|
|
873
|
+
dossier.type = "personal"
|
|
874
|
+
elif index == 1:
|
|
875
|
+
dossier.type = "global"
|
|
872
876
|
ds.dossier.save(dossier.dossier_id, dossier)
|
|
873
877
|
|
|
874
878
|
ds.dossier.commit()
|
|
@@ -152,7 +152,7 @@ suppress-none-returning = true
|
|
|
152
152
|
[tool.poetry]
|
|
153
153
|
package-mode = true
|
|
154
154
|
name = "howler-api"
|
|
155
|
-
version = "4.0.0.
|
|
155
|
+
version = "4.0.0.dev1311"
|
|
156
156
|
description = "Howler - API server"
|
|
157
157
|
authors = [
|
|
158
158
|
"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
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/cronjobs/action_queue_worker.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
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/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
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/external/generate_sigma_rules.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
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/autonomous_system.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/code_signature.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
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/odm/models/ecs/vulnerability.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
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/queues/__init__.py
RENAMED
|
File without changes
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/queues/comms.py
RENAMED
|
File without changes
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/queues/multi.py
RENAMED
|
File without changes
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/queues/named.py
RENAMED
|
File without changes
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/remote/datatypes/queues/priority.py
RENAMED
|
File without changes
|
|
File without changes
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/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
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/bundle_compat_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{howler_api-4.0.0.dev1308 → howler_api-4.0.0.dev1311}/howler/services/correlation_service.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
|