Releases: Axonius/axonius_api_client
4.50.0
4.50.0
- Bugfix: Errors when using Python 3.11
- Bugfix: axonshell adapters cnx add missing argument for connection label
Bugfix: Errors when using Python 3.11
- Most issues due to dataclasses no longer accepting mutable defaults,
set all dataclasses used as constants as frozen=True - revalidated against:
Versions:
* Python 3.7.8 64 bit
* Python 3.10.8 64 bit
* Python 3.11.0 64 bit
Operating Systems:
* macOS 12.6.1 (Monterey)
* Ubuntu Linux 18.04.05 64 bit (using "ubuntu-18.04.5-desktop-amd64.iso")
* Ubuntu Linux 22.04.01 64 bit (using "ubuntu-22.04.1-desktop-amd64.iso")
* Microsoft Windows 10 x64
* Microsoft Windows 11 x64
* Microsoft Windows Server 2016 x64
* Microsoft Windows Server 2019 x64
* Microsoft Windows Server 2022 x64
Bugfix: axonshell adapters cnx add missing argument for connection label
- Added option --connection-label
- Also added support for -c "connection_label=foo"
What's Changed
- 4.50.0 by @lifehackjim in #212
Full Changelog: 4.40.8...4.50.0
4.40.8
4.40.8
Bugfix: updating a connection setting of type file would throw file not found error
Error
raise ConfigInvalidValue(f"{sinfo}\nFile is not an existing file!")
axonius_api_client.exceptions.ConfigInvalidValue: Value "..." of type 'str' supplied for updating settings for connection Adapter Name: 'json', Instance name: 'Master', Instance ID: '55c35820b0284ac5ba28e7ab8f96683c', Connection ID: '55c35820b0284ac5ba28e7ab8f96683c', Connection UUID: '55c35820b0284ac5ba28e7ab8f96683c', Is active: True, Status: success setting 'file_path'
File is not an existing file!
Python Reproduction
cnx = client.adapters.cnx.get_by_adapter("json")[0]
updated = client.adapters.cnx.update_by_id(
cnx_id=cnx["id"], adapter_name="json", file_path="~/workdir/json_adapter.json"
)
Axonshell Reproduction
axonshell adapters cnx update-by-id -n json -i 635ab06b875e3b8ba0b1b9a6 -c file_path=~/workdir/json_adapter.json -npo
Changes
- changed axonius_api_client.tools.json_load to not load contents from file if load_file=False
- changed axonius_api_client.adapters.cnx.Cnx.cb_file_upload to pass load_file=False when calling json_load
What's Changed
- 4.40.8 by @lifehackjim in #211
Full Changelog: 4.40.7...4.40.8
4.40.7
4.40.7
Bugfix: axonshell system meta about does not return Customer ID
- "Customer ID" no longer returned in endpoint "api/settings/meta/about"
- Added new endpoint "api/settings/metadata"
- Modified axonius_api_client.api.system.meta.Meta.about to combine the returns of
endpoint "api/settings/meta/about" and endpoint "api/settings/metadata"
What's Changed
- Bugfix/about missing customer by @nate-axonius in #209
- 4.40.7 by @lifehackjim in #210
Full Changelog: 4.40.6...4.40.7
4.40.6
4.40.6
- Feature: Run Enforcement against manual selection of Asset IDs
- Feature: support semi-colon instead of comma as CSV delimiter for env vars
- Bugfix: Role permissions throw KeyError for some RBAC category actions
- Bugfix: Reduce log output
Feature: Run Enforcement against manual selection of Asset IDs
Axonshell changes
New commands added to groups axonshell devices
, axonshell users
,
and axonshell vulnerabilities
:
- run-enforcement-from-jsonl: Grab Asset IDs from a JSONL file and run
an Enforcement Set against them.
# Notes:
# 1) --path must be a JSONL file with one dictionary per line
# Example:
# 1) Get assets in JSONL format:
axonshell devices get --export-format json --json-flat --export-file data.jsonl --export-overwrite --wiz simple 'os.type equals windows'
# 2) Run an enforcement set against the asset IDs in the JSON file:
# 2a) prompting to verify the count:
axonshell devices run-enforcement-from-jsonl --path data.jsonl --eset test
# 2b) With no prompting (will error out if the count mismatches):
axonshell devices run-enforcement-from-jsonl --path data.jsonl --eset test --no-prompt
# 2c) With no verification because we know the asset IDs are valid for this instance:
axonshell devices run-enforcement-from-jsonl --path data.jsonl --eset test --verified
- run-enforcement-from-json: Grab Asset IDs from a JSON file and run an
Enforcement Set against them.
# Notes:
# 1) --path must be a JSON file containing a list of dictionaries
# Example:
# 1) Get assets in JSON format:
axonshell devices get --export-format json --export-file data.json --export-overwrite --wiz simple 'os.type equals windows'
# 2) Run an enforcement set against the asset IDs in the JSON file:
# 2a) prompting to verify the count:
axonshell devices run-enforcement-from-json --path data.json --eset test
# 2b) With no prompting (will error out if the count mismatches):
axonshell devices run-enforcement-from-json --path data.json --eset test --no-prompt
# 2c) With no verification because we know the asset IDs are valid for this instance:
axonshell devices run-enforcement-from-json --path data.json --eset test --verified
- run-enforcement-from-csv: Grab Asset IDs from a CSV file and run an
Enforcement Set against them.
# Notes:
# 1) --path must be a CSV file with headers
# 2) --path can also be a CSV file exported from the GUI.
# Example:
# 1) Get assets in CSV format:
axonshell devices get --export-format csv --export-file data.csv --export-overwrite --wiz simple 'os.type equals windows'
# 2) Run an enforcement set against the asset IDs in the CSV file:
# 2a) prompting to verify the count:
axonshell devices run-enforcement-from-csv --path data.csv --eset test
# 2b) With no prompting (will error out if the count mismatches):
axonshell devices run-enforcement-from-csv --path data.csv --eset test --no-prompt
# 2c) With no verification because we know the asset IDs are valid for this instance:
axonshell devices run-enforcement-from-csv --path data.csv --eset test --verified
- run-enforcement-from-text: Grab Asset IDs from any old text file and run an
Enforcement Set against them.
# Notes:
# 1) --path must be a text file with valid asset IDs
# 2) All lines will have any non alpha-numeric characters removed from them and
# if a 32 character alpha numeric string is found it is considered an Asset ID.
# Example:
# 1) Get assets in JSON format then use jq to extract the IDs to a text file:
axonshell devices get --export-format json --export-file data.json --export-overwrite --wiz simple 'os.type equals windows'
jq '.[].internal_axon_id' data.json > data.txt
# 2) Run an enforcement set against the asset IDs in the text file:
# 2a) prompting to verify the count:
axonshell devices run-enforcement-from-text --path data.txt --eset test
# 2b) With no prompting (will error out if the count mismatches):
axonshell devices run-enforcement-from-text --path data.txt --eset test --no-prompt
# 2c) With no verification because we know the asset IDs are valid for this instance:
axonshell devices run-enforcement-from-text --path data.txt --eset test --verified
API Client library changes
New Methods for client.devices/client.users/client.vulnerabilities:
- run_enforcement: Run an enforcement set against a manually selected list of assets.
'''Get a list of assets from a query and manually extract the IDs.
We know assets are valid because we just got them, so we pass verified=True.
'''
client = globals()['client'] # instance of axonius_api_client.Connect
apiobj = client.devices # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows" # "query of assets to target"
ESET = "test" # "name or uuid of enforcement set"
ITEMS = apiobj.get(wiz_entries=WIZ)
IDS = [x['internal_axon_id'] for x in ITEMS]
runner = apiobj.run_enforcement(eset=ESET, ids=IDS, verified=True)
print(runner)
'''
Runner(
state='Ran Enforcement Set against 31 supplied Asset IDs',
eset='test',
executed=True,
count_ids=31,
count_result=None,
verified=True,
verify_count=True,
prompt=False,
grabber=None,
)
'''
- run_enforcement_from_items: Get Asset IDs from a list of dicts or strs and run
an Enforcement Set against them.
'''Get a list of assets from a query and use the grabber get the IDs.
We know assets are valid because we just got them, so we pass verified=True.
'''
client = globals()['client'] # instance of axonius_api_client.Connect
apiobj = client.devices # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows" # "query of assets to target"
ESET = "test" # "name or uuid of enforcement set"
ITEMS = apiobj.get(wiz_entries=WIZ)
runner = apiobj.run_enforcement_from_items(eset=ESET, items=ITEMS, verified=True)
print(runner)
'''
Runner(
state='Ran Enforcement Set against 31 supplied Asset IDs',
eset='test',
executed=True,
count_ids=31,
count_result=None,
verified=True,
verify_count=True,
prompt=False,
grabber=Grabber(
count_supplied=31,
count_found=31,
do_echo=True,
do_raise=False,
source=None,
),
)
'''
- run_enforcement_from_json: Get Asset IDs from a JSON string with a list of
dicts and run an Enforcement Set against them.
'''Get a list of assets from a query and export the assets to a JSON str
then run an enforcement against all asset IDs from the JSON str.
We know assets are valid because we just got them, so we pass verified=True.
'''
import io
client = globals()['client'] # instance of axonius_api_client.Connect
apiobj = client.devices # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows" # "query of assets to target"
ESET = "test" # "name or uuid of enforcement set"
FH = io.StringIO()
z = apiobj.get(wiz_entries=WIZ, export="json", export_fd=FH, export_fd_close=False)
FH.seek(0)
ITEMS = FH.getvalue()
runner = apiobj.run_enforcement_from_json(eset=ESET, items=ITEMS, verified=True)
print(runner)
'''
Runner(
state='Ran Enforcement Set against 31 supplied Asset IDs',
eset='test',
executed=True,
count_ids=31,
count_result=None,
verified=True,
verify_count=True,
prompt=False,
grabber=Grabber(
count_supplied=31,
count_found=31,
do_echo=True,
do_raise=False,
source='from_json items type=str, length=15519 post_load type=list, length=31',
),
)
'''
'''Get a list of assets from a query and export the assets to a JSON file
then run an enforcement against all asset IDs from the JSON file.
We know assets are valid because we just got them, so we pass verified=True.
'''
import pathlib
client = globals()['client'] # instance of axonius_api_client.Connect
apiobj = client.devices # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows" # "query of assets to target"
ESET = "test" # "name or uuid of enforcement set"
PATH = pathlib.Path("data.json")
z = apiobj.get(wiz_entries=WIZ, export="json", export_file=PATH, export_overwrite=True)
runner = apiobj.run_enforcement_from_json(eset=ESET, items=PATH, verified=True)
print(runner)
'''
Runner(
state='Ran Enforcement Set against 31 supplied Asset IDs',
eset='test',
executed=True,
count_ids=31,
count_result=None,
verified=True,
verify_count=True,
prompt=False,
grabber=Grabber(
count_supplied=31,
count_found=31,
do_echo=True,
do_raise=False,
source='from_json items type=PosixPath, length=None post_load type=list, length=31',
),
)
'''
- run_enforcement_from_jsonl: Get Asset IDs from a JSONL string with one dict
per line and run an Enforcement Set against them.
'''Get a list of assets from a query and export the assets to a JSONL str
then run an enforcement against all asset IDs from the JSONL str.
We know assets are valid because we just got them, so we pass verified=True.
'''
import io
client = globals()['client'] # instance of axonius_api_client.Connect
apiobj = client.devices # client.devices, client.users, or client.vulnerabilities
WIZ = "simple os.type equals Windows" # "query of assets to target"
ESET = "test" # "name or uuid of enforcement set"
FH = io.StringIO()
z = apiobj.get(
wiz_entries=WIZ, export="json", json_flat=True, export_fd=FH, export_fd_close=False)
FH.seek(...
4.40.5
4.40.5
- Bugfix: python 3.6 does not have re.Pattern
- Bugfix: python 3.8 can not use typing.Union with isinstance
- Bugfix: Parsing of --header and --cookie was being mishandled
- Bugfix: more header/cookie names should be hidden in logs by default
Bugfix: python 3.6 does not have re.Pattern
- now using typing.Pattern
Bugfix: python 3.8 can not use typing.Union with isinstance
-
Would throw error
TypeError: Subscripted generics cannot be used with class and instance checks
-
now using isinstance(val, (...))
Bugfix: Parsing of --header and --cookie was being mishandled
- fixed
Bugfix: more header/cookie names should be hidden in logs by default
- list of keys used to be
[
"api-key",
"api-secret",
]
- reworked to support string for exact key matches or regex patterns
- strings beginning with ~ will be turned into regex pattern
- list of keys is now
[
"~cookie",
"~auth",
"~token",
"~^cf_",
"~secret",
"~key",
"~username",
"~password",
]
What's Changed
Full Changelog: 4.40.4...4.40.5
4.40.4
4.40.4
- Feature: Add support for supplying cookies
- Feature: Specify request options when getting assets
- Bugfix: OS Env AX_HEADERS not parsing properly
- Bugfix: silence urllib3 deprecation warning
- Schema Updates
Feature: Add support for supplying cookies
-
New OS environment variable AX_COOKIES
- Treated as a CSV by default
- example:
AX_COOKIES="key1=value1,key2=value2"
- example:
- Can be treated as JSON
- example:
AX_COOKIES='json:{"key1": "value1", "key2": "value2"}'
- example:
- Treated as a CSV by default
-
Added new argument to axonshell root command
--cookie
, examples:axonshell --cookie key1=value1 --cookies key2=value2 devices count
AX_COOKIES="key1=value1,key2=value2" axonshell devices count
export AX_COOKIES="key1=value1,key2=value2"; axonshell devices count
-cook, --cookie DICT_PARAM Additional cookies to supply with every
request (Example: 'key1=value1') (env var
parsed as CSV unless starts with 'json:')
(multiples) [env var: AX_COOKIES]
- Added more info to axonshell root command:
Using existing .env file: '/Users/jimbo/gh/Axonius/axonapi/.env'
AX_ENV=
Tips:
- All of the options listed above must be supplied BEFORE any commands or groups.
- CORRECT: axonshell --log-console devices count
- INCORRECT: axonshell devices count --log-console
- All values stored in a .env file will be treated as OS environment variables.
- Almost all options throughout axonshell have an associated OS environment variable.
- Use AX_ENV to point to a custom .env file:
- bash: export AX_ENV=/path/to/.env # for all commands in current shell
- bash: AX_ENV=/path/to/.env axonshell tools shell # for single commands
- cmd.exe: SET AX_ENV="c:\path\to\.env"
- powershell: $AX_ENV = "c:\path\to\.env"
- Use AX_COOKIES and AX_HEADERS as comma seperated values or json:
- AX_COOKIES="key1=value1,key2=value2,key3=value4"
- AX_HEADERS='json:{"key1": "value1", "key2": "value2"}'
- Use AX_URL, AX_KEY, AX_SECRET to specify credentials
- Internals: added new argument cookies:dict=None
axonius_api_client.http.Http.__init__
axonius_api_client.http.Http.__call__
axonius_api_client.connect.Connect.__init__
Feature: Specify request options when getting assets
- Want to be able to set response timeout on specific calls
to get assets, example:
http_args = {"connect_timeout": 5, "response_timeout": 9999}
client.devices.get(http_args=http_args) # noqa
- Internals: added new argument http_args:dict=None
client.devices.get
client.users.get
client.vulnerabilities.get
Bugfix: OS Env AX_HEADERS not parsing properly
- Now works like the newly added AX_COOKIES
Bugfix: silence urllib3 deprecation warning
- Now only import pyopenssl on python<3.10.1
Schema Updates
SavedQuery
- new properties: access
- map access property to wonky private property replacement
- disable schema validation for "used_in" due to validation errors
Enforcements
- new properties: settings, description
What's Changed
- New example that adds adapter connections from a CSV. by @nate-axonius in #201
- 4.40.4 by @lifehackjim in #202
- 4.40.4 by @lifehackjim in #203
Full Changelog: 4.40.3...4.40.4
4.40.3
4.40.3
Feature: Run Enforcement Set against trigger
New endpoints:
- run_set_against_trigger: PUT: api/V4.5/enforcements/{uuid}/trigger
- run_sets_against_trigger: POST: api/V4.5/enforcements/trigger
New Methods:
- client.enforcements.run
- client.enforcements._run_sets_against_trigger
- client.enforcements._run_set_against_trigger
New Commands:
- axonshell enforcements run
What's Changed
Full Changelog: 4.40.2...4.40.3
4.40.2
4.40.2
Feature: Get Query History
New Methods:
- client.devices.saved_query.get_query_history
- client.devices.saved_query.get_query_history_generator
- client.devices.saved_query.get_query_history_run_by
- client.devices.saved_query.get_query_history_run_from
New Commands:
- axonshell devices saved-query get-query-history
- axonshell users saved-query get-query-history
- axonshell vulnerabilities saved-query get-query-history
Bugfix: Adapter specific Advanced settings using wrong schema
This command would produce the wrong output:
axonshell adapters config-get -ct specific -n tenable_io
This command would fail due to mismatched schema:
axonshell adapters config-update -ct specific -n tenable_io -c exclude_no_last_scan=y
Both of these issues are addressed in this version.
What's Changed
- 4.40.2 by @lifehackjim in #198
Full Changelog: 4.40.1...4.40.2
4.40.1
- 4.40.1
- Feature: Get Adapter Fetch History
- Feature: Add support for new Get Saved Query arguments
- Feature: Include saved query ID and expressions when counting or getting assets by saved query
- Feature: Update schemas with new fields
- Feature: Fix for Python 3.6
- Bugfix: History date arguments not showing in get-by-saved-query
- Bugfix: explode_entities argument improperly named
- Bugfix: use-password-reset-token command had incorrect description
4.40.1
Feature: Get Adapter Fetch History
New Methods:
- client.adapters.get_fetch_history
- client.adapters.get_fetch_history_generator
- client.adapters.get_fetch_history_filters
New Commands:
- axonshell adapters get-fetch-history-filters
- axonshell adapters get-fetch-history
Feature: Add support for new Get Saved Query arguments
New arguments for method client.devices.saved_query.get:
- include_usage (bool, default: False): include details of what other saved queries are using each sq
- get_view_data (bool, default: True): include the view object of each sq
- creators (optional, list of str, default: None, NOT YET SUPPORTED): only get sqs created by supplied users
- folder (optional, str, default: None, NOT YET SUPPORTED): name of folder to get saved queries from
- used_in (optional, list of str, default: None, NOT YET SUPPORTED): only get sq's that are used in supplied sqs
- paging options: page_sleep, page_size, row_start, row_stop
Feature: Include saved query ID and expressions when counting or getting assets by saved query
Performing a get_by_saved_query or count_by_saved_query will now accurately reflect the sq in the audit logs
Feature: Update schemas with new fields
Updated schemas:
- json_api.assets.AssetRequest
- json_api.adapters.Adapter
- json_api.adapters.Cnxs
- json_api.enforcements.SetBasic
- json_api.enforcements.UpdateResponse
- json_api.enforcements.ActionType
- json_api.instances.Instance
- json_api.saved_queries.SavedQuery
- json_api.system_users.SystemUser
Feature: Fix for Python 3.6
Changed parsing of datetime stamp for all_logs_list.py from datetime.datetime.fromisoformat
(3.7+ only) to dateutil.parser.parse
Bugfix: History date arguments not showing in get-by-saved-query
axonshell devices/users/vulnerabilities get-by-saved-query now showing history arguments properly:
-hd, --history-date YYYY-MM-DD
-hda, --history-days-ago TEXT
-hex, --history-exact / -nhex, --no-history-exact
Bugfix: explode_entities argument improperly named
--explode-entities
accepted properly now, mistaken form of --explode_entities
will be left for backwards compatibility
Bugfix: use-password-reset-token command had incorrect description
axonshell tools use-password-reset-token now shows the correct description.
What's Changed
- 4.40.1 by @lifehackjim in #195
Full Changelog: 4.40.0...4.40.1
4.40.0
4.40.0
Feature: Support for SAAS instances and tunnels in Adapter Connections
New argument:
- name: tunnel
- type: string
- default: None
- description: name or ID of SAAS tunnel
'tunnel' argument added to methods
- client.adapters.cnx.get_by_adapter
- client.adapters.cnx.get_by_uuid
- client.adapters.cnx.get_by_label
- client.adapters.cnx.get_by_id
- client.adapters.cnx.update_by_id
- client.adapters.cnx.delete_by_id
- client.adapters.cnx.test_by_id
'--tunnel' argument added to commands:
- axonshell adapters cnx add
- axonshell adapters cnx add-from-json
- axonshell adapters cnx add-multiple-from-json
- axonshell adapters cnx delete-by-id
- axonshell adapters cnx get
- axonshell adapters cnx get-by-id
- axonshell adapters cnx set-active
- axonshell adapters cnx set-label
- axonshell adapters cnx test
- axonshell adapters cnx test-by-id
- axonshell adapters cnx update-by-id
Feature: Support for getting SAAS tunnels
New methods:
- client.instances.get_tunnels
- client.instances.get_tunnel
- client.instances.get_tunnel_default
Feature: Support for vulnerabilities asset type
This model should be considered BETA support for now. The query wizard does not yet support building the types
of queries needed for the vulnerabilities asset type.
New model:
- client.vulnerabilities
New command:
- axonshell vulnerabilities
Feature: Support for Split by asset entities
In order to mirror the functionality provided when doing a CSV export from the GUI and enabling "Split by asset entities".
New argument:
- name: explode_entities
- type: boolean
- default: False
- description: Enable --include-details and split each row into the data source from each adapter connection
'explode_entities' argument added to methods:
- client.devices.get*
- client.users.get*
- client.vulnerabilities.get*
'--explode_entities/--no-explode_entities' and '-exe/-nexe' arguments added to commands:
- axonshell devices get*
- axonshell users get*
- axonshell vulnerabilities get*
Bugfix: History date ignored when getting assets
Methods fixed:
- client.devices.get*
- client.users.get*
- client.vulnerabilities.get*
Commands fixed:
- axonshell devices get*
- axonshell users get*
- axonshell vulnerabilities get*
Bugfix: System user schema
Certain system user attributes are allowed to be None now:
- first_name
- last_name
- pic_name