<!-- TOC -->
* [5.0.0](500)
* [Massive back-end library changes](massive-back-end-library-changes)
* [Bugfix: Logging in with credentials KeyError access_token](bugfix-logging-in-with-credentials-keyerror-accesstoken)
* [Bugfix: Signup object has no attribute auth](bugfix-signup-object-has-no-attribute-auth)
* [Bugfix: Multiple with datascopes](bugfix-multiple-with-datascopes)
* [Axonshell Changes](axonshell-changes)
* [New command group in axonshell enforcements for tasks](new-command-group-in-axonshell-enforcements-for-tasks)
* [axonshell enforcements tasks count](axonshell-enforcements-tasks-count)
* [axonshell enforcements tasks get](axonshell-enforcements-tasks-get)
* [axonshell enforcements tasks get-filters](axonshell-enforcements-tasks-get-filters)
* [Added Cloudflared support](added-cloudflared-support)
* [Updated Enforcement Set Warning](updated-enforcement-set-warning)
* [Added new option to enable max logging](added-new-option-to-enable-max-logging)
* [Saved Query now required for Enforcement Sets](saved-query-now-required-for-enforcement-sets)
* [Add options to asset fetches to give more control over exports](add-options-to-asset-fetches-to-give-more-control-over-exports)
* [Add support for using column filters in get-by-saved-query](add-support-for-using-column-filters-in-get-by-saved-query)
* [Add options to asset fetches to support REST API features](add-options-to-asset-fetches-to-support-rest-api-features)
* [New help-detailed option for asset fetches](new-help-detailed-option-for-asset-fetches)
* [Startup banner enhancements](startup-banner-enhancements)
* [axonshell tools shell enhancements](axonshell-tools-shell-enhancements)
* [Library changes](library-changes)
* [New projects directory](new-projects-directory)
* [axonius_api_client.http.Http signature rewrite](axoniusapiclienthttphttp-signature-rewrite)
* [Docstring updates galore](docstring-updates-galore)
* [ApiEndpoint refactor](apiendpoint-refactor)
* [get_env_connect returns more Connect args](getenvconnect-returns-more-connect-args)
* [JSONAPI models refactor](jsonapi-models-refactor)
* [AuthModel refactor](authmodel-refactor)
* [axonius_api_client.connect.Connect signature rewrite and refactor](axoniusapiclientconnectconnect-signature-rewrite-and-refactor)
* [New ApiModel client.enforcements.tasks](new-apimodel-clientenforcementstasks)
* [New project cf_token](new-project-cftoken)
* [AssetMixin.get_generator signature rewrite](assetmixingetgenerator-signature-rewrite)
* [AssetMixin.get_by_saved_query rewrite](assetmixingetbysavedquery-rewrite)
* [AssetMixin.count rewrite](assetmixincount-rewrite)
* [Remove v4.0 from all ApiEndpoints](remove-v40-from-all-apiendpoints)
<!-- TOC -->
Massive back-end library changes
Transitioning to a modular approach and minimizing package dependencies as much as possible.
The axonshell interface remains unchanged and although the Python library interface has changed in several places, the actual usage remains consistent and will still work the same way for now.
For a comprehensive list of changes to the Python library, see below the axonshell changes.
Bugfix: Logging in with credentials KeyError access_token
In this release, the issue related to logging in with credentials resulting in a KeyError for 'access_token' has been fixed.
The response from the REST API has changed, and the access_token must now be accessed from the response headers instead of the response body of the login endpoint.
Bugfix: Signup object has no attribute auth
In this release, the issue with the Signup object not having the 'auth' attribute has been addressed and fixed.
Users should no longer encounter this error, and the Signup object should now function as expected.
Bugfix: Multiple with datascopes
A bugfix has been implemented to address issues related to datascopes when adding a saved query.
Previously, when datascopes were enabled, the default folder for saving a new query was /Shared Queries.
However, with datascopes enabled, saving to this folder is no longer allowed.
To resolve this issue, the API client logic has been updated to set the default folder for saving queries to /Global instead of /Shared Queries when datascopes are enabled.
Axonshell Changes
New command group in axonshell enforcements for tasks
A new command group has been added to the axonshell enforcements command group for tasks.
text
Usage: axonshell enforcements tasks [OPTIONS] COMMAND [ARGS]...
Group: Work with tasks ran by the Enforcement Center.
Options:
--help Show this message and exit.
Commands:
count Get Count of Enforcement Center Tasks matching filters.
get Get Enforcement Center Tasks matching filters.
get-filters Get valid values for filtering count or get of Enforcement...
axonshell enforcements tasks count
text
Usage: axonshell enforcements tasks count [OPTIONS]
Get Count of Enforcement Center Tasks matching filters.
Options:
-u, --url URL URL of an Axonius instance [env var:
AX_URL; required]
-k, --key KEY API Key (or username if credentials=True) of
user in an Axonius instance [env var:
AX_KEY; required]
-s, --secret SECRET API Secret (or password if credentials=True)
of user in an Axonius instance [env var:
AX_SECRET; required]
-at, --action-types TEXT Only get tasks that were ran by types of
actions (use re_prefix for pattern matching)
(multiple) [env var: AX_ACTION_TYPES]
-ate, --action-types-error / -nate, --no-action-types-error
Error if any action_types provided are not
valid [env var: AX_ACTION_TYPES_ERROR;
default: action-types-error]
-atm, --action-types-minimum INTEGER
Error if matches for action_types are < this
number [env var: AX_ACTION_TYPES_MINIMUM]
-df, --date-from TEXT Only get tasks with creation date >= this
date [env var: AX_DATE_FROM]
-dfa, --date-from-add TEXT seconds to add to date_from (or now if
date_from not provided) [env var:
AX_DATE_FROM_ADD]
-dfs, --date-from-subtract TEXT
seconds to subtract from date_from (or now
if date_from not provided) [env var:
AX_DATE_FROM_SUBTRACT]
-dt, --date-to TEXT Only get tasks with creation date <= this
date [env var: AX_DATE_TO]
-dta, --date-to-add TEXT seconds to add to date_to (or now if date_to
not provided) [env var: AX_DATE_TO_ADD]
-dts, --date-to-subtract TEXT seconds to subtract from date_to (or now if
date_to not provided) [env var:
AX_DATE_TO_SUBTRACT]
-du, --discovery-uuids TEXT Only get tasks that were ran by discovery
UUIDs (use re_prefix for pattern matching)
(multiple) [env var: AX_DISCOVERY_UUIDS]
-due, --discovery-uuids-error / -ndue, --no-discovery-uuids-error
Error if any discovery_uuids provided are
not valid [env var:
AX_DISCOVERY_UUIDS_ERROR; default:
discovery-uuids-error]
-dum, --discovery-uuids-minimum INTEGER
Error if matches for discovery_uuids are <
this number [env var:
AX_DISCOVERY_UUIDS_MINIMUM]
-do, --duration-operator [equal|greater|less]
Operator to evaluate the duration_seconds
value against task run durations [env var:
AX_DURATION_OPERATOR; default: less]
-ds, --duration-seconds INTEGER
Only get tasks where run duration matches
duration_operator [env var:
AX_DURATION_SECONDS]
-en, --enforcement-names TEXT Only get tasks that were ran by enforcement
names (use re_prefix for pattern matching)
(multiple) [env var: AX_ENFORCEMENT_NAMES]
-ene, --enforcement-names-error / -nene, --no-enforcement-names-error
Error if any enforcement_names provided are
not valid [env var:
AX_ENFORCEMENT_NAMES_ERROR; default:
enforcement-names-error]
-enm, --enforcement-names-minimum INTEGER
Error if matches for enforcement_names are <
this number [env var:
AX_ENFORCEMENT_NAMES_MINIMUM]
-re, --re-prefix TEXT Any strings provided to action_type,
discovery_uuids, enforcement_names,statuses,
or statuses_result that start with this
value will be treated as a regex pattern
[env var: AX_RE_PREFIX; default: ~]
-sp, --split / -nsp, --no-split
Split strings provided to filters using
split_sep [env var: AX_SPLIT; default:
split]
-ss, --split-sep TEXT Split strings provided to filters using this
separator [env var: AX_SPLIT_SEP; default:
re.compile(',')]
-st, --strip / -nst, --no-strip
Strip strings provided to filters [env var:
AX_STRIP; default: strip]
-so, --sort TEXT Ask REST API to sort tasks on this attribute
(prefix with '-' for descending) [env var:
AX_SORT]
-st, --statuses TEXT Only get tasks that have the provided
statuses (use re_prefix for pattern
matching) (multiple) [env var: AX_STATUSES]
-ste, --statuses-error / -note, --no-statuses-error
Error if any statuses provided are not valid
[env var: AX_STATUSES_ERROR; default:
statuses-error]
-stm, --statuses-minimum INTEGER
Error if matches for statuses are < this
number [env var: AX_STATUSES_MINIMUM]
-sr, --statuses-result TEXT Only get tasks that have the provided result
statuses (use re_prefix for pattern
matching) (multiple) [env var:
AX_STATUSES_RESULT]
-sre, --statuses-result-error / -nsre, --no-statuses-result-error
Error if any result statuses provided are
not valid [env var:
AX_STATUSES_RESULT_ERROR; default: statuses-
result-error]
-srm, --statuses-result-minimum INTEGER
Error if matches for result statuses are <
this number [env var:
AX_STATUSES_RESULT_MINIMUM]
-id, --task-id INTEGER Only get tasks associated with this 'pretty
id' [env var: AX_TASK_ID]
--help Show this message and exit.
axonshell enforcements tasks get
text
Usage: axonshell enforcements tasks get [OPTIONS]
Get Enforcement Center Tasks matching filters.
Options:
-u, --url URL URL of an Axonius instance [env var:
AX_URL; required]
-k, --key KEY API Key (or username if credentials=True) of
user in an Axonius instance [env var:
AX_KEY; required]
-s, --secret SECRET API Secret (or password if credentials=True)
of user in an Axonius instance [env var:
AX_SECRET; required]
-at, --action-types TEXT Only get tasks that were ran by types of
actions (use re_prefix for pattern matching)
(multiple) [env var: AX_ACTION_TYPES]
-ate, --action-types-error / -nate, --no-action-types-error
Error if any action_types provided are not
valid [env var: AX_ACTION_TYPES_ERROR;
default: action-types-error]
-atm, --action-types-minimum INTEGER
Error if matches for action_types are < this
number [env var: AX_ACTION_TYPES_MINIMUM]
-df, --date-from TEXT Only get tasks with creation date >= this
date [env var: AX_DATE_FROM]
-dfa, --date-from-add TEXT seconds to add to date_from (or now if
date_from not provided) [env var:
AX_DATE_FROM_ADD]
-dfs, --date-from-subtract TEXT
seconds to subtract from date_from (or now
if date_from not provided) [env var:
AX_DATE_FROM_SUBTRACT]
-dt, --date-to TEXT Only get tasks with creation date <= this
date [env var: AX_DATE_TO]
-dta, --date-to-add TEXT seconds to add to date_to (or now if date_to
not provided) [env var: AX_DATE_TO_ADD]
-dts, --date-to-subtract TEXT seconds to subtract from date_to (or now if
date_to not provided) [env var:
AX_DATE_TO_SUBTRACT]
-du, --discovery-uuids TEXT Only get tasks that were ran by discovery
UUIDs (use re_prefix for pattern matching)
(multiple) [env var: AX_DISCOVERY_UUIDS]
-due, --discovery-uuids-error / -ndue, --no-discovery-uuids-error
Error if any discovery_uuids provided are
not valid [env var:
AX_DISCOVERY_UUIDS_ERROR; default:
discovery-uuids-error]
-dum, --discovery-uuids-minimum INTEGER
Error if matches for discovery_uuids are <
this number [env var:
AX_DISCOVERY_UUIDS_MINIMUM]
-do, --duration-operator [equal|greater|less]
Operator to evaluate the duration_seconds
value against task run durations [env var:
AX_DURATION_OPERATOR; default: less]
-ds, --duration-seconds INTEGER
Only get tasks where run duration matches
duration_operator [env var:
AX_DURATION_SECONDS]
-en, --enforcement-names TEXT Only get tasks that were ran by enforcement
names (use re_prefix for pattern matching)
(multiple) [env var: AX_ENFORCEMENT_NAMES]
-ene, --enforcement-names-error / -nene, --no-enforcement-names-error
Error if any enforcement_names provided are
not valid [env var:
AX_ENFORCEMENT_NAMES_ERROR; default:
enforcement-names-error]
-enm, --enforcement-names-minimum INTEGER
Error if matches for enforcement_names are <
this number [env var:
AX_ENFORCEMENT_NAMES_MINIMUM]
-re, --re-prefix TEXT Any strings provided to action_type,
discovery_uuids, enforcement_names,statuses,
or statuses_result that start with this
value will be treated as a regex pattern
[env var: AX_RE_PREFIX; default: ~]
-sp, --split / -nsp, --no-split
Split strings provided to filters using
split_sep [env var: AX_SPLIT; default:
split]
-ss, --split-sep TEXT Split strings provided to filters using this
separator [env var: AX_SPLIT_SEP; default:
re.compile(',')]
-st, --strip / -nst, --no-strip
Strip strings provided to filters [env var:
AX_STRIP; default: strip]
-so, --sort TEXT Ask REST API to sort tasks on this attribute
(prefix with '-' for descending) [env var:
AX_SORT]
-st, --statuses TEXT Only get tasks that have the provided
statuses (use re_prefix for pattern
matching) (multiple) [env var: AX_STATUSES]
-ste, --statuses-error / -note, --no-statuses-error
Error if any statuses provided are not valid
[env var: AX_STATUSES_ERROR; default:
statuses-error]
-stm, --statuses-minimum INTEGER
Error if matches for statuses are < this
number [env var: AX_STATUSES_MINIMUM]
-sr, --statuses-result TEXT Only get tasks that have the provided result
statuses (use re_prefix for pattern
matching) (multiple) [env var:
AX_STATUSES_RESULT]
-sre, --statuses-result-error / -nsre, --no-statuses-result-error
Error if any result statuses provided are
not valid [env var:
AX_STATUSES_RESULT_ERROR; default: statuses-
result-error]
-srm, --statuses-result-minimum INTEGER
Error if matches for result statuses are <
this number [env var:
AX_STATUSES_RESULT_MINIMUM]
-id, --task-id INTEGER Only get tasks associated with this 'pretty
id' [env var: AX_TASK_ID]
-ps, --page-size INTEGER Number of rows to get per page [env var:
AX_PAGE_SIZE; default: 2000]
-rt, --row-start INTEGER Row to start on [env var: AX_ROW_START;
default: 0]
-rs, --row-stop INTEGER Row to stop on [env var: AX_ROW_STOP]
-ex, --explode / -nex, --no-explode
Explode each result for each task into
individual rows (defaults per --export-
format json:False, jsonl:False, csv:True)
[env var: AX_EXPLODE]
-sc, --schemas / -nsc, --no-schemas
Include schema definitions for each task and
result attribute (defaults per --export-
format json:False, jsonl:False, csv:True)
[env var: AX_SCHEMAS]
-xt, --export-format [str|json|jsonl|csv]
Format to write data as to STDOUT or
--export-file. [env var: AX_EXPORT_FORMAT;
default: str]
-xf, --export-file PATH File to send data to [env var:
AX_EXPORT_FILE]
-xo, --export-overwrite / -nxo, --no-export-overwrite
If --export-file supplied and it exists,
overwrite it [env var: AX_EXPORT_OVERWRITE;
default: no-export-overwrite]
-e, --echo / -ne, --no-echo Echo fetch messages to console. [env var:
AX_ECHO; default: echo]
--help Show this message and exit.
axonshell enforcements tasks get-filters
text
Usage: axonshell enforcements tasks get-filters [OPTIONS]
Get valid values for filtering count or get of Enforcement Center Tasks.
Options:
-u, --url URL URL of an Axonius instance [env var:
AX_URL; required]
-k, --key KEY API Key (or username if credentials=True) of
user in an Axonius instance [env var:
AX_KEY; required]
-s, --secret SECRET API Secret (or password if credentials=True)
of user in an Axonius instance [env var:
AX_SECRET; required]
-iat, --include-action-types / -niat, --no-include-action-types
Include Action types in use by any
Enforcement Set in output [env var:
AX_ACTION_TYPES; default: include-action-
types]
-idu, --include-discovery-uuids / -nidu, --no-include-discovery-uuids
Include UUIDs of Discovery Cycles that have
launched a task in output [env var:
AX_DISCOVERY_UUIDS; default: include-
discovery-uuids]
-ien, --include-enforcement-names / -nien, --no-include-enforcement-names
Include Names of all Enforcement Sets that
have launched a task in output [env var:
AX_ENFORCEMENT_NAMES; default: include-
enforcement-names]
-iti, --include-task-ids / -niti, --no-include-task-ids
Include Pretty IDs of all tasks for all
Enforcement Sets in output [env var:
AX_TASK_IDS; default: include-task-ids]
-is, --include-statuses / -nis, --no-include-statuses
Include Statuses of all tasks and task
results for all Enforcement Sets in output
[env var: AX_STATUSES; default: include-
statuses]
-xt, --export-format [str|json]
Format to write data as to STDOUT or
--export-file. [env var: AX_EXPORT_FORMAT;
default: str]
-xf, --export-file PATH File to send data to [env var:
AX_EXPORT_FILE]
-xo, --export-overwrite / -nxo, --no-export-overwrite
If --export-file supplied and it exists,
overwrite it [env var: AX_EXPORT_OVERWRITE;
default: no-export-overwrite]
--help Show this message and exit.
Added Cloudflared support
Cloudflared support has been introduced to axonshell. Numerous new options are now available:
text
-cfu, --cf-url TEXT CLOUDFLARE ACCESS TOKEN: URL to use in
cloudflared commands, will fallback to url
if not supplied [env var: CF_URL, AX_URL]
-cft, --cf-token TEXT CLOUDFLARE ACCESS TOKEN: token supplied by
user, will be checked for validity if not
empty [env var: CF_TOKEN]
-cfr, --cf-run / -ncfr, --no-cf-run
CLOUDFLARE ACCESS TOKEN: If no token
supplied or in OS env vars, try to get token
from cloudflared commands [env var: CF_RUN;
default: no-cf-run]
-cfrac, --cf-run-access / -ncfrac, --no-cf-run-access
CLOUDFLARE ACCESS TOKEN: If run is True, try
to get token from `access token` command
[env var: CF_RUN_ACCESS; default: cf-run-
access]
-cfrlc, --cf-run-login / -ncfrlc, --no-cf-run-login
CLOUDFLARE ACCESS TOKEN: If run is True and
no token returned from `access token`
command, try to get token from `access
login` command [env var: CF_RUN_LOGIN;
default: cf-run-login]
-cfp, --cf-path TEXT CLOUDFLARE ACCESS TOKEN: Path to cloudflared
binary to run, can be full path or path in
OS env var $PATH [env var: CF_PATH;
default: cloudflared]
-cfta, --cf-timeout-access INTEGER
CLOUDFLARE ACCESS TOKEN: Timeout for `access
token` command in seconds [env var:
CF_TIMEOUT_ACCESS; default: 60]
-cftl, --cf-timeout-login INTEGER
CLOUDFLARE ACCESS TOKEN: Timeout for `access
login` command in seconds [env var:
CF_TIMEOUT_LOGIN; default: 180]
-cfe, --cf-error / -ncfe, --no-cf-error
CLOUDFLARE ACCESS TOKEN: Raise error if an
invalid token is found or no token can be
found [env var: CF_ERROR; default: no-cf-
error]
-cfeac, --cf-error-access / -ncfeac, --no-cf-error-access
CLOUDFLARE ACCESS TOKEN: Raise exc if
`access token` command fails and login is
False [env var: CF_ERROR_ACCESS; default:
cf-error-access]
-cfel, --cf-error-login / -ncfel, --no-cf-error-login
CLOUDFLARE ACCESS TOKEN: Raise exc if
`access login` command fails [env var:
CF_ERROR_LOGIN; default: cf-error-login]
-cfec, --cf-echo / -ncfec, --no-cf-echo
CLOUDFLARE ACCESS TOKEN: Echo commands and
results to STDERR [env var: CF_ECHO;
default: cf-echo]
-cfev, --cf-echo-verbose / -ncfev, --no-cf-echo-verbose
CLOUDFLARE ACCESS TOKEN: Echo more stuff to
STDERR [env var: CF_ECHO_VERBOSE; default:
no-cf-echo-verbose]
With these new options and with cloudflared installed, axonshell can use cloudflared to automate the authentication and access to an Axonius instance is protected by a CF_ACCESS_TOKEN.
For example, to always automatically run cloudflared (and error if a cloudflare access token can not be fetched):
bash
echo 'CF_RUN="yes"' >> .env
echo 'CF_ERROR="yes"' >> .env
axonshell devices count
Or to run cloudflared for a specific command:
bash
axonshell --cf-run --cf-error devices count
Updated Enforcement Set Warning
The warning message displayed when creating an Enforcement Set has been updated to provide more information:
text
Enforcement Sets will be forced to the /Drafts folder if:
- Any configuration supplied for any action is invalid
- No Saved Query is supplied for the trigger
Easiest way to learn the correct configuration for an action:
- Create an Enforcement Set using the GUI
- export the Enforcement Set in JSON format using:
axonshell enforcements get -v "enforcement name" -xf json
- Get the 'config' dictionary for the action you want to use from the JSON output
- Use the 'config' dictionary as appropriate 'config' argument for this method
This updated message helps users understand how to create a valid Enforcement Set and highlights potential issues that might force the Enforcement Set to the /Drafts folder.
Added new option to enable max logging
The --log-http-max option has been added to Axonshell to simplify enabling maximum logging with just a single option.
This provides a shortcut to include the maximum output for HTTP logging, which can be incredibly useful for debugging purposes or for reverse engineering the API calls made by the API client during various workflows.
text
-lmax, --log-http-max / -nlmax, --no-log-http-max
Shortcut to include_output http logging -
overrides: log_request_body = True,
log_response_body = True, log_level_http =
"debug", log_level_package = "debug",
log_level_console = "debug", log_level_file
= "debug", log_request_attrs = "all",
log_response_attrs = "all", log_body_lines =
10000 [env var: AX_LOG_HTTP_MAX; default:
no-log-http-max]
Using the new option:
bash
axonshell -lmax -c devices count
Is equivalent to using:
bash
axonshell \
--log-request-body \
--log-response-body \
--log-request-attrs "all" \
--log-response-attrs "all" \
--log-level-console "debug" \
--log-level-file "debug" \
--log-body-lines 10000
--log-console
By using the --log-http-max option, you can easily enable comprehensive logging to better understand the underlying API interactions and troubleshoot any issues that may arise.
This feature enhances the user experience by offering a more streamlined approach to enabling maximum logging, making it easier to analyze API calls and resolve potential problems.
Saved Query now required for Enforcement Sets
The --query-name option is now required when creating Enforcement Sets using axonshell:
bash
axonshell enforcements create --query-name
Additionally, the `axonshell enforcements update-remove-query` command will now raise a NotAllowedError, as removing a saved query from an Enforcement Set is no longer allowed.
Add options to asset fetches to give more control over exports
The following commands have been updated to provide more control over CSV and XLSX exports:
bash
axonshell devices get, get-by-saved-query
axonshell users get, get-by-saved-query
axonshell vulnerabilities get, get-by-saved-query
Previously, certain options were automatically set to True for `--export-format csv` or `xslx`.
Now, these options have been exposed to axonshell, giving users more control over their exports:
text
--csv-field-flatten / --no-csv-field-flatten
For CSV/XLSX Export: Enable flattening of
complex fields [env var:
AX_CSV_FIELD_FLATTEN; default: csv-field-
flatten]
--csv-field-join / --no-csv-field-join
For CSV/XLSX Export: Enable joining of list
fields [env var: AX_CSV_FIELD_JOIN;
default: csv-field-join]
--csv-field-null / --no-csv-field-null
For CSV/XLSX Export: Enable null values for
missing fields [env var: AX_CSV_FIELD_NULL;
default: csv-field-null]
Add support for using column filters in get-by-saved-query
The following commands have been updated to support using column filters when fetching assets:
bash
axonshell devices get-by-saved-query
axonshell users get-by-saved-query
axonshell vulnerabilities get-by-saved-query
The following options have been added to support using column filters when fetching assets
by saved query:
text
-if, --include-fields / -nif, --no-include-fields
Include fields from the saved query GUI
Path: Assets Table => Columns, REST API
Saved Query path: view => query => fields,
REST API get assets argument: fields, API
Client get assets argument: fields:
Optional[list[str]] = None, axonshell get
assets argument: --fields/-f [env var:
AX_INCLUDE_FIELDS; default: include-fields]
-iea, --include-excluded-adapters / -niea, --no-include-excluded-adapters
Include column filters for excluded adapters
from the saved query GUI Path: Assets Table
=> Columns => Column Filters => Field values
- refine by adapter connection, REST API
Saved Query path: view =>
colExcludeAdapters, REST API get assets
argument: excluded_adapters, API Client get
assets argument: excluded_adapters:
Optional[list[dict]] = None, axonshell get
assets argument: NOT IMPLEMENTED (but is
used in get-by-saved-query) [env var:
AX_INCLUDE_EXCLUDE_ADAPTERS; default:
include-excluded-adapters]
-iaea, --include-asset-excluded-adapters / -niaea, --no-include-asset-excluded-adapters
Include column filters for asset excluded
adapters fields from the saved query GUI
Path: Assets Table => Columns => Column
Filters => Field values - refine by adapter
connection, REST API Saved Query path: view
=> colExcludeAdapters, REST API get assets
argument: excluded_adapters, API Client get
assets argument: excluded_adapters:
Optional[list[dict]] = None, axonshell get
assets argument: NOT IMPLEMENTED (but is
used in get-by-saved-query) [env var:
AX_INCLUDE_ASSET_EXCLUDE_ADAPTERS; default:
include-asset-excluded-adapters]
-iff, --include-field-filters / -niff, --no-include-field-filters
Include column filters for field filters
from the saved query GUI Path: Assets Table
=> Columns => Column Filters => Field values
- refine by condition, REST API Saved Query
path: view => colFilters, REST API get
assets argument: field_filters, API Client
get assets argument: field_filters:
Optional[list[dict]] = None, axonshell get
assets argument: NOT IMPLEMENTED (but is
used in get-by-saved-query) [env var:
AX_INCLUDE_FIELD_FILTERS; default: include-
field-filters]
-iaf, --include-asset-filters / -niaf, --no-include-asset-filters
Include column filters for asset filters
from the saved query GUI Path: Assets Table
=> Columns => Column Filters => Asset
entities - refine by condition, REST API
Saved Query path: view =>
assetConditionExpressions, REST API get
assets argument: asset_filters, API Client
get assets argument: asset_filters:
Optional[list[dict] = None, axonshell get
assets argument: NOT IMPLEMENTED (but is
used in get-by-saved-query) [env var:
AX_INCLUDE_ASSET_FILTERS; default: include-
asset-filters]
-uce, --use-cache-entry / -nuce, --no-use-cache-entry
Ask the API to use a cache entry for this
query, if available [env var:
AX_USE_CACHE_ENTRY; default: no-use-cache-
entry]
In this release, support for using column filters when fetching assets by saved query has been added to Axonshell.
New options have been introduced to allow users to include fields, excluded adapters, asset excluded adapters, field filters, and asset filters from the saved query.
Additionally, an option has been added to ask the API to use a cache entry for the query if available.
Previously, the --include-fields option was automatically set to True for get-by-saved-query.
Now, you can disable it in order to exclude the fields defined in the saved query GUI with your fetch.
The API client now supports using column filters when fetching assets by saved query, as it has been brought up to date with the REST API models.
This update enhances the flexibility and functionality of Axonshell when fetching assets by saved query, providing users with more control over the data they retrieve.
Add options to asset fetches to support REST API features
The following commands have been updated to provide access to new REST API features:
bash
axonshell devices get, get-by-saved-query
axonshell users get, get-by-saved-query
axonshell vulnerabilities get, get-by-saved-query
The following options have been added to support new REST API features for asset fetches:
text
-anfne, --api-null-for-non-exist / -nanfne, --no-api-null-for-non-exist
Ask the REST API to return null for non
existent fields [env var:
AX_NULL_FOR_NON_EXIST; default: no-api-null-
for-non-exist]
-afonef, --api-filter-out-non-existing-fields / -nafonef, --no-api-filter-out-non-existing-fields
Ask the REST API to filter out non existent
fields [env var:
AX_FILTER_OUT_NON_EXISTING_FIELDS; default:
api-filter-out-non-existing-fields]
-amfi, --api-max-field-items INTEGER
Ask the REST API to limit the number of
values returned for a field [env var:
AX_MAX_FIELD_ITEMS]
-amcfi, --api-complex-fields-preview-limit INTEGER
Ask the REST API to limit the number of
values returned for a complex field [env
var: AX_COMPLEX_FIELDS_PREVIEW_LIMIT]
-ahfc, --api-use-heavy-fields-collection / -nahfc, --no-api-use-heavy-fields-collection
Ask the REST API to use the heavy fields
collection [env var:
AX_USE_HEAVY_FIELDS_COLLECTION; default: no-
api-use-heavy-fields-collection]
These new options allow users to interact with the REST API in a more tailored and efficient manner.
Users can now:
* request null values for non-existent fields (different logic than the API clients --field-null)
* filter out non-existent fields
* limit the number of values returned for a field or a complex field
* decide whether to use the heavy fields collection during asset fetches
New help-detailed option for asset fetches
The following commands have a new --help-detailed choice:
bash
axonshell devices get, get-by-saved-query
axonshell users get, get-by-saved-query
axonshell vulnerabilities get, get-by-saved-query
Example:
bash
axonshell devices get --help-detailed asset_helper
This new --help-detailed choice provides comprehensive information on the various attributes used in fetching assets, creating saved queries, and more.
This new feature enhances user experience by offering more detailed guidance and support for using the Axonshell commands effectively.
Users can now easily access in-depth information on specific attributes or options in a convenient and streamlined manner.
Feel free to look at the other --help-detailed sections:
bash
✗ axonshell devices get --help-detailed x
Usage: axonshell devices get [OPTIONS]
Try 'axonshell devices get --help' for help.
Error: Invalid value for '--help-detailed': 'x' is not one of
'auth', 'query', 'assetexport', 'selectfields', 'wizard', 'asset_helper'.
Startup banner enhancements
The startup banner for axonshell has been improved to provide more useful information to users. This includes:
* Basic details of the SSL certificate offered by the Axonius instance.
* Basic details about the current user running axonshell.
* Trial, license, and SSL expiry numbers are always displayed and color-coded
based on their ranges.
text
** Connected to 'https://..:443', CLIENT v5.0.0, PYTHON v3.11.2 [signup on 2023-04-17 23:18:43.171026]
Axonius Version 'DEMO', Build Date: '2023-04-17' (14 days ago)
SSL Issued To: 'C=US, ST=California, L=San Francisco, O=Cloudflare, Inc., CN=axonius.com', Expires On: '2023-10-30 23:59:59+00:00'
User: 'admin', Source: 'internal', Role: 'Admin', Last Login Delta: 0:00:01.854351
** WARNING: Trial expires in 16 days (error<=15, warn<=30, info<=45, debug=None or > info)
** License expires in None days (error<=30, warn<=60, info<=90, debug=None or > info)
** SSL Certificate expires in 182 days (error<=60, warn<=90, info<=120, debug=None or > info)
These enhancements make it easier for users to quickly access relevant information about their Axonius instance, user account, and license status.
axonshell tools shell enhancements
The `axonshell tools shell` command has been enhanced to provide an updated list of shortcuts for various models, accounting for additions over time.
A helpful HELP string has also been added so that you can easily view the available shortcuts:
text
$ axonshell tools shell
Welcome human. We have some refreshments available for you:
Local variables available:
- axonapi: API client package itself
- client/c: API Client connection object
- ctx: Click context object
- jdump/j: Helper function to pretty print python objects
- j(HELP): this message
Local variables as shortcuts from client properties:
- activity_logs/al: Work with activity logs
- adapters/a: Work with adapters and adapter connections
- dashboard/db: Work with discovery cycle
- dashboard_spaces/dbs: Work with dashboard spaces
- data_scopes/ds: Work with data scopes
- devices/d: Work with device assets
- folders/f: Work with folders
- instances/i: Work with instances
- meta/m: Work with instance metadata
- remote_support/rs: Work with configuring system remote support
- settings_global/sgl: Work with Global system settings
- settings_gui/sgu: Work with GUI system settings
- settings_lifecycle/sl: Work with lifecycle system settings
- settings_ip/sip: Work with Identity Provider system settings
- enforcements/e: Work with enforcements
- system_roles/sr: Work with system roles
- system_users/su: Work with system users
- users/u: Work with user assets
- openapi/oas: Work with the OpenAPI specification file
- vulnerabilities/v: Work with vulnerability assets
>>>
These enhancements make it easier and more convenient for users to access and work with different models using the axonshell tools shell.
Library changes
In this release, several significant changes have been made to the library structure.
New projects directory
A new "projects" directory has been created to accommodate packages that originated as projects and could potentially be moved into their own separate Python packages.
The cert_human package has been relocated to this new directory, along with the url_parser package and a newly created cf_token package, which has been developed to support this release.
These changes reflect the ongoing evolution and organization of the library, ensuring better maintainability and ease of use for developers working with these packages.
axonius_api_client.http.Http signature rewrite
The signature of the Http class has been restructured to make it more user-friendly and consistent with the rest of the library.
The most notable change is that all arguments are now exposed as keyword arguments, and many of them use default values that are defined as constants that can be overridden.
Additionally, the docstrings have been updated to provide more detailed information on the various arguments.
Previously, these options were hidden behind a complex kwargs dictionary that was difficult to use and understand.
python
class Http:
def __init__(
self,
url: t.Union[UrlParser, str],
certpath: t.Optional[PathLike] = None,
certwarn: bool = CERT_WARN,
certverify: bool = CERT_VERIFY,
headers: t.Optional[T_Headers] = None,
cookies: t.Optional[T_Cookies] = None,
cert_client_both: t.Optional[PathLike] = None,
cert_client_cert: t.Optional[PathLike] = None,
cert_client_key: t.Optional[PathLike] = None,
connect_timeout: t.Optional[t.Union[int, float]] = CONNECT_TIMEOUT,
response_timeout: t.Optional[t.Union[int, float]] = RESPONSE_TIMEOUT,
http_proxy: t.Optional[str] = None,
https_proxy: t.Optional[str] = None,
log_body_lines: int = LOG_BODY_LINES,
log_hide_headers: t.Optional[PatternLikeListy] = HIDE_HEADERS,
log_hide_str: t.Optional[str] = LOG_HIDE_STR,
log_level: t.Union[int, str] = LOG_LEVEL,
log_level_urllib: t.Union[int, str] = LOG_LEVEL_URLLIB,
log_request_attrs: t.Optional[t.Union[str, t.Iterable[str]]] = None,
log_request_body: bool = LOG_REQUEST_BODY,
log_response_attrs: t.Optional[t.Union[str, t.Iterable[str]]] = None,
log_response_body: bool = LOG_RESPONSE_BODY,
save_history: bool = SAVE_HISTORY,
save_last: bool = SAVE_LAST,
cf_token: t.Optional[str] = None,
cf_url: t.Optional[str] = None,
cf_path: t.Optional[PathLike] = cf_constants.CF_PATH,
cf_run: bool = cf_constants.CLIENT_RUN,
cf_run_login: bool = cf_constants.FLOW_RUN_LOGIN,
cf_run_access: bool = cf_constants.FLOW_RUN_ACCESS,
cf_env: bool = cf_constants.FLOW_ENV,
cf_echo: bool = cf_constants.FLOW_ECHO,
cf_echo_verbose: bool = cf_constants.FLOW_ECHO_VERBOSE,
cf_error: bool = cf_constants.CLIENT_ERROR,
cf_error_login: bool = cf_constants.FLOW_ERROR,
cf_error_access: bool = cf_constants.FLOW_ERROR,
cf_timeout_access: t.Optional[int] = cf_constants.TIMEOUT_ACCESS,
cf_timeout_login: t.Optional[int] = cf_constants.TIMEOUT_LOGIN,
**kwargs,
):
"""HTTP client that wraps around :obj:`requests.Session`.
Notes:
* If certpath is supplied, certverify is ignored
* private key supplied to cert_client_key or cert_client_both
can **NOT** be password encrypted
Args:
url: URL, hostname, or IP address of Axonius instance
certpath: token to CA bundle file to use when verifying certs offered by :attr:`url`
certwarn: show insecure warning once or never show insecure warning
certverify: raise exception if cert is self-signed or only if cert is invalid
headers: headers to send with every request
cookies: cookies to send with every request
log_level: log level to use for this object
log_body_lines: max length of request and response bodies to log
log_hide_headers: headers to hide when logging
save_last: save last request and response to :attr:`last_request` and
:attr:`last_response`
save_history: save all requests and responses to :attr:`history`
connect_timeout: seconds to wait for connections to open to :attr:`url`
response_timeout: seconds to wait for responses from :attr:`url`
log_request_body: log the request body
log_response_body: log the response body
http_proxy: proxy to use when making http requests to :attr:`url`
https_proxy: proxy to use when making https requests to :attr:`url`
log_level_urllib: log level to use for urllib3
cert_client_key: path to client private key file
cert_client_both: path to client private key and cert file
cert_client_cert: path to client cert file
cf_url: URL to use in `access token` and `access login` commands,
will fallback to url if not supplied
cf_token: access token supplied by user, will be checked for validity if not empty
cf_env: if no token supplied, try to get token from OS env var CF_TOKEN
cf_run: if no token supplied or in OS env vars, try to get token from `access token` and
`access login` commands
cf_run_access: if run is True, try to get token from `access token`,
cf_run_login: if run is True and no token returned from `access token` command,
try to get token from `access login` command
cf_path: path to cloudflared binary to run, can be full path or path in OS env var $PATH
cf_timeout_access: timeout for `access token` command in seconds
cf_timeout_login: timeout for `access login` command in seconds
cf_error: raise error if an invalid token is found or no token can be found
cf_error_access: raise exc if `access token` command fails and login is False
cf_error_login: raise exc if `access login` command fails
cf_echo: echo commands and results to stdout
cf_echo_verbose: echo checks to stdout
**kwargs: no longer used, will throw a deprecation warning
Raises:
:exc:`HttpError`:
- if either cert_client_cert or cert_client_key are supplied, and the other is
not supplied
- if any of cert_path, cert_client_cert, cert_client_key, or cert_client_both
are supplied and the file does not exist
"""
Docstring updates galore
I will be continuing to update docstrings to be more consistent and to include more information.
ApiEndpoint refactor
The `ApiEndpoint` class has been refactored to address some issues with the interface between ApiEndpoint and Connect objects.
get_env_connect returns more Connect args
Whereas previously `get_env_connect` returned only the `url`, `key`, `secret`, and `certwarn` arguments, it now returns some of the new arguments that are critical for authentication and connection.
python
import axonius_api_client as axonapi
connect_args = axonapi.get_env_connect()
print(list(connect_args.keys()))
['url', 'key', 'secret', 'certwarn', 'credentials', 'cf_token', 'cf_path', 'cf_run', 'cf_error']
JSONAPI models refactor
I am starting to refactor all the JSONAPI models and schemas to be:
* standardized
* only one schema & model pair per file
* ensure they are in sync with the current model definitions in the REST API
* have a consistent naming scheme.
This work will be finished over multiple releases.
Eventually I want to create a tool that will automatically generate the marshmallow schemas and dataclass containers and CLI arguments via click from the REST API definitions
AuthModel refactor
The `AuthModel` class has been refactored to bring it into line with the changes to `Connect` and `Http`.
AuthModel now has a much simpler signature, and the docstrings have been updated to provide more detailed information on the various arguments.
There are now 3 AuthModels: ApiKey, Credentials, and Null (used for Signup).
axonius_api_client.connect.Connect signature rewrite and refactor
Similar to the `Http` class, the signature of the `Connect` class has been rewritten to be easier to understand and use.
This was necessary because while `Http` is a wrapper around `requests.Session`, `Connect` is a wrapper around `Http` and `axonius_api_client.auth.AuthModel`.
The most notable change is that all arguments are now exposed as keyword arguments, and many of them use default values that are defined as constants that can be overridden.
Additionally, the docstrings have been updated to provide more detailed information on the various arguments.
Previously, these options were hidden behind a complex kwargs dictionary that was difficult to use and understand.
Additionally, much of the core logic of Connect was refactored to be more modular and easier to maintain.
python
class Connect:
def __init__(
self,
url: str,
key: str,
secret: str,
log_console: bool = False,
log_file: bool = False,
log_file_rotate: bool = False,
certpath: t.Optional[PathLike] = None,
certverify: bool = False,
certwarn: bool = True,
proxy: t.Optional[str] = None,
headers: t.Optional[T_Headers] = None,
cookies: t.Optional[T_Cookies] = None,
credentials: bool = False,
timeout_connect: t.Optional[t.Union[int, float]] = Http.CONNECT_TIMEOUT,
timeout_response: t.Optional[t.Union[int, float]] = Http.RESPONSE_TIMEOUT,
cert_client_key: t.Optional[PathLike] = None,
cert_client_cert: t.Optional[PathLike] = None,
cert_client_both: t.Optional[PathLike] = None,
save_history: bool = False,
log_level: t.Union[str, int] = "debug",
log_request_attrs: t.Optional[t.Union[str, t.Iterable[str]]] = None,
log_response_attrs: t.Optional[t.Union[str, t.Iterable[str]]] = None,
log_request_body: bool = False,
log_response_body: bool = False,
log_logger: logging.Logger = LOG_LOGGER,
log_level_package: t.Union[str, int] = LOG_LEVEL_PACKAGE,
log_level_endpoints: t.Union[str, int] = LOG_LEVEL_ENDPOINTS,
log_level_http: t.Union[str, int] = Http.LOG_LEVEL,
log_level_auth: t.Union[str, int] = LOG_LEVEL_AUTH,
log_level_api: t.Union[str, int] = LOG_LEVEL_API,
log_level_console: t.Union[str, int] = LOG_LEVEL_CONSOLE,
log_level_file: t.Union[str, int] = LOG_LEVEL_FILE,
log_console_fmt: str = LOG_FMT_BRIEF,
log_http_max: bool = LOG_HTTP_MAX,
log_file_fmt: str = LOG_FMT_VERBOSE,
log_file_name: t.Optional[PathLike] = LOG_FILE_NAME,
log_file_path: t.Optional[PathLike] = LOG_FILE_PATH,
log_file_max_mb: int = LOG_FILE_MAX_MB,
log_file_max_files: int = LOG_FILE_MAX_FILES,
log_hide_secrets: bool = True,
log_body_lines: int = Http.LOG_BODY_LINES,
wraperror: bool = True,
cf_token: t.Optional[str] = None,
cf_url: t.Optional[str] = None,
cf_path: t.Optional[PathLike] = cf_constants.CF_PATH,
cf_run: bool = cf_constants.CLIENT_RUN,
cf_run_login: bool = cf_constants.FLOW_RUN_LOGIN,
cf_run_access: bool = cf_constants.FLOW_RUN_ACCESS,
cf_env: bool = cf_constants.FLOW_ENV,
cf_echo: bool = cf_constants.FLOW_ECHO,
cf_echo_verbose: bool = cf_constants.FLOW_ECHO_VERBOSE,
cf_error: bool = cf_constants.CLIENT_ERROR,
cf_error_login: bool = cf_constants.FLOW_ERROR,
cf_error_access: bool = cf_constants.FLOW_ERROR,
cf_timeout_access: t.Optional[int] = cf_constants.TIMEOUT_ACCESS,
cf_timeout_login: t.Optional[int] = cf_constants.TIMEOUT_LOGIN,
http: t.Optional[Http] = None,
auth: t.Optional[AuthModel] = None,
auth_null: t.Optional[AuthModel] = None,
**kwargs,
):
"""Easy all-in-one connection handler.
Args:
url: URL, hostname, or IP address of Axonius instance
key: API Key from account page in Axonius instance
secret: API Secret from account page in Axonius instance
log_console: include_output logging to console
log_file: include_output logging to file
certpath: path to CA bundle file to use when verifying certs offered by url
certverify: raise exception if cert is self-signed or only if cert is invalid
certwarn: show insecure warning once or never show insecure warning
proxy: proxy to use when making https requests to url
headers: additional headers to supply with every request
cookies: additional cookies to supply with every request
credentials: treat key as username as secret as password
timeout_connect: seconds to wait for connections to open to url
timeout_response: seconds to wait for responses from url
cert_client_key: file with private key to offer to url
cert_client_cert: file with client cert to offer to url
cert_client_both: file with client cert and private key to offer to url
save_history: save history of responses to Http.HISTORY
log_level: log level to use for this object
log_request_attrs: list of request attributes to log
log_response_attrs: list of response attributes to log
log_request_body: log request body
log_response_body: log response body
log_logger: Logger for the entire package, where console and file output
handlers will be attached to
log_level_package: log level to use for package root logger
log_level_endpoints: log level to use for endpoint loggers
log_level_http: log level to use for http loggers
log_level_auth: log level to use for auth loggers
log_level_api: log level to use for api loggers
log_level_console: log level to use for console loggers
log_level_file: log level to use for file loggers
log_console_fmt: format string to use for console logging
log_file_fmt: format string to use for file logging
log_file_name: name of file to log to
log_file_path: path to directory to log to
log_file_max_mb: max size of log file in MB
log_file_max_files: max number of log files to keep
log_body_lines: max length of request/response body to log
log_hide_secrets: hide secrets in logs
log_http_max: Shortcut to include_output ALL http logging *warning: heavy log output*
wraperror: wrap certain errors in a more user friendly format
cf_url: URL to use in `access token` and `access login` commands,
will fallback to url if not supplied
cf_token: access token supplied by user, will be checked for validity if not empty
cf_env: if no token supplied, try to get token from OS env var CF_TOKEN
cf_run: if no token supplied or in OS env vars, try to get token from `access token` and
`access login` commands
cf_run_access: if run is True, try to get token from `access token`,
cf_run_login: if run is True and no token returned from `access token` command,
try to get token from `access login` command
cf_path: path to cloudflared binary to run, can be full path or path in OS env var $PATH
cf_timeout_access: timeout for `access token` command in seconds
cf_timeout_login: timeout for `access login` command in seconds
cf_error: raise error if an invalid token is found or no token can be found
cf_error_access: raise exc if `access token` command fails and login is False
cf_error_login: raise exc if `access login` command fails
cf_echo: echo commands and results to stderr
cf_echo_verbose: echo more to stderr
http: http object to use for this connection
auth: auth model to use for this connection
auth_null: null auth model to use for this connection
**kwargs: unused
"""
New ApiModel client.enforcements.tasks
Methods available:
text
count(): Get the number of tasks that match the provided filters in request_obj
get_filters(): Get all filters (enums) for all enforcements
get(): Get all tasks that match the provided filters in request_obj
build_get_request(): Build a request object for get() and count()
get_generator(): Get all tasks that match the provided filters in request_obj as a generator
direct_get_generator(): Direct API method to get all tasks for enforcements in basic model as a generator
direct_count(): Direct API method to get the number of tasks for enforcements.
direct_get(): Direct API method to get all tasks for enforcements in basic model.
get_full(): Direct API method to get a single task for an enforcement in full model.
New project cf_token
This project makes all the cloudflare access token magic available as a standalone package.
AssetMixin.get_generator signature rewrite
The signature of `AssetMixin.get_generator` has been rewritten to be more flexible and easier to use.
Many of these arguments were previously hidden behind kwargs.
There are still a ton of arguments hidden behind kwargs, they are all defined in
`axonius_api_client.api.asset_callbacks.base.Base.args_map()`
There are new arguments to allow for column filters to be supplied as part of the request object: field_filters, excluded_adapters, asset_excluded_adapters, asset_filters.
These column filters are all fairly complex and undocumented.
Create queries in the GUI with column filters defined in them to get an idea of how they work.
There are many new arguments as a result of updating the JSONAPI models to be in sync with the REST API model definitions.
Finally, the API client now sends a proper query ID and frontend_sent_time with every request, along with other new attributes that are used by the REST API.
python
def get_generator(
self,
query: t.Optional[str] = None,
fields: t.Optional[t.Union[t.List[str], str]] = None,
fields_manual: t.Optional[t.Union[t.List[str], str]] = None,
fields_regex: t.Optional[t.Union[t.List[str], str]] = None,
fields_regex_root_only: bool = True,
fields_fuzzy: t.Optional[t.Union[t.List[str], str]] = None,
fields_default: bool = True,
fields_root: t.Optional[str] = None,
fields_error: bool = True,
max_rows: t.Optional[int] = None,
max_pages: t.Optional[int] = None,
row_start: int = 0,
page_size: int = MAX_PAGE_SIZE,
page_start: int = 0,
page_sleep: int = 0,
export: str = DEFAULT_CALLBACKS_CLS,
sort_field: t.Optional[str] = None,
sort_descending: bool = False,
history_date: t.Optional[t.Union[str, datetime.timedelta, datetime.datetime]] = None,
history_days_ago: t.Optional[int] = None,
history_exact: bool = False,
wiz_entries: t.Optional[t.Union[t.List[dict], t.List[str], dict, str]] = None,
wiz_parsed: t.Optional[dict] = None,
file_date: t.Optional[str] = None,
use_heavy_fields_collection: bool = False,
sort_field_parsed: t.Optional[str] = None,
search: t.Optional[str] = None,
history_date_parsed: t.Optional[str] = None,
field_filters: t.Optional[t.List[dict]] = None,
excluded_adapters: t.Optional[t.List[dict]] = None,
asset_excluded_adapters: t.Optional[t.List[dict]] = None,
asset_filters: t.Optional[t.List[dict]] = None,
expressions: t.Optional[t.List[dict]] = None,
fields_parsed: t.Optional[t.Union[dict, t.List[str]]] = None,
include_details: bool = False,
include_notes: bool = False,
use_cursor: bool = True,
cursor_id: t.Optional[str] = None,
saved_query_id: t.Optional[str] = None,
query_id: t.Optional[t.Union[str, uuid.UUID]] = None,
is_refresh: bool = False,
null_for_non_exist: bool = False,
source_component: t.Optional[str] = None,
frontend_sent_time: t.Optional[datetime.datetime] = None,
filter_out_non_existing_fields: bool = True,
complex_fields_preview_limit: t.Optional[int] = None,
max_field_items: t.Optional[int] = None,
initial_count: t.Optional[int] = None,
request_obj: t.Optional[AssetRequest] = None,
export_templates: t.Optional[dict] = None,
http_args: t.Optional[dict] = None,
**kwargs,
) -> t.Generator[dict, None, None]:
"""Get assets from a query.
See Also:
If ``export`` is not supplied, see
:meth:`axonius_api_client.api.asset_callbacks.base.Base.args_map`.
If ``export`` equals ``json``, see
:meth:`axonius_api_client.api.asset_callbacks.base_json.Json.args_map`.
If ``export`` equals ``csv``, see
:meth:`axonius_api_client.api.asset_callbacks.base_csv.Csv.args_map`.
If ``export`` equals ``json_to_csv``, see
:meth:`axonius_api_client.api.asset_callbacks.base_json_to_csv.JsonToCsv.args_map`.
If ``export`` equals ``table``, see
:meth:`axonius_api_client.api.asset_callbacks.base_table.Table.args_map`.
If ``export`` equals ``xlsx``, see
:meth:`axonius_api_client.api.asset_callbacks.base_xlsx.Xlsx.args_map`.
:obj:`axonius_api_client.constants.asset_helpers.ASSET_HELPERS` for a list of
helpers that translate between GUI titles, API request attributes, and saved query
paths.
Args:
query: if supplied, only get the assets that match the query
fields: fields to return for each asset (will be validated)
fields_manual: fields to return for each asset (will NOT be validated)
fields_regex: regex of fields to return for each asset
fields_regex_root_only: only match fields_regex values against root fields
fields_fuzzy: string to fuzzy match of fields to return for each asset
fields_default: include the default fields in :attr:`fields_default`
fields_root: include all fields of an adapter that are not complex sub-fields
fields_error: throw validation errors on supplied fields
max_rows: only return N rows
max_pages: only return N pages
row_start: start at row N
page_size: fetch N rows per page
page_start: start at page N
page_sleep: sleep for N seconds between each page fetch
export: export assets using a callback method
include_notes: include any defined notes for each adapter
include_details: include details fields showing the adapter source of agg values
saved_query_id: ID of saved query this fetch is associated with
expressions: expressions used by query wizard to create query
sort_field: sort the returned assets on a given field
sort_descending: reverse the sort of the returned assets
history_date: return assets for a given historical date
history_days_ago: return assets for a history date N days ago
history_exact: Use the closest match for history_date and history_days_ago
wiz_entries: wizard expressions to create query from
file_date: string to use in filename templates for {DATE}
wiz_parsed: parsed output from a query wizard
fields_parsed: previously parsed fields
sort_field_parsed: previously parsed sort field
history_date_parsed: previously parsed history date
initial_count: previously fetched initial count
search: search string to use for this query
use_heavy_fields_collection: unknown
use_cursor: use cursor based pagination
field_filters: field filters to apply to this query
excluded_adapters: adapters to exclude from this query
asset_excluded_adapters: adapters to exclude from this query
asset_filters: asset filters to apply to this query
cursor_id: cursor ID to use for this query
query_id: query ID to use for this query
is_refresh: is this a refresh query
null_for_non_exist: return null for non existent fields
source_component: source component to use for this query
export_templates: filename template replacement mappings
filter_out_non_existing_fields: filter out fields that do not exist
complex_fields_preview_limit: limit the number of complex fields to preview
max_field_items: max number of items to return for a field
frontend_sent_time: frontend sent time to use for this query
http_args: http args to pass to :meth:`axonius_api_client.http.Http.__call__` for each
page fetched
request_obj: request object to use for this query
**kwargs: passed thru to the asset callback defined in ``export``
"""
def get_generator(
self,
query: t.Optional[str] = None,
fields: t.Optional[t.Union[t.List[str], str]] = None,
fields_manual: t.Optional[t.Union[t.List[str], str]] = None,
fields_regex: t.Optional[t.Union[t.List[str], str]] = None,
fields_regex_root_only: bool = True,
fields_fuzzy: t.Optional[t.Union[t.List[str], str]] = None,
fields_default: bool = True,
fields_root: t.Optional[str] = None,
fields_error: bool = True,
max_rows: t.Optional[int] = None,
max_pages: t.Optional[int] = None,
row_start: int = 0,
page_size: int = MAX_PAGE_SIZE,
page_start: int = 0,
page_sleep: int = 0,
export: str = DEFAULT_CALLBACKS_CLS,
sort_field: t.Optional[str] = None,
sort_descending: bool = False,
history_date: t.Optional[t.Union[str, datetime.timedelta, datetime.datetime]] = None,
history_days_ago: t.Optional[int] = None,
history_exact: bool = False,
wiz_entries: t.Optional[t.Union[t.List[dict], t.List[str], dict, str]] = None,
wiz_parsed: t.Optional[dict] = None,
file_date: t.Optional[str] = None,
use_heavy_fields_collection: bool = False,
sort_field_parsed: t.Optional[str] = None,
search: t.Optional[str] = None,
history_date_parsed: t.Optional[str] = None,
field_filters: t.Optional[t.List[dict]] = None,
excluded_adapters: t.Optional[t.List[dict]] = None,
asset_excluded_adapters: t.Optional[t.List[dict]] = None,
asset_filters: t.Optional[t.List[dict]] = None,
expressions: t.Optional[t.List[dict]] = None,
fields_parsed: t.Optional[t.Union[dict, t.List[str]]] = None,
include_details: bool = False,
include_notes: bool = False,
use_cursor: bool = True,
cursor_id: t.Optional[str] = None,
saved_query_id: t.Optional[str] = None,
query_id: t.Optional[t.Union[str, uuid.UUID]] = None,
is_refresh: bool = False,
null_for_non_exist: bool = False,
source_component: t.Optional[str] = None,
frontend_sent_time: t.Optional[datetime.datetime] = None,
filter_out_non_existing_fields: bool = True,
complex_fields_preview_limit: t.Optional[int] = None,
max_field_items: t.Optional[int] = None,
initial_count: t.Optional[int] = None,
request_obj: t.Optional[AssetRequest] = None,
export_templates: t.Optional[dict] = None,
http_args: t.Optional[dict] = None,
**kwargs,
) -> t.Generator[dict, None, None]:
"""Get assets from a query.
See Also:
If ``export`` is not supplied, see
:meth:`axonius_api_client.api.asset_callbacks.base.Base.args_map`.
If ``export`` equals ``json``, see
:meth:`axonius_api_client.api.asset_callbacks.base_json.Json.args_map`.
If ``export`` equals ``csv``, see
:meth:`axonius_api_client.api.asset_callbacks.base_csv.Csv.args_map`.
If ``export`` equals ``json_to_csv``, see
:meth:`axonius_api_client.api.asset_callbacks.base_json_to_csv.JsonToCsv.args_map`.
If ``export`` equals ``table``, see
:meth:`axonius_api_client.api.asset_callbacks.base_table.Table.args_map`.
If ``export`` equals ``xlsx``, see
:meth:`axonius_api_client.api.asset_callbacks.base_xlsx.Xlsx.args_map`.
:obj:`axonius_api_client.constants.asset_helpers.ASSET_HELPERS` for a list of
helpers that translate between GUI titles, API request attributes, and saved query
paths.
Args:
query: if supplied, only get the assets that match the query
fields: fields to return for each asset (will be validated)
fields_manual: fields to return for each asset (will NOT be validated)
fields_regex: regex of fields to return for each asset
fields_regex_root_only: only match fields_regex values against root fields
fields_fuzzy: string to fuzzy match of fields to return for each asset
fields_default: include the default fields in :attr:`fields_default`
fields_root: include all fields of an adapter that are not complex sub-fields
fields_error: throw validation errors on supplied fields
max_rows: only return N rows
max_pages: only return N pages
row_start: start at row N
page_size: fetch N rows per page
page_start: start at page N
page_sleep: sleep for N seconds between each page fetch
export: export assets using a callback method
include_notes: include any defined notes for each adapter
include_details: include details fields showing the adapter source of agg values
saved_query_id: ID of saved query this fetch is associated with
expressions: expressions used by query wizard to create query
sort_field: sort the returned assets on a given field
sort_descending: reverse the sort of the returned assets
history_date: return assets for a given historical date
history_days_ago: return assets for a history date N days ago
history_exact: Use the closest match for history_date and history_days_ago
wiz_entries: wizard expressions to create query from
file_date: string to use in filename templates for {DATE}
wiz_parsed: parsed output from a query wizard
fields_parsed: previously parsed fields
sort_field_parsed: previously parsed sort field
history_date_parsed: previously parsed history date
initial_count: previously fetched initial count
search: search string to use for this query
use_heavy_fields_collection: unknown
use_cursor: use cursor based pagination
field_filters: field filters to apply to this query
excluded_adapters: adapters to exclude from this query
asset_excluded_adapters: adapters to exclude from this query
asset_filters: asset filters to apply to this query
cursor_id: cursor ID to use for this query
query_id: query ID to use for this query
is_refresh: is this a refresh query
null_for_non_exist: return null for non existent fields
source_component: source component to use for this query
export_templates: filename template replacement mappings
filter_out_non_existing_fields: filter out fields that do not exist
complex_fields_preview_limit: limit the number of complex fields to preview
max_field_items: max number of items to return for a field
frontend_sent_time: frontend sent time to use for this query
http_args: http args to pass to :meth:`axonius_api_client.http.Http.__call__` for each
page fetched
request_obj: request object to use for this query
**kwargs: passed thru to the asset callback defined in ``export``
"""
AssetMixin.get_by_saved_query rewrite
python
def get_by_saved_query(
self,
name: str,
include_fields: bool = True,
include_excluded_adapters: bool = True,
include_asset_excluded_adapters: bool = True,
include_field_filters: bool = True,
include_asset_filters: bool = True,
**kwargs,
) -> GEN_TYPE:
"""Get assets that would be returned by a saved query.
Examples:
First, create a ``client`` using :obj:`axonius_api_client.connect.Connect` and assume
``apiobj`` is ``client.devices`` or ``client.users``
>>> import axonius_api_client as axonapi
>>> connect_args: dict = axonapi.get_env_connect()
>>> client: axonapi.Connect = axonapi.Connect(**connect_args)
>>> apiobj: axonapi.api.assets.AssetMixin = client.devices
>>> or client.users or client.vulnerabilities
Get assets from a saved query with complex fields flattened
>>> assets: t.List[dict] = apiobj.get_by_saved_query(name="test", field_flatten=True)
See Also:
:obj:`axonius_api_client.constants.asset_helpers.ASSET_HELPERS` for a list of
helpers that translate between GUI titles, API request attributes, and saved query
paths.
Args:
name: name of saved query to get assets from
include_fields: include fields from saved query
include_excluded_adapters: include column filters for excluded adapters from saved query
include_asset_excluded_adapters: include column filters for asset excluded adapters
from saved query
include_field_filters: include column filters for field filters from saved query
include_asset_filters: include column filters for asset filters from saved query
**kwargs: passed to :meth:`get`
"""
AssetMixin.count rewrite
python
def count(
self,
query: t.Optional[str] = None,
history_date: t.Optional[t.Union[str, datetime.timedelta, datetime.datetime]] = None,
history_days_ago: t.Optional[int] = None,
history_exact: bool = False,
wiz_entries: t.Optional[t.Union[t.List[dict], t.List[str], dict, str]] = None,
wiz_parsed: t.Optional[t.List[dict]] = None,
history_date_parsed: t.Optional[str] = None,
use_cache_entry: bool = False,
use_heavy_fields_collection: bool = False,
frontend_sent_time: t.Optional[datetime.datetime] = None,
query_id: t.Optional[t.Union[str, uuid.UUID]] = None,
saved_query_id: t.Optional[str] = None,
request_obj: t.Optional[CountRequest] = None,
http_args: t.Optional[dict] = None,
sleep: t.Optional[t.Union[int, float]] = 0.5,
**kwargs,
) -> int:
"""Get the count of assets from a query.
Examples:
>>> import axonius_api_client as axonapi
>>> connect_args: dict = axonapi.get_env_connect()
>>> client: axonapi.Connect = axonapi.Connect(**connect_args)
>>> apiobj: axonapi.api.assets.AssetMixin = client.devices
>>> or client.users or client.vulnerabilities
Get count of all assets
>>> path: int = apiobj.count()
Get count of all assets for a given date
>>> path: int = apiobj.count(history_date="2020-09-29")
Get count of assets matching a query built by the GUI query wizard
>>> use_query: str = '(specific_data.data.name == "test")'
>>> path: int = apiobj.count(query=use_query)
Get count of assets matching a query built by the API client query wizard
>>> entries: str = 'simple name equals test'
>>> path: int = apiobj.count(wiz_entries=entries)
Same as above but using a list of dicts instead of a string for wiz_entries
>>> entries: t.List[dict] = [{'type': 'simple', 'path': 'name equals test'}]
>>> path: int = apiobj.count(wiz_entries=entries)
Args:
query: only return the count of assets that match the query
history_date: return asset count for a given historical date
history_days_ago: return asset count for a given historical date that is N days ago
history_exact: if True, return the exact asset count for a given historical date
if False, return the asset count for the closest historical date
wiz_entries: build a query from the entries and return the count of
assets that match the query
wiz_parsed: previously parsed wiz_entries
history_date_parsed: previously parsed history_date
use_cache_entry: if True, use the last query that was run to get the count
use_heavy_fields_collection: if True, use the HEAVV fields collection to get the count
frontend_sent_time: time that the query was sent from the frontend
query_id: ID to identify this query
saved_query_id: ID of saved query that count is being issued for
request_obj: request object to use instead of building one
http_args: args to pass to http request
sleep: time to sleep between requests
**kwargs: sent to :meth:`build_count_request`
"""
Remove v4.0 from all ApiEndpoints
v4.0 is now considered deprecated and will be removed in a future release.
All ApiEndpoints have been updated to remove v4.0 from the path.
What's Changed
* back-merge 4.60.4 by lifehackjim in https://github.com/Axonius/axonius_api_client/pull/238
* Sa 3421/feature/enforcement tasks by lifehackjim in https://github.com/Axonius/axonius_api_client/pull/240
* 5.0.0 by lifehackjim in https://github.com/Axonius/axonius_api_client/pull/241
**Full Changelog**: https://github.com/Axonius/axonius_api_client/compare/4.60.4...5.0.0