2. PyTan Package

A python package that makes using the Tanium Server SOAP API easy.

pytan.__version__ = '2.1.6'

Version of PyTan

Copyright for PyTan

pytan.__license__ = 'MIT'

License for PyTan

pytan.__author__ = 'Jim Olsen <jim.olsen@tanium.com>'

Author of Pytan

2.1. pytan.handler

The main pytan module that provides first level entities for programmatic use.

class pytan.handler.Handler(username=None, password=None, host=None, port=443, loglevel=0, debugformat=False, gmt_log=True, session_id=None, **kwargs)[source]

Bases: object

Creates a connection to a Tanium SOAP Server on host:port

Parameters:

username : str

  • default: None
  • username to connect to host with

password : str

  • default: None
  • password to connect to host with

host : str

  • default: None
  • hostname or ip of Tanium SOAP Server

port : int, optional

  • default: 443
  • port of Tanium SOAP Server on host

loglevel : int, optional

  • default: 0
  • 0 do not print anything except warnings/errors
  • 1 and higher will print more

debugformat : bool, optional

  • default: False
  • False: use one line logformat
  • True: use two lines

gmt_log : bool, optional

  • default: True
  • True: use GMT timezone for log output
  • False: use local time for log output

session_id : str, optional

  • default: None
  • session_id to use while authenticating instead of username/password

pytan_user_config : str, optional

  • default: pytan.constants.PYTAN_USER_CONFIG
  • JSON file containing key/value pairs to override class variables
Other Parameters:
 

http_debug : bool, optional

  • default: False
  • False: do not print requests package debug
  • True: do print requests package debug
  • This is passed through to pytan.sessions.Session

http_auth_retry: bool, optional

  • default: True
  • True: retry HTTP GET/POST’s
  • False: do not retry HTTP GET/POST’s
  • This is passed through to pytan.sessions.Session

http_retry_count: int, optional

  • default: 5
  • number of times to retry HTTP GET/POST’s if the connection times out/fails
  • This is passed through to pytan.sessions.Session

soap_request_headers : dict, optional

  • default: {‘Content-Type’: ‘text/xml; charset=utf-8’, ‘Accept-Encoding’: ‘gzip’}
  • dictionary of headers to add to every HTTP GET/POST
  • This is passed through to pytan.sessions.Session

auth_connect_timeout_sec : int, optional

  • default: 5
  • number of seconds before timing out for a connection while authenticating
  • This is passed through to pytan.sessions.Session

auth_response_timeout_sec : int, optional

  • default: 15
  • number of seconds before timing out for a response while authenticating
  • This is passed through to pytan.sessions.Session

info_connect_timeout_sec : int, optional

  • default: 5
  • number of seconds before timing out for a connection while getting /info.json
  • This is passed through to pytan.sessions.Session

info_response_timeout_sec : int, optional

  • default: 15
  • number of seconds before timing out for a response while getting /info.json
  • This is passed through to pytan.sessions.Session

soap_connect_timeout_sec : int, optional

  • default: 15
  • number of seconds before timing out for a connection for a SOAP request
  • This is passed through to pytan.sessions.Session

soap_response_timeout_sec : int, optional

  • default: 540
  • number of seconds before timing out for a response for a SOAP request
  • This is passed through to pytan.sessions.Session

stats_loop_enabled : bool, optional

  • default: False
  • False: do not enable the statistics loop thread
  • True: enable the statistics loop thread
  • This is passed through to pytan.sessions.Session

stats_loop_sleep_sec : int, optional

  • default: 5
  • number of seconds to sleep in between printing the statistics when stats_loop_enabled is True
  • This is passed through to pytan.sessions.Session

record_all_requests: bool, optional

  • default: False
  • False: do not add each requests response object to session.ALL_REQUESTS_RESPONSES
  • True: add each requests response object to session.ALL_REQUESTS_RESPONSES
  • This is passed through to pytan.sessions.Session

stats_loop_targets : list of dict, optional

  • default: [{‘Version’: ‘Settings/Version’}, {‘Active Questions’: ‘Active Question Cache/Active Question Estimate’}, {‘Clients’: ‘Active Question Cache/Active Client Estimate’}, {‘Strings’: ‘String Cache/Total String Count’}, {‘Handles’: ‘System Performance Info/HandleCount’}, {‘Processes’: ‘System Performance Info/ProcessCount’}, {‘Memory Available’: ‘percentage(System Performance Info/PhysicalAvailable,System Performance Info/PhysicalTotal)’}]
  • list of dictionaries with the key being the section of info.json to print info from, and the value being the item with in that section to print the value
  • This is passed through to pytan.sessions.Session

persistent: bool, optional

force_server_version: str, optional

  • default: ‘’
  • use this to override the server_version detection

See also

pytan.constants.LOG_LEVEL_MAPS
maps a given loglevel to respective logger names and their logger levels
pytan.constants.INFO_FORMAT
debugformat=False
pytan.constants.DEBUG_FORMAT
debugformat=True
taniumpy.session.Session
Session object used by Handler

Notes

  • for 6.2: port 444 is the default SOAP port, port 443 forwards /soap/ URLs to the SOAP port, Use port 444 if you have direct access to it. However, port 444 is the only port that exposes the /info page in 6.2
  • for 6.5: port 443 is the default SOAP port, there is no port 444

Examples

Setup a Handler() object:

>>> import sys
>>> sys.path.append('/path/to/pytan/')
>>> import pytan
>>> handler = pytan.Handler('username', 'password', 'host')
_add(obj, **kwargs)[source]

Wrapper for interfacing with taniumpy.session.Session.add()

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to add
Returns:

added_obj : taniumpy.object_types.base.BaseType

  • full object that was added
_ask_manual(get_results=True, **kwargs)[source]

Ask a manual question using definitions and get the results back

This method requires in-depth knowledge of how filters and options are created in the API, and as such is not meant for human consumption. Use ask_manual() instead.

Parameters:

sensor_defs : str, dict, list of str or dict

  • default: []
  • sensor definitions

question_filter_defs : dict, list of dict, optional

  • default: []
  • question filter definitions

question_option_defs : dict, list of dict, optional

  • default: []
  • question option definitions

get_results : bool, optional

  • default: True
  • True: wait for result completion after asking question
  • False: just ask the question and return it in ret

sse : bool, optional

  • default: False
  • True: perform a server side export when getting result data
  • False: perform a normal get result data (default for 6.2)
  • Keeping False by default for now until the columnset’s are properly identified in the server export

sse_format : str, optional

  • default: ‘xml_obj’
  • format to have server side export report in, one of: {‘csv’, ‘xml’, ‘xml_obj’, ‘cef’, 0, 1, 2}

leading : str, optional

  • default: ‘’
  • used for sse_format ‘cef’ only, the string to prepend to each row

trailing : str, optional

  • default: ‘’
  • used for sse_format ‘cef’ only, the string to append to each row

polling_secs : int, optional

complete_pct : int/float, optional

  • default: 99
  • Percentage of mr_tested out of estimated_total to consider the question “done”
  • This is passed through to pytan.pollers.QuestionPoller

override_timeout_secs : int, optional

  • default: 0
  • If supplied and not 0, timeout in seconds instead of when object expires
  • This is passed through to pytan.pollers.QuestionPoller

callbacks : dict, optional

  • default: {}
  • can be a dict of functions to be run with the key names being the various state changes: ‘ProgressChanged’, ‘AnswersChanged’, ‘AnswersComplete’
  • This is passed through to pytan.pollers.QuestionPoller.run()

override_estimated_total : int, optional

  • instead of getting number of systems that should see this question from result_info.estimated_total, use this number
  • This is passed through to pytan.pollers.QuestionPoller()

force_passed_done_count : int, optional

  • when this number of systems have passed the right hand side of the question, consider the question complete
  • This is passed through to pytan.pollers.QuestionPoller()
Returns:

ret : dict, containing:

See also

pytan.constants.FILTER_MAPS
valid filter dictionaries for filters
pytan.constants.OPTION_MAPS
valid option dictionaries for options

Examples

>>> # example of str for sensor_defs
>>> sensor_defs = 'Sensor1'
>>> # example of dict for sensor_defs
>>> sensor_defs = {
... 'name': 'Sensor1',
...     'filter': {
...         'operator': 'RegexMatch',
...         'not_flag': 0,
...         'value': '.*'
...     },
...     'params': {'key': 'value'},
...     'options': {'and_flag': 1}
... }
>>> # example of dict for question_filter_defs
>>> question_filter_defs = {
...     'operator': 'RegexMatch',
...     'not_flag': 0,
...     'value': '.*'
... }
_check_sse_crash_prevention(obj, **kwargs)[source]

Runs a number of methods used to prevent crashing the platform server when performing server side exports

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to pass to self._check_sse_empty_rs
_check_sse_empty_rs(obj, ok_version, **kwargs)[source]

Checks if the server version is less than any versions in pytan.constants.SSE_CRASH_MAP, if so verifies that the result set is not empty

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to get result info for to ensure non-empty answers

ok_version : bool

  • if the version currently running is an “ok” version
_check_sse_format_support(sse_format, sse_format_int, **kwargs)[source]

Determines if the export format integer is supported in the server version

Parameters:

sse_format : str or int

  • user supplied export format

sse_format_int : int

  • sse_format parsed into an int
_check_sse_timing(ok_version, **kwargs)[source]

Checks that the last server side export was at least 1 second ago if server version is less than any versions in pytan.constants.SSE_CRASH_MAP

Parameters:

ok_version : bool

  • if the version currently running is an “ok” version
_check_sse_version(**kwargs)[source]

Validates that the server version supports server side export

_debug_locals(fname, flocals)[source]

Method to print out locals for a function if self.debug_method_locals is True

_deploy_action(run=False, get_results=True, **kwargs)[source]

Deploy an action and get the results back

This method requires in-depth knowledge of how filters and options are created in the API, and as such is not meant for human consumption. Use deploy_action() instead.

Parameters:

package_def : dict

  • definition that describes a package

action_filter_defs : str, dict, list of str or dict, optional

  • default: []
  • action filter definitions

action_option_defs : dict, list of dict, optional

  • default: []
  • action filter option definitions

start_seconds_from_now : int, optional

  • default: 0
  • start action N seconds from now

distribute_seconds : int, optional

  • default: 0
  • distribute action evenly over clients over N seconds

issue_seconds : int, optional

  • default: 0
  • have the server re-ask the action status question if performing a GetResultData over N seconds ago

expire_seconds : int, optional

  • default: package.expire_seconds
  • expire action N seconds from now, will be derived from package if not supplied

run : bool, optional

  • default: False
  • False: just ask the question that pertains to verify action, export the results to CSV, and raise pytan.exceptions.RunFalse – does not deploy the action
  • True: actually deploy the action

get_results : bool, optional

  • default: True
  • True: wait for result completion after deploying action
  • False: just deploy the action and return the object in ret

action_name : str, optional

  • default: prepend package name with “API Deploy “
  • custom name for action

action_comment : str, optional

  • default:
  • custom comment for action

polling_secs : int, optional

complete_pct : int/float, optional

  • default: 100
  • Percentage of passed_count out of successfully run actions to consider the action “done”
  • This is passed through to pytan.pollers.ActionPoller

override_timeout_secs : int, optional

  • default: 0
  • If supplied and not 0, timeout in seconds instead of when object expires
  • This is passed through to pytan.pollers.ActionPoller

override_passed_count : int, optional

  • instead of getting number of systems that should run this action by asking a question, use this number
  • This is passed through to pytan.pollers.ActionPoller
Returns:

ret : dict, containing:

See also

pytan.constants.FILTER_MAPS
valid filter dictionaries for filters
pytan.constants.OPTION_MAPS
valid option dictionaries for options

Notes

  • For 6.2:
    • We need to add an Action object
    • The Action object should not be in an ActionList
    • Action.start_time must be specified, if it is not specified the action shows up as expired immediately. We default to 1 second from current time if start_seconds_from_now is not passed in
  • For 6.5 / 6.6:
    • We need to add a SavedAction object, the server creates the Action object for us
    • To emulate what the console does, the SavedAction should be in a SavedActionList
    • Action.start_time does not need to be specified

Examples

>>> # example of dict for `package_def`
>>> package_def = {'name': 'PackageName1', 'params':{'param1': 'value1'}}
>>> # example of str for `action_filter_defs`
>>> action_filter_defs = 'Sensor1'
>>> # example of dict for `action_filter_defs`
>>> action_filter_defs = {
... 'name': 'Sensor1',
...     'filter': {
...         'operator': 'RegexMatch',
...         'not_flag': 0,
...         'value': '.*'
...     },
...     'options': {'and_flag': 1}
... }
_export_class_BaseType(obj, export_format, **kwargs)[source]

Handles exporting taniumpy.object_types.base.BaseType

Parameters:

obj : taniumpy.object_types.base.BaseType

  • taniumpy object to export

export_format : str

  • str of format to perform export in
Returns:

result : str

  • results of exporting obj into format export_format
_export_class_ResultSet(obj, export_format, **kwargs)[source]

Handles exporting taniumpy.object_types.result_set.ResultSet

Parameters:

obj : taniumpy.object_types.result_set.ResultSet

  • taniumpy object to export

export_format : str

  • str of format to perform export in
Returns:

result : str

  • results of exporting obj into format export_format
_export_format_csv(obj, **kwargs)[source]

Handles exporting format: CSV

Parameters:

obj : taniumpy.object_types.result_set.ResultSet or taniumpy.object_types.base.BaseType

  • taniumpy object to export
Returns:

result : str

  • results of exporting obj into csv format
_export_format_json(obj, **kwargs)[source]

Handles exporting format: JSON

Parameters:

obj : taniumpy.object_types.result_set.ResultSet or taniumpy.object_types.base.BaseType

  • taniumpy object to export
Returns:

result : str

  • results of exporting obj into json format
_export_format_xml(obj, **kwargs)[source]

Handles exporting format: XML

Parameters:

obj : taniumpy.object_types.result_set.ResultSet or taniumpy.object_types.base.BaseType

  • taniumpy object to export
Returns:

result : str

  • results of exporting obj into XML format
_find(obj, **kwargs)[source]

Wrapper for interfacing with taniumpy.session.Session.find()

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to find
Returns:

found : taniumpy.object_types.base.BaseType

  • full object that was found
_get_multi(obj_map, **kwargs)[source]

Find multiple item wrapper using _find()

Parameters:

obj_map : dict

  • dict containing the map for a given object type
Returns:

found : taniumpy.object_types.base.BaseType

  • full object that was found
_get_package_def(d, **kwargs)[source]

Uses get() to update a definition with a package object

Parameters:

d : dict

  • dict containing package definition
Returns:

d : dict

  • dict containing package definitions with package object in ‘package_obj’
_get_sensor_defs(defs, **kwargs)[source]

Uses get() to update a definition with a sensor object

Parameters:

defs : list of dict

  • list of dicts containing sensor definitions
Returns:

defs : list of dict

  • list of dicts containing sensor definitions with sensor object in ‘sensor_obj’
_get_single(obj_map, **kwargs)[source]

Find single item wrapper using _find()

Parameters:

obj_map : dict

  • dict containing the map for a given object type
Returns:

found : taniumpy.object_types.base.BaseType

  • full object that was found
_resolve_sse_format(sse_format, **kwargs)[source]

Resolves the server side export format the user supplied to an integer for the API

Parameters:

sse_format : str or int

  • user supplied export format
Returns:

sse_format_int : int

  • sse_format parsed into an int
_single_find(obj_map, k, v, **kwargs)[source]

Wrapper for single item searches interfacing with taniumpy.session.Session.find()

Parameters:

obj_map : dict

  • dict containing the map for a given object type

k : str

  • attribute name to set to v

v : str

  • attribute value to set on k
Returns:

found : taniumpy.object_types.base.BaseType

  • full object that was found
_version_support_check(v_maps, **kwargs)[source]

Checks that each of the version maps in v_maps is greater than or equal to the current servers version

Parameters:

v_maps : list of str

  • each str should be a platform version
  • each str will be checked against self.session.server_version
  • if self.session.server_version is not greater than or equal to any str in v_maps, return will be False
  • if self.session.server_version is greater than all strs in v_maps, return will be True
  • if self.server_version is invalid/can’t be determined, return will be False
Returns:

bool

  • True if all values in all v_maps are greater than or equal to self.session.server_version
  • False otherwise
approve_saved_action(id, **kwargs)[source]

Approve a saved action

Parameters:

id : int

  • id of saved action to approve
Returns:

saved_action_approve_obj : taniumpy.object_types.saved_action_approval.SavedActionApproval

  • The object containing the return from SavedActionApproval
ask(**kwargs)[source]

Ask a type of question and get the results back

Parameters:

qtype : str, optional

  • default: ‘manual’
  • type of question to ask: {‘saved’, ‘manual’, ‘_manual’}
Returns:

result : dict, containing:

See also

pytan.constants.Q_OBJ_MAP
maps qtype to a method in Handler()
pytan.handler.Handler.ask_saved()
method used when qtype == ‘saved’
pytan.handler.Handler.ask_manual()
method used when qtype == ‘manual’
pytan.handler.Handler._ask_manual()
method used when qtype == ‘_manual’
ask_manual(**kwargs)[source]

Ask a manual question using human strings and get the results back

This method takes a string or list of strings and parses them into their corresponding definitions needed by _ask_manual()

Parameters:

sensors : str, list of str

  • default: []
  • sensors (columns) to include in question

question_filters : str, list of str, optional

  • default: []
  • filters that apply to the whole question

question_options : str, list of str, optional

  • default: []
  • options that apply to the whole question

get_results : bool, optional

  • default: True
  • True: wait for result completion after asking question
  • False: just ask the question and return it in result

sensors_help : bool, optional

  • default: False
  • False: do not print the help string for sensors
  • True: print the help string for sensors and exit

filters_help : bool, optional

  • default: False
  • False: do not print the help string for filters
  • True: print the help string for filters and exit

options_help : bool, optional

  • default: False
  • False: do not print the help string for options
  • True: print the help string for options and exit

polling_secs : int, optional

complete_pct : int/float, optional

  • default: 99
  • Percentage of mr_tested out of estimated_total to consider the question “done”
  • This is passed through to pytan.pollers.QuestionPoller

override_timeout_secs : int, optional

  • default: 0
  • If supplied and not 0, timeout in seconds instead of when object expires
  • This is passed through to pytan.pollers.QuestionPoller

callbacks : dict, optional

  • default: {}
  • can be a dict of functions to be run with the key names being the various state changes: ‘ProgressChanged’, ‘AnswersChanged’, ‘AnswersComplete’
  • This is passed through to pytan.pollers.QuestionPoller.run()

override_estimated_total : int, optional

  • instead of getting number of systems that should see this question from result_info.estimated_total, use this number
  • This is passed through to pytan.pollers.QuestionPoller()

force_passed_done_count : int, optional

  • when this number of systems have passed the right hand side of the question, consider the question complete
  • This is passed through to pytan.pollers.QuestionPoller()
Returns:

result : dict, containing:

See also

pytan.constants.FILTER_MAPS
valid filter dictionaries for filters
pytan.constants.OPTION_MAPS
valid option dictionaries for options
pytan.handler.Handler._ask_manual()
private method with the actual workflow used to create and add the question object

Notes

When asking a question from the Tanium console, you construct a question like:

Get Computer Name and IP Route Details from all machines with Is Windows containing “True”

Asking the same question in PyTan has some similarities:

>>> r = handler.ask_manual(sensors=['Computer Name', 'IP Route Details'], question_filters=['Is Windows, that contains:True'])

There are two sensors in this question, after the “Get” and before the “from all machines”: “Computer Name” and “IP Route Details”. The sensors after the “Get” and before the “from all machines” can be referred to as any number of things:

  • sensors
  • left hand side
  • column selects

The sensors that are defined after the “Get” and before the “from all machines” are best described as a column selection, and control what columns you want to show up in your results. These sensor names are the same ones that would need to be passed into ask_question() for the sensors arguments.

You can filter your column selections by using a filter in the console like so:

Get Computer Name starting with “finance” and IP Route Details from all machines with Is Windows containing “True”

And in PyTan:

>>> r = handler.ask_manual(sensors=['Computer Name, that starts with:finance', 'IP Route Details'], question_filters=['Is Windows, that contains:True'])

This will cause the results to have the same number of columns, but for any machine that returns results that do not match the filter specified for a given sensor, the row for that column will contain “[no results]”.

There is also a sensor specified after the “from all machines with”: “Is Windows”. This sensor can be referred to as any number of things:

  • question filters
  • sensors (also)
  • right hand side
  • row selects

Any system that does not match the conditions in the question filters will return no results at all. These question filters are really just sensors all over again, but instead of controlling what columns are output in the results, they control what rows are output in the results.

Examples

>>> # example of str for `sensors`
>>> sensors = 'Sensor1'
>>> # example of str for `sensors` with params
>>> sensors = 'Sensor1{key:value}'
>>> # example of str for `sensors` with params and filter
>>> sensors = 'Sensor1{key:value}, that contains:example text'
>>> # example of str for `sensors` with params and filter and options
>>> sensors = (
...     'Sensor1{key:value}, that contains:example text,'
...     'opt:ignore_case, opt:max_data_age:60'
... )
>>> # example of str for question_filters
>>> question_filters = 'Sensor2, that contains:example test'
>>> # example of list of str for question_options
>>> question_options = ['max_data_age:3600', 'and']
ask_parsed(question_text, picker=None, get_results=True, **kwargs)[source]

Ask a parsed question as question_text and use the index of the parsed results from picker

Parameters:

question_text : str

  • The question text you want the server to parse into a list of parsed results

picker : int

  • default: None
  • The index number of the parsed results that correlates to the actual question you wish to run

get_results : bool, optional

  • default: True
  • True: wait for result completion after asking question
  • False: just ask the question and return it in ret

sse : bool, optional

  • default: False
  • True: perform a server side export when getting result data
  • False: perform a normal get result data (default for 6.2)
  • Keeping False by default for now until the columnset’s are properly identified in the server export

sse_format : str, optional

  • default: ‘xml_obj’
  • format to have server side export report in, one of: {‘csv’, ‘xml’, ‘xml_obj’, ‘cef’, 0, 1, 2}

leading : str, optional

  • default: ‘’
  • used for sse_format ‘cef’ only, the string to prepend to each row

trailing : str, optional

  • default: ‘’
  • used for sse_format ‘cef’ only, the string to append to each row

polling_secs : int, optional

complete_pct : int/float, optional

  • default: 99
  • Percentage of mr_tested out of estimated_total to consider the question “done”
  • This is passed through to pytan.pollers.QuestionPoller

override_timeout_secs : int, optional

  • default: 0
  • If supplied and not 0, timeout in seconds instead of when object expires
  • This is passed through to pytan.pollers.QuestionPoller

callbacks : dict, optional

  • default: {}
  • can be a dict of functions to be run with the key names being the various state changes: ‘ProgressChanged’, ‘AnswersChanged’, ‘AnswersComplete’
  • This is passed through to pytan.pollers.QuestionPoller.run()

override_estimated_total : int, optional

  • instead of getting number of systems that should see this question from result_info.estimated_total, use this number
  • This is passed through to pytan.pollers.QuestionPoller()

force_passed_done_count : int, optional

  • when this number of systems have passed the right hand side of the question, consider the question complete
  • This is passed through to pytan.pollers.QuestionPoller()
Returns:

ret : dict, containing:

Examples

Ask the server to parse ‘computer name’, but don’t pick a choice (will print out a list of choices at critical logging level and then throw an exception):
>>> v = handler.ask_parsed('computer name')
Ask the server to parse ‘computer name’ and pick index 1 as the question you want to run:
>>> v = handler.ask_parsed('computer name', picker=1)
ask_saved(refresh_data=False, **kwargs)[source]

Ask a saved question and get the results back

Parameters:

id : int, list of int, optional

  • id of saved question to ask

name : str, list of str

  • name of saved question

refresh_data: bool, optional

  • default False
  • False: do not perform a getResultInfo before issuing a getResultData
  • True: perform a getResultInfo before issuing a getResultData

sse : bool, optional

  • default: False
  • True: perform a server side export when getting result data
  • False: perform a normal get result data (default for 6.2)
  • Keeping False by default for now until the columnset’s are properly identified in the server export

sse_format : str, optional

  • default: ‘xml_obj’
  • format to have server side export report in, one of: {‘csv’, ‘xml’, ‘xml_obj’, ‘cef’, 0, 1, 2}

leading : str, optional

  • default: ‘’
  • used for sse_format ‘cef’ only, the string to prepend to each row

trailing : str, optional

  • default: ‘’
  • used for sse_format ‘cef’ only, the string to append to each row

polling_secs : int, optional

complete_pct : int/float, optional

  • default: 99
  • Percentage of mr_tested out of estimated_total to consider the question “done”
  • This is passed through to pytan.pollers.QuestionPoller

override_timeout_secs : int, optional

  • default: 0
  • If supplied and not 0, timeout in seconds instead of when object expires
  • This is passed through to pytan.pollers.QuestionPoller

callbacks : dict, optional

  • default: {}
  • can be a dict of functions to be run with the key names being the various state changes: ‘ProgressChanged’, ‘AnswersChanged’, ‘AnswersComplete’
  • This is passed through to pytan.pollers.QuestionPoller.run()

override_estimated_total : int, optional

  • instead of getting number of systems that should see this question from result_info.estimated_total, use this number
  • This is passed through to pytan.pollers.QuestionPoller()

force_passed_done_count : int, optional

  • when this number of systems have passed the right hand side of the question, consider the question complete
  • This is passed through to pytan.pollers.QuestionPoller()
Returns:

ret : dict, containing

Notes

id or name must be supplied

create_dashboard(name, text='', group='', public_flag=True, **kwargs)[source]

Calls pytan.handler.Handler.run_plugin() to run the CreateDashboard plugin and parse the response

Parameters:

name : str

  • name of dashboard to create

text : str, optional

  • default: ‘’
  • text for this dashboard

group : str, optional

  • default: ‘’
  • group name for this dashboard

public_flag : bool, optional

  • default: True
  • True: make this dashboard public
  • False: do not make this dashboard public
Returns:

plugin_result, sql_zipped : tuple

  • plugin_result will be the taniumpy object representation of the SOAP response from Tanium server
  • sql_zipped will be a dict with the SQL results embedded in the SOAP response
create_from_json(objtype, json_file, **kwargs)[source]

Creates a new object using the SOAP api from a json file

Parameters:

objtype : str

  • Type of object described in json_file

json_file : str

  • path to JSON file that describes an API object
Returns:

ret : taniumpy.object_types.base.BaseType

  • TaniumPy object added to Tanium SOAP Server

See also

pytan.constants.GET_OBJ_MAP
maps objtype to supported ‘create_json’ types
create_group(groupname, filters=[], filter_options=[], **kwargs)[source]

Create a group object

Parameters:

groupname : str

  • name of group to create

filters : str or list of str, optional

  • default: []
  • each string must describe a filter

filter_options : str or list of str, optional

  • default: []
  • each string must describe an option for filters

filters_help : bool, optional

  • default: False
  • False: do not print the help string for filters
  • True: print the help string for filters and exit

options_help : bool, optional

  • default: False
  • False: do not print the help string for options
  • True: print the help string for options and exit
Returns:

group_obj : taniumpy.object_types.group.Group

  • TaniumPy object added to Tanium SOAP Server

See also

pytan.constants.FILTER_MAPS
valid filters for filters
pytan.constants.OPTION_MAPS
valid options for filter_options
create_package(name, command, display_name='', file_urls=[], command_timeout_seconds=600, expire_seconds=600, parameters_json_file='', verify_filters=[], verify_filter_options=[], verify_expire_seconds=600, **kwargs)[source]

Create a package object

Parameters:

name : str

  • name of package to create

command : str

  • command to execute

display_name : str, optional

  • display name of package

file_urls : list of strings, optional

  • default: []
  • URL of file to add to package
  • can optionally define download_seconds by using SECONDS::URL
  • can optionally define file name by using FILENAME||URL
  • can combine optionals by using SECONDS::FILENAME||URL
  • FILENAME will be extracted from basename of URL if not provided

command_timeout_seconds : int, optional

  • default: 600
  • timeout for command execution in seconds

parameters_json_file : str, optional

  • default: ‘’
  • path to json file describing parameters for package

expire_seconds : int, optional

  • default: 600
  • timeout for action expiry in seconds

verify_filters : str or list of str, optional

  • default: []
  • each string must describe a filter to be used to verify the package

verify_filter_options : str or list of str, optional

  • default: []
  • each string must describe an option for verify_filters

verify_expire_seconds : int, optional

  • default: 600
  • timeout for verify action expiry in seconds

filters_help : bool, optional

  • default: False
  • False: do not print the help string for filters
  • True: print the help string for filters and exit

options_help : bool, optional

  • default: False
  • False: do not print the help string for options
  • True: print the help string for options and exit

metadata: list of list of strs, optional

  • default: []
  • each list must be a 2 item list:
  • list item 1 property name
  • list item 2 property value
Returns:

package_obj : taniumpy.object_types.package_spec.PackageSpec

  • TaniumPy object added to Tanium SOAP Server

See also

pytan.constants.FILTER_MAPS
valid filters for verify_filters
pytan.constants.OPTION_MAPS
valid options for verify_filter_options
create_report_file(contents, report_file=None, **kwargs)[source]

Exports a python API object to a file

Parameters:

contents : str

  • contents to write to report_file

report_file : str, optional

  • filename to save report as

report_dir : str, optional

  • default: None
  • directory to save report in, will use current working directory if not supplied

prefix : str, optional

  • default: ‘’
  • prefix to add to report_file

postfix : str, optional

  • default: ‘’
  • postfix to add to report_file
Returns:

report_path : str

  • the full path to the file created with contents
create_sensor(**kwargs)[source]

Create a sensor object

Raises:pytan.exceptions.HandlerError : pytan.utils.pytan.exceptions.HandlerError

Warning

Not currently supported, too complicated to add. Use create_from_json() instead for this object type!

create_user(name, rolename=[], roleid=[], properties=[], group='', **kwargs)[source]

Create a user object

Parameters:

name : str

  • name of user to create

rolename : str or list of str, optional

  • default: []
  • name(s) of roles to add to user

roleid : int or list of int, optional

  • default: []
  • id(s) of roles to add to user

properties: list of list of strs, optional

  • default: []
  • each list must be a 2 item list:
  • list item 1 property name
  • list item 2 property value

group: str

  • default: ‘’
  • name of group to assign to user
Returns:

user_obj : taniumpy.object_types.user.User

  • TaniumPy object added to Tanium SOAP Server
create_whitelisted_url(url, regex=False, download_seconds=86400, properties=[], **kwargs)[source]

Create a whitelisted url object

Parameters:

url : str

  • text of new url

regex : bool, optional

  • default: False
  • False: url is not a regex pattern
  • True: url is a regex pattern

download_seconds : int, optional

  • default: 86400
  • how often to re-download url

properties: list of list of strs, optional

  • default: []
  • each list must be a 2 item list:
  • list item 1 property name
  • list item 2 property value
Returns:

url_obj : taniumpy.object_types.white_listed_url.WhiteListedUrl

  • TaniumPy object added to Tanium SOAP Server
delete(objtype, **kwargs)[source]

Delete an object type

Parameters:

objtype : string

  • type of object to delete

id/name/hash : int or string, list of int or string

  • search attributes of object to delete, must supply at least one valid search attr
Returns:

ret : dict

  • dict containing deploy action object and results from deploy action

See also

pytan.constants.GET_OBJ_MAP
maps objtype to supported ‘search’ keys
delete_dashboard(name, **kwargs)[source]

Calls pytan.handler.Handler.run_plugin() to run the DeleteDashboards plugin and parse the response

Parameters:

name : str

  • name of dashboard to delete
Returns:

plugin_result, sql_zipped : tuple

  • plugin_result will be the taniumpy object representation of the SOAP response from Tanium server
  • sql_zipped will be a dict with the SQL results embedded in the SOAP response
deploy_action(**kwargs)[source]

Deploy an action and get the results back

This method takes a string or list of strings and parses them into their corresponding definitions needed by _deploy_action()

Parameters:

package : str

  • package to deploy with this action

action_filters : str, list of str, optional

  • default: []
  • each string must describe a sensor and a filter which limits which computers the action will deploy package to

action_options : str, list of str, optional

  • default: []
  • options to apply to action_filters

start_seconds_from_now : int, optional

  • default: 0
  • start action N seconds from now

distribute_seconds : int, optional

  • default: 0
  • distribute action evenly over clients over N seconds

issue_seconds : int, optional

  • default: 0
  • have the server re-ask the action status question if performing a GetResultData over N seconds ago

expire_seconds : int, optional

  • default: package.expire_seconds
  • expire action N seconds from now, will be derived from package if not supplied

run : bool, optional

  • default: False
  • False: just ask the question that pertains to verify action, export the results to CSV, and raise pytan.exceptions.RunFalse – does not deploy the action
  • True: actually deploy the action

get_results : bool, optional

  • default: True
  • True: wait for result completion after deploying action
  • False: just deploy the action and return the object in ret

action_name : str, optional

  • default: prepend package name with “API Deploy “
  • custom name for action

action_comment : str, optional

  • default:
  • custom comment for action

polling_secs : int, optional

complete_pct : int/float, optional

  • default: 100
  • Percentage of passed_count out of successfully run actions to consider the action “done”
  • This is passed through to pytan.pollers.ActionPoller

override_timeout_secs : int, optional

  • default: 0
  • If supplied and not 0, timeout in seconds instead of when object expires
  • This is passed through to pytan.pollers.ActionPoller

override_passed_count : int, optional

  • instead of getting number of systems that should run this action by asking a question, use this number
  • This is passed through to pytan.pollers.ActionPoller
Returns:

ret : dict, containing:

See also

pytan.constants.FILTER_MAPS
valid filter dictionaries for filters
pytan.constants.OPTION_MAPS
valid option dictionaries for options
pytan.handler.Handler._deploy_action()
private method with the actual workflow used to create and add the action object

Examples

>>> # example of str for `package`
>>> package = 'Package1'
>>> # example of str for `package` with params
>>> package = 'Package1{key:value}'
>>> # example of str for `action_filters` with params and filter for sensors
>>> action_filters = 'Sensor1{key:value}, that contains:example text'
>>> # example of list of str for `action_options`
>>> action_options = ['max_data_age:3600', 'and']
export_obj(obj, export_format='csv', **kwargs)[source]

Exports a python API object to a given export format

Parameters:

obj : taniumpy.object_types.base.BaseType or taniumpy.object_types.result_set.ResultSet

  • TaniumPy object to export

export_format : str, optional

  • default: ‘csv’
  • the format to export obj to, one of: {‘csv’, ‘xml’, ‘json’}

header_sort : list of str, bool, optional

header_add_sensor : bool, optional

  • default: False
  • for export_format csv and obj type taniumpy.object_types.result_set.ResultSet
  • False: do not prefix the headers with the associated sensor name for each column
  • True: prefix the headers with the associated sensor name for each column

header_add_type : bool, optional

  • default: False
  • for export_format csv and obj type taniumpy.object_types.result_set.ResultSet
  • False: do not postfix the headers with the result type for each column
  • True: postfix the headers with the result type for each column

expand_grouped_columns : bool, optional

  • default: False
  • for export_format csv and obj type taniumpy.object_types.result_set.ResultSet
  • False: do not expand multiline row entries into their own rows
  • True: expand multiline row entries into their own rows

explode_json_string_values : bool, optional

  • default: False
  • for export_format json or csv and obj type taniumpy.object_types.base.BaseType
  • False: do not explode JSON strings in object attributes into their own object attributes
  • True: explode JSON strings in object attributes into their own object attributes

minimal : bool, optional

  • default: False
  • for export_format xml and obj type taniumpy.object_types.base.BaseType
  • False: include empty attributes in XML output
  • True: do not include empty attributes in XML output
Returns:

result : str

  • the contents of exporting export_format

See also

pytan.constants.EXPORT_MAPS
maps the type obj to export_format and the optional args supported for each

Notes

When performing a CSV export and importing that CSV into excel, keep in mind that Excel has a per cell character limit of 32,000. Any cell larger than that will be broken up into a whole new row, which can wreak havoc with data in Excel.

export_to_report_file(obj, export_format='csv', **kwargs)[source]

Exports a python API object to a file

Parameters:

obj : taniumpy.object_types.base.BaseType or taniumpy.object_types.result_set.ResultSet

  • TaniumPy object to export

export_format : str, optional

  • default: ‘csv’
  • the format to export obj to, one of: {‘csv’, ‘xml’, ‘json’}

header_sort : list of str, bool, optional

header_add_sensor : bool, optional

  • default: False
  • for export_format csv and obj type taniumpy.object_types.result_set.ResultSet
  • False: do not prefix the headers with the associated sensor name for each column
  • True: prefix the headers with the associated sensor name for each column

header_add_type : bool, optional

  • default: False
  • for export_format csv and obj type taniumpy.object_types.result_set.ResultSet
  • False: do not postfix the headers with the result type for each column
  • True: postfix the headers with the result type for each column

expand_grouped_columns : bool, optional

  • default: False
  • for export_format csv and obj type taniumpy.object_types.result_set.ResultSet
  • False: do not expand multiline row entries into their own rows
  • True: expand multiline row entries into their own rows

explode_json_string_values : bool, optional

  • default: False
  • for export_format json or csv and obj type taniumpy.object_types.base.BaseType
  • False: do not explode JSON strings in object attributes into their own object attributes
  • True: explode JSON strings in object attributes into their own object attributes

minimal : bool, optional

  • default: False
  • for export_format xml and obj type taniumpy.object_types.base.BaseType
  • False: include empty attributes in XML output
  • True: do not include empty attributes in XML output

report_file: str, optional

  • default: None
  • filename to save report as, will be automatically generated if not supplied

report_dir: str, optional

  • default: None
  • directory to save report in, will use current working directory if not supplied

prefix: str, optional

  • default: ‘’
  • prefix to add to report_file

postfix: str, optional

  • default: ‘’
  • postfix to add to report_file
Returns:

report_path, result : tuple

  • report_path : str, the full path to the file created with contents of result
  • result : str, the contents written to report_path

See also

pytan.handler.Handler.export_obj()
method that performs the actual work to do the exporting
pytan.handler.Handler.create_report_file()
method that performs the actual work to write the report file

Notes

When performing a CSV export and importing that CSV into excel, keep in mind that Excel has a per cell character limit of 32,000. Any cell larger than that will be broken up into a whole new row, which can wreak havoc with data in Excel.

get(objtype, **kwargs)[source]

Get an object type

Parameters:

objtype : string

  • type of object to get

id/name/hash : int or string, list of int or string

  • search attributes of object to get, must supply at least one valid search attr
Returns:

obj_list : taniumpy.object_types.base.BaseType

  • The object list of items found for objtype

See also

pytan.constants.GET_OBJ_MAP
maps objtype to supported ‘search’ keys
pytan.handler.Handler._get_multi()
private method used to get multiple items
pytan.handler.Handler._get_single()
private method used to get singular items
get_all(objtype, **kwargs)[source]

Get all objects of a type

Parameters:

objtype : string

  • type of object to get
Returns:

obj_list : taniumpy.object_types.base.BaseType

  • The object list of items found for objtype

See also

pytan.constants.GET_OBJ_MAP
maps objtype to supported ‘search’ keys
pytan.handler.Handler._find()
private method used to find items
get_dashboards(name='', **kwargs)[source]

Calls pytan.handler.Handler.run_plugin() to run the GetDashboards plugin and parse the response

Parameters:

name : str, optional

  • default: ‘’
  • name of dashboard to get, if empty will return all dashboards
Returns:

plugin_result, sql_zipped : tuple

  • plugin_result will be the taniumpy object representation of the SOAP response from Tanium server
  • sql_zipped will be a dict with the SQL results embedded in the SOAP response
get_result_data(obj, aggregate=False, shrink=True, **kwargs)[source]

Get the result data for a python API object

This method issues a GetResultData command to the SOAP api for obj. GetResultData returns the columns and rows that are currently available for obj.

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to get result data for

aggregate : bool, optional

  • default: False
  • False: get all the data
  • True: get just the aggregate data (row counts of matches)

shrink : bool, optional

  • default: True
  • True: Shrink the object down to just id/name/hash attributes (for smaller request)
  • False: Use the full object as is
Returns:

rd : taniumpy.object_types.result_set.ResultSet

The return of GetResultData for obj

get_result_data_sse(obj, **kwargs)[source]

Get the result data for a python API object using a server side export (sse)

This method issues a GetResultData command to the SOAP api for obj with the option export_flag set to 1. This will cause the server to process all of the data for a given result set and save it as export_format. Then the user can use an authenticated GET request to get the status of the file via “/export/${export_id}.status”. Once the status returns “Completed.”, the actual report file can be retrieved by an authenticated GET request to “/export/${export_id}.gz”. This workflow saves a lot of processing time and removes the need to paginate large result sets necessary in normal GetResultData calls.

Version support
  • 6.5.314.4231: initial sse support (csv only)
  • 6.5.314.4300: export_format support (adds xml and cef)
  • 6.5.314.4300: fix core dump if multiple sse done on empty resultset
  • 6.5.314.4300: fix no status file if sse done on empty resultset
  • 6.5.314.4300: fix response if more than two sse done in same second
Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to get result data for

sse_format : str, optional

  • default: ‘csv’
  • format to have server create report in, one of: {‘csv’, ‘xml’, ‘xml_obj’, ‘cef’, 0, 1, 2}

leading : str, optional

  • default: ‘’
  • used for sse_format ‘cef’ only, the string to prepend to each row

trailing : str, optional

  • default: ‘’
  • used for sse_format ‘cef’ only, the string to append to each row
Returns:

export_data : either str or taniumpy.object_types.result_set.ResultSet

  • If sse_format is one of csv, xml, or cef, export_data will be a str containing the contents of the ResultSet in said format
  • If sse_format is xml_obj, export_data will be a taniumpy.object_types.result_set.ResultSet

See also

pytan.constants.SSE_FORMAT_MAP
maps sse_format to an integer for use by the SOAP API
pytan.constants.SSE_RESTRICT_MAP
maps sse_format integers to supported platform versions
pytan.constants.SSE_CRASH_MAP
maps platform versions that can cause issues in various scenarios
get_result_info(obj, shrink=True, **kwargs)[source]

Get the result info for a python API object

This method issues a GetResultInfo command to the SOAP api for obj. GetResultInfo returns information about how many servers have passed the obj, total number of servers, and so on.

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to get result data for

shrink : bool, optional

  • default: True
  • True: Shrink the object down to just id/name/hash attributes (for smaller request)
  • False: Use the full object as is
Returns:

ri : taniumpy.object_types.result_info.ResultInfo

  • The return of GetResultInfo for obj
get_server_version(**kwargs)[source]

Uses taniumpy.session.Session.get_server_version() to get the version of the Tanium Server

Returns:

server_version: str

  • Version of Tanium Server in string format
parse_query(question_text, **kwargs)[source]

Ask a parsed question as question_text and get a list of parsed results back

Parameters:

question_text : str

  • The question text you want the server to parse into a list of parsed results
Returns:

parse_job_results : taniumpy.object_types.parse_result_group.ParseResultGroup

read_pytan_user_config(kwargs)[source]

Read a PyTan User Config and update the current class variables

Returns:

kwargs : dict

  • kwargs with updated variables from PyTan User Config (if any)
run_plugin(obj, **kwargs)[source]

Wrapper around pytan.session.Session.run_plugin() to run the plugin and zip up the SQL results into a python dictionary

Parameters:

obj : taniumpy.object_types.plugin.Plugin

  • Plugin object to run
Returns:

plugin_result, sql_zipped : tuple

  • plugin_result will be the taniumpy object representation of the SOAP response from Tanium server
  • sql_zipped will be a dict with the SQL results embedded in the SOAP response
stop_action(id, **kwargs)[source]

Stop an action

Parameters:

id : int

  • id of action to stop
Returns:

action_stop_obj : taniumpy.object_types.action_stop.ActionStop

The object containing the ID of the action stop job

write_pytan_user_config(**kwargs)[source]

Write a PyTan User Config with the current class variables for use with pytan_user_config in instantiating Handler()

Parameters:

pytan_user_config : str, optional

  • default: self.puc
  • JSON file to wite with current class variables
Returns:

puc : str

  • filename of PyTan User Config that was written to
xml_to_result_set_obj(x, **kwargs)[source]

Wraps a Result Set XML from a server side export in the appropriate tags and returns a ResultSet object

Parameters:

x : str

  • str of XML to convert to a ResultSet object
Returns:

rs : taniumpy.object_types.result_set.ResultSet

  • x converted into a ResultSet object

2.2. pytan.sessions

Session classes for the pytan module.

class pytan.sessions.Session(host, port=443, **kwargs)[source]

Bases: object

This session object uses the requests package instead of the built in httplib library.

This provides support for keep alive, gzip, cookies, forwarding, and a host of other features automatically.

Examples

Setup a Session() object:

>>> import sys
>>> sys.path.append('/path/to/pytan/')
>>> import pytan
>>> session = pytan.sessions.Session('host')

Authenticate with the Session() object:

>>> session.authenticate('username', 'password')
ALL_REQUESTS_RESPONSES = []

This list will be updated with each requests response object that was received

AUTH_CONNECT_TIMEOUT_SEC = 5

number of seconds before timing out for a connection while authenticating

AUTH_FAIL_CODES = [401, 403]

List of HTTP response codes that equate to authorization failures

AUTH_RES = 'auth'

The URL to use for authentication requests

AUTH_RESPONSE_TIMEOUT_SEC = 15

number of seconds before timing out for a response while authenticating

BAD_RESPONSE_CMD_PRUNES = ['\n', 'XML Parse Error: ', 'SOAPProcessing Exception: class ', 'ERROR: 400 Bad Request']

List of strings to remove from commands in responses that do not match the response in the request

BAD_SERVER_VERSIONS = [None, '', 'Unable to determine', 'Not yet determined']

List of server versions that are not valid

ELEMENT_RE_TXT = '<{0}>(.*?)</{0}>'

regex string to search for an element in XML bodies

HTTP_AUTH_RETRY = True

retry HTTP GET/POST’s with username/password if session_id fails or not

HTTP_DEBUG = False

print requests package debug or not

HTTP_RETRY_COUNT = 5

number of times to retry HTTP GET/POST’s if the connection times out/fails

INFO_CONNECT_TIMEOUT_SEC = 5

number of seconds before timing out for a connection while getting server info

INFO_RES = 'info.json'

The URL to use for server info requests

INFO_RESPONSE_TIMEOUT_SEC = 15

number of seconds before timing out for a response while getting server info

LAST_REQUESTS_RESPONSE = None

This variable will be updated with the last requests response object that was received

LAST_RESPONSE_INFO = {}

This variable will be updated with the information from the most recent call to _get_response()

RECORD_ALL_REQUESTS = False

Controls whether each requests response object is appended to the self.ALL_REQUESTS_RESPONSES list

REQUESTS_SESSION = None

The Requests session allows you to persist certain parameters across requests. It also persists cookies across all requests made from the Session instance. Any requests that you make within a session will automatically reuse the appropriate connection

REQUEST_BODY_BASE = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\n<SOAP-ENV:Body>\n <typens:tanium_soap_request xmlns:typens="urn:TaniumSOAP">\n <command>$command</command>\n <object_list>$object_list</object_list>\n $options\n </typens:tanium_soap_request>\n</SOAP-ENV:Body>\n</SOAP-ENV:Envelope>'

The XML template used for all SOAP Requests in string form

SOAP_CONNECT_TIMEOUT_SEC = 15

number of seconds before timing out for a connection while sending a SOAP Request

SOAP_REQUEST_HEADERS = {'Content-Type': 'text/xml; charset=utf-8', 'Accept-Encoding': 'gzip'}

dictionary of headers to add to every HTTP GET/POST

SOAP_RES = 'soap'

The URL to use for SOAP requests

SOAP_RESPONSE_TIMEOUT_SEC = 540

number of seconds before timing out for a response while sending a SOAP request

STATS_LOOP_ENABLED = False

enable the statistics loop thread or not

STATS_LOOP_SLEEP_SEC = 5

number of seconds to sleep in between printing the statistics when stats_loop_enabled is True

STATS_LOOP_TARGETS = [{'Version': 'Settings/Version'}, {'Active Questions': 'Active Question Cache/Active Question Estimate'}, {'Clients': 'Active Question Cache/Active Client Estimate'}, {'Strings': 'String Cache/Total String Count'}, {'Handles': 'System Performance Info/HandleCount'}, {'Processes': 'System Performance Info/ProcessCount'}, {'Memory Available': 'percentage(System Performance Info/PhysicalAvailable,System Performance Info/PhysicalTotal)'}]

list of dictionaries with the key being the section of info.json to print info from, and the value being the item with in that section to print the value

XMLNS = {'xsi': 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"', 'typens': 'xmlns:typens="urn:TaniumSOAP"', 'xsd': 'xmlns:xsd="http://www.w3.org/2001/XMLSchema"', 'SOAP-ENV': 'xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"'}

The namespace mappings for use in XML Request bodies

_build_body(command, object_list, log_options=False, **kwargs)[source]

Utility method for building an XML Request Body

Parameters:

command : str

  • text to use in command node when building template

object_list : str

  • XML string to use in object list node when building template

kwargs : dict, optional

log_options : bool, optional

  • default: False
  • False: Do not print messages setting attributes in Options from keys in kwargs
  • True: Print messages setting attributes in Options from keys in kwargs
Returns:

body : str

  • The XML request body created from the string.template self.REQUEST_BODY_TEMPLATE
_check_auth()[source]

Utility method to check if authentication has been done yet, and throw an exception if not

_clean_headers(headers=None)[source]

Utility method for getting the headers for the current request, combining them with the session headers used for every request, and obfuscating the value of any ‘password’ header.

Parameters:

headers : dict

  • dict of key/value pairs for a set of headers for a given request
Returns:

headers : dict

  • dict of key/value pairs for a set of cleaned headers for a given request
_create_add_object_body(obj, **kwargs)[source]

Utility method for building an XML Request Body to add an object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to convert into XML

kwargs : dict, optional

Returns:

obj_body : str

_create_delete_object_body(obj, **kwargs)[source]

Utility method for building an XML Request Body to delete an object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to convert into XML

kwargs : dict, optional

Returns:

obj_body : str

_create_get_object_body(obj, **kwargs)[source]

Utility method for building an XML Request Body to get an object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to convert into XML

kwargs : dict, optional

Returns:

obj_body : str

_create_get_result_data_body(obj, **kwargs)[source]

Utility method for building an XML Request Body to get result data for an object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to convert into XML

kwargs : dict, optional

Returns:

obj_body : str

_create_get_result_info_body(obj, **kwargs)[source]

Utility method for building an XML Request Body to get result info for an object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to convert into XML

kwargs : dict, optional

Returns:

obj_body : str

_create_run_plugin_object_body(obj, **kwargs)[source]

Utility method for building an XML Request Body to run a plugin

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to convert into XML

kwargs : dict, optional

Returns:

obj_body : str

_create_update_object_body(obj, **kwargs)[source]

Utility method for building an XML Request Body to update an object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to convert into XML

kwargs : dict, optional

Returns:

obj_body : str

_debug_locals(fname, flocals)[source]

Method to print out locals for a function if self.DEBUG_METHOD_LOCALS is True

_extract_resultxml(response_body)[source]

Utility method to get the ‘ResultXML’ element from an XML body

Parameters:

response_body : str

  • XML body to search for the ‘ResultXML’ element in
Returns:

ret : str of ResultXML element

  • str if ‘export_id’ element found in XML
_find_stat_target(target, diags)[source]

Utility method for finding a target in info.json and returning the value, optionally performing a percentage calculation on two values if the target[0] starts with percentage(

Parameters:

target : list

  • index0 : label : human friendly name to refer to search_path
  • index1 : search_path : / seperated search path to find a given value from info.json

diags : dict

  • flattened dictionary of info.json diagnostics
Returns:

dict

_flatten_server_info(structure)[source]

Utility method for flattening the JSON structure for info.json into a more python usable format

Parameters:

structure

  • dict/tuple/list to flatten
Returns:

flattened

  • the dict/tuple/list flattened out
_full_url(url, **kwargs)[source]

Utility method for constructing a full url

Parameters:

url : str

  • url to use in string

host : str, optional

  • default: self.host
  • hostname/IP address to use in string

port : str, optional

  • default: self.port
  • port to use in string
Returns:

full_url : str

_get_percentage(part, whole)[source]

Utility method for getting percentage of part out of whole

Parameters:

part: int, float

whole: int, float

Returns:

str : the percentage of part out of whole in 2 decimal places

_get_response(request_body, **kwargs)[source]

This is a wrapper around pytan.sessions.Session.http_post() for SOAP XML requests and responses.

This method will update self.session_id if the response contains a different session_id than what is currently in this object.

Parameters:

request_body : str

  • the XML request body to send to the server

connect_timeout: int, optional

  • default: self.SOAP_CONNECT_TIMEOUT_SEC
  • timeout in seconds for connection to host

response_timeout: int, optional

  • default: self.SOAP_RESPONSE_TIMEOUT_SEC
  • timeout in seconds for response from host

retry_auth: bool, optional

  • default: True
  • True: retry authentication with username/password if session_id fails
  • False: throw exception if session_id fails

retry_count: int, optional

  • number of times to retry the request if the server fails to respond properly or in time

pytan_help : str, optional

  • default: ‘’
  • help string to add to self.LAST_REQUESTS_RESPONSE.pytan_help
Returns:

body : str

  • str containing body of response from server

See also

pytan.sessions.Session.http_post()
wrapper method used to perform the HTTP POST
_http_get(host, port, url, headers=None, connect_timeout=15, response_timeout=180, debug=False, pytan_help='', **kwargs)[source]

This is an HTTP GET method that utilizes the requests package.

Parameters:

host : str

  • host to connect to

port : int

  • port to connect to

url : str

  • url to fetch on the server

headers : dict, optional

  • default: None
  • headers to supply as part of POST request

connect_timeout : int, optional

  • default: 15
  • timeout in seconds for connection to host

response_timeout : int, optional

  • default: 180
  • timeout in seconds for response from host

debug : bool, optional

  • default: False
  • False: do not print requests debug messages
  • True: print requests debug messages

pytan_help : str, optional

  • default: ‘’
  • help string to add to self.LAST_REQUESTS_RESPONSE.pytan_help

perform_xml_clean : bool, optional

  • default: False
  • False: Do not run the response_body through an XML cleaner
  • True: Run the response_body through an XML cleaner before returning it

clean_restricted : bool, optional

  • default: True
  • True: When XML cleaning the response_body, remove restricted characters as well as invalid characters
  • False: When XML cleaning the response_body, remove only invalid characters

log_clean_messages : bool, optional

  • default: True
  • True: When XML cleaning the response_body, enable logging messages about invalid/restricted matches
  • False: When XML cleaning the response_body, disable logging messages about invalid/restricted matches

log_bad_characters : bool, optional

  • default: False
  • False: When XML cleaning the response_body, disable logging messages about the actual characters that were invalid/restricted
  • True: When XML cleaning the response_body, enable logging messages about the actual characters that were invalid/restricted
Returns:

body : str

  • str containing body of response from server
_http_post(host, port, url, body=None, headers=None, connect_timeout=15, response_timeout=180, debug=False, pytan_help='', **kwargs)[source]

This is an HTTP POST method that utilizes the requests package.

Parameters:

host : str

  • host to connect to

port : int

  • port to connect to

url : str

  • url to fetch on the server

body : str, optional

  • default: None
  • body to send as part of the POST request

headers : dict, optional

  • default: None
  • headers to supply as part of POST request

connect_timeout : int, optional

  • default: 15
  • timeout in seconds for connection to host

response_timeout : int, optional

  • default: 180
  • timeout in seconds for response from host

debug : bool, optional

  • default: False
  • False: do not print requests debug messages
  • True: print requests debug messages

pytan_help : str, optional

  • default: ‘’
  • help string to add to self.LAST_REQUESTS_RESPONSE.pytan_help

perform_xml_clean : bool, optional

  • default: True
  • True: Run the response_body through an XML cleaner before returning it
  • False: Do not run the response_body through an XML cleaner

clean_restricted : bool, optional

  • default: True
  • True: When XML cleaning the response_body, remove restricted characters as well as invalid characters
  • False: When XML cleaning the response_body, remove only invalid characters

log_clean_messages : bool, optional

  • default: True
  • True: When XML cleaning the response_body, enable logging messages about invalid/restricted matches
  • False: When XML cleaning the response_body, disable logging messages about invalid/restricted matches

log_bad_characters : bool, optional

  • default: False
  • False: When XML cleaning the response_body, disable logging messages about the actual characters that were invalid/restricted
  • True: When XML cleaning the response_body, enable logging messages about the actual characters that were invalid/restricted
Returns:

body : str

  • str containing body of response from server

See also

pytan.xml_clean.xml_cleaner()
function to remove invalid/bad characters from XML responses
_invalid_server_version()[source]

Utility method to find out if self.server_version is valid or not

_regex_body_for_element(body, element, fail=True)[source]

Utility method to use a regex to get an element from an XML body

Parameters:

body : str

  • XML to search

element : str

  • element name to search for in body

fail : bool, optional

  • default: True
  • True: throw exception if unable to find any matches for regex in body
  • False do not throw exception if unable to find any matches for regex in body
Returns:

ret : str

  • The first value that matches the regex ELEMENT_RE_TXT with element

Notes

  • Using regex is WAY faster than ElementTree chewing the body in and out, this matters a LOT on LARGE return bodies
_replace_auth(headers)[source]

Utility method for removing username, password, and/or session from supplied headers and replacing them with the current objects session or username and password

Parameters:

headers : dict

  • dict of key/value pairs for a set of headers for a given request
Returns:

headers : dict

  • dict of key/value pairs for a set of headers for a given request
_resolve_stat_target(search_path, diags)[source]

Utility method for resolving the value of search_path in info.json and returning the value

Parameters:

search_path : str

  • / seperated search path to find a given value from info.json

diags : dict

  • flattened dictionary of info.json diagnostics
Returns:

str

  • value resolved from diags for search_path
_start_stats_thread(**kwargs)[source]

Utility method starting the pytan.sessions.Session._stats_loop() method in a threaded daemon

_stats_loop(**kwargs)[source]

Utility method for logging server stats via pytan.sessions.Session.get_server_stats() every self.STATS_LOOP_SLEEP_SEC

add(obj, **kwargs)[source]

Creates and sends a AddObject XML Request body from obj and parses the response into an appropriate taniumpy object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to add
Returns:

obj : taniumpy.object_types.base.BaseType

  • added object
authenticate(username=None, password=None, session_id=None, **kwargs)[source]

Authenticate against a Tanium Server using a username/password or a session ID

Parameters:

username : str, optional

  • default: None
  • username to authenticate as

password : str, optional

  • default: None
  • password for username

session_id : str, optional

  • default: None
  • session_id to authenticate with, this will be used in favor of username/password if all 3 are supplied.

persistent: bool, optional

  • default: False
  • False: do not request a persistent session (returns a session_id that expires 5 minutes after last use)
  • True: do request a persistent (returns a session_id that expires 1 week after last use)

pytan_help : str, optional

  • default: ‘’
  • help string to add to self.LAST_REQUESTS_RESPONSE.pytan_help

Notes

Can request a persistent session that will last up to 1 week when authenticating with username and password.

New persistent sessions may be handed out by the Tanium server when the session handed by this auth call is used to login with that week. The new session must be used to login, as no matter what persistent sessions will expire 1 week after issuance (or when logout is called with that session, or when logout with all_sessions=True is called for any session for this user)

the way sessions get issued:

  • a GET request to /auth is issued
  • username/password supplied in headers as base64 encoded, or session is supplied in headers as string
  • session is returned upon successful auth
  • if there is a header “persistent=1” in the headers, a session that expires after 1 week will be issued if username/password was used to auth. persistent is ignored if session is used to auth.
  • if there is not a header “persistent=1” in the headers, a session that expires after 5 minutes will be issued
  • if session is used before it expires, it’s expiry will be extended by 5 minutes or 1 week, depending on the type of persistence
  • while using the SOAP api, new session ID’s may be returned as part of the response. these new session ID’s should be used in lieu of the old session ID

/auth URL This url is used for validating a server user’s credentials. It supports a few different ways to authenticate and returns a SOAP session ID on success. These sessions expire after 5 minutes by default if they aren’t used in SOAP requests. This expiration is configured with the server setting ‘session_expiration_seconds’.

Supported Authentication Methods:
  • HTTP Basic Auth (Clear Text/BASE64)
  • Username/Password/Domain Headers (Clear Text)
  • Negotiate (NTLM Only)

NTLM is enabled by default in 6.3 or greater and requires a persistent connection until a session is generated.

delete(obj, **kwargs)[source]

Creates and sends a DeleteObject XML Request body from obj and parses the response into an appropriate taniumpy object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to delete
Returns:

obj : taniumpy.object_types.base.BaseType

  • deleted object
disable_stats_loop(sleep=None)[source]

Disables the stats loop thread, which will print out the results of pytan.sessions.Session.get_server_stats() every pytan.sessions.Session.STATS_LOOP_SLEEP_SEC

Parameters:

sleep : int, optional

See also

pytan.sessions.Session._stats_loop()
method started as a thread which checks self.STATS_LOOP_ENABLED before running pytan.sessions.Session.get_server_stats()
enable_stats_loop(sleep=None)[source]

Enables the stats loop thread, which will print out the results of pytan.sessions.Session.get_server_stats() every pytan.sessions.Session.STATS_LOOP_SLEEP_SEC

Parameters:

sleep : int, optional

See also

pytan.sessions.Session._stats_loop()
method started as a thread which checks self.STATS_LOOP_ENABLED before running pytan.sessions.Session.get_server_stats()
find(obj, **kwargs)[source]

Creates and sends a GetObject XML Request body from object_type and parses the response into an appropriate taniumpy object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to find
Returns:

obj : taniumpy.object_types.base.BaseType

  • found objects
force_server_version = ''

In the case where the user wants to have pytan act as if the server is a specific version, regardless of what server_version is.

get_result_data(obj, **kwargs)[source]

Creates and sends a GetResultData XML Request body from obj and parses the response into an appropriate taniumpy object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to get result set for
Returns:

obj : taniumpy.object_types.result_set.ResultSet

  • otherwise, obj will be the ResultSet for obj
get_result_data_sse(obj, **kwargs)[source]

Creates and sends a GetResultData XML Request body that starts a server side export from obj and parses the response for an export_id.

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to start server side export
Returns:

export_id : str

  • value of export_id element found in response
get_result_info(obj, **kwargs)[source]

Creates and sends a GetResultInfo XML Request body from obj and parses the response into an appropriate taniumpy object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to get result info for
Returns:

obj : taniumpy.object_types.result_info.ResultInfo

  • ResultInfo for obj
get_server_info(port=None, fallback_port=444, **kwargs)[source]

Gets the /info.json

Parameters:

port : int, optional

  • default: None
  • port to attempt getting /info.json from, if not specified will use self.port

fallback_port : int, optional

  • default: 444
  • fallback port to attempt getting /info.json from if port fails
Returns:

info_dict : dict

  • raw json response converted into python dict
  • ‘diags_flat’: info.json flattened out into an easier to use structure for python handling
  • ‘server_info_pass_msgs’: messages about successfully retrieving info.json
  • ‘server_info_fail_msgs’: messages about failing to retrieve info.json

See also

pytan.sessions.Session._flatten_server_info()
method to flatten the dictionary received from info.json into a python friendly format

Notes

  • 6.2 /info.json is only available on soap port (default port: 444)
  • 6.5 /info.json is only available on server port (default port: 443)
get_server_stats(**kwargs)[source]

Creates a str containing a number of stats gathered from /info.json

Returns:

str

  • str containing stats from /info.json

See also

pytan.sessions.Session.STATS_LOOP_TARGETS
list of dict containing stat keys to pull from /info.json
get_server_version(**kwargs)[source]

Tries to parse the server version from /info.json

Returns:

str

  • str containing server version from /info.json
host = None

host to connect to

http_get(url, **kwargs)[source]

This is an authenticated HTTP GET method. It will always forcibly use the authentication credentials that are stored in the current object when performing an HTTP GET.

Parameters:

url : str

  • url to fetch on the server

host : str, optional

  • default: self.host
  • host to connect to

port : int, optional

  • default: self.port
  • port to connect to

headers : dict, optional

  • default: {}
  • headers to supply as part of GET request

connect_timeout : int, optional

  • default: self.SOAP_CONNECT_TIMEOUT_SEC
  • timeout in seconds for connection to host

response_timeout : int, optional

  • default: self.SOAP_RESPONSE_TIMEOUT_SEC
  • timeout in seconds for response from host

debug : bool, optional

  • default: self.HTTP_DEBUG
  • False: do not print requests debug messages
  • True: print requests debug messages

auth_retry : bool, optional

  • default: self.HTTP_AUTH_RETRY
  • True: retry authentication with username/password if session_id fails
  • False: throw exception if session_id fails

retry_count : int, optional

  • default: self.HTTP_RETRY_COUNT
  • number of times to retry the GET request if the server fails to respond properly or in time

pytan_help : str, optional

  • default: ‘’
  • help string to add to self.LAST_REQUESTS_RESPONSE.pytan_help
Returns:

body : str

  • str containing body of response from server

See also

pytan.sessions.Session._http_get()
private method used to perform the actual HTTP GET
http_post(**kwargs)[source]

This is an authenticated HTTP POST method. It will always forcibly use the authentication credentials that are stored in the current object when performing an HTTP POST.

Parameters:

url : str, optional

  • default: self.SOAP_RES
  • url to fetch on the server

host : str, optional

  • default: self.host
  • host to connect to

port : int, optional

  • default: self.port
  • port to connect to

headers : dict, optional

  • default: {}
  • headers to supply as part of POST request

body : str, optional

  • default: ‘’
  • body to send as part of the POST request

connect_timeout : int, optional

  • default: self.SOAP_CONNECT_TIMEOUT_SEC
  • timeout in seconds for connection to host

response_timeout : int, optional

  • default: self.SOAP_RESPONSE_TIMEOUT_SEC
  • timeout in seconds for response from host

debug : bool, optional

  • default: self.HTTP_DEBUG
  • False: do not print requests debug messages
  • True: print requests debug messages

auth_retry : bool, optional

  • default: self.HTTP_AUTH_RETRY
  • True: retry authentication with username/password if session_id fails
  • False: throw exception if session_id fails

retry_count : int, optional

  • default: self.HTTP_RETRY_COUNT
  • number of times to retry the POST request if the server fails to respond properly or in time

pytan_help : str, optional

  • default: ‘’
  • help string to add to self.LAST_REQUESTS_RESPONSE.pytan_help
Returns:

body : str

  • str containing body of response from server

See also

pytan.sessions.Session._http_post()
private method used to perform the actual HTTP POST
is_auth

Property to determine if there is a valid session_id or username and password stored in this object

Returns:

bool

  • True: if self._session_id or self._username and _self.password are set
  • False: if not
logout(all_session_ids=False, **kwargs)[source]

Logout a given session_id from Tanium. If not session_id currently set, it will authenticate to get one.

Parameters:

all_session_ids : bool, optional

  • default: False
  • False: only log out the current session id for the current user
  • True: log out ALL session id’s associated for the current user

pytan_help : str, optional

  • default: ‘’
  • help string to add to self.LAST_REQUESTS_RESPONSE.pytan_help
platform_is_6_5(**kwargs)[source]

Check to see if self.server_version is less than 6.5

Returns:

is6_5 : bool

  • True if self.force_server_version is greater than or equal to 6.5
  • True if self.server_version is greater than or equal to 6.5
  • False if self.server_version is less than 6.5
port = None

port to connect to

run_plugin(obj, **kwargs)[source]

Creates and sends a RunPlugin XML Request body from obj and parses the response into an appropriate taniumpy object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to run
Returns:

obj : taniumpy.object_types.base.BaseType

  • results from running object
save(obj, **kwargs)[source]

Creates and sends a UpdateObject XML Request body from obj and parses the response into an appropriate taniumpy object

Parameters:

obj : taniumpy.object_types.base.BaseType

  • object to save
Returns:

obj : taniumpy.object_types.base.BaseType

  • saved object
server_version = 'Not yet determined'

version string of server, will be updated when get_server_version() is called

session_id

Property to fetch the session_id for this object

Returns:self._session_id : str
setup_logging()[source]

2.3. pytan.pollers

Collection of classes and methods for polling of actions/questions in pytan

class pytan.pollers.ActionPoller(handler, obj, **kwargs)[source]

Bases: pytan.pollers.QuestionPoller

A class to poll the progress of an Action.

The primary function of this class is to poll for result info for an action, and fire off events:
  • ‘SeenProgressChanged’
  • ‘SeenAnswersComplete’
  • ‘FinishedProgressChanged’
  • ‘FinishedAnswersComplete’
Parameters:

handler : pytan.handler.Handler

  • PyTan handler to use for GetResultInfo calls

obj : taniumpy.object_types.action.Action

  • object to poll for progress

polling_secs : int, optional

  • default: 5
  • Number of seconds to wait in between GetResultInfo loops

complete_pct : int/float, optional

  • default: 100
  • Percentage of passed_count out of successfully run actions to consider the action “done”

override_timeout_secs : int, optional

  • default: 0
  • If supplied and not 0, timeout in seconds instead of when object expires

override_passed_count : int, optional

  • instead of getting number of systems that should run this action by asking a question, use this number
ACTION_DONE_KEY = 'success'

key in action_result_map that maps to an action being done

COMPLETE_PCT_DEFAULT = 100

default value for self.complete_pct

EXPIRATION_ATTR = 'expiration_time'

attribute of self.obj that contains the expiration for this object

OBJECT_TYPE

valid type of object that can be passed in as obj to __init__

alias of Action

RUNNING_STATUSES = ['active', 'open']

values for status attribute of action object that mean the action is running

_derive_object_info(**kwargs)[source]

Derive self.object_info from self.obj

_derive_package_spec(**kwargs)[source]

Get the package_spec attribute for self.obj, then fetch the full package_spec object

_derive_result_map(**kwargs)[source]

Determine what self.result_map should contain for the various statuses an action can have

A package object has to have a verify_group defined on it in order for deploy action verification to trigger. That can be only done at package creation/update

If verify_enable is True, then the various result states for an action change

_derive_status(**kwargs)[source]

Get the status attribute for self.obj

_derive_stopped_flag(**kwargs)[source]

Get the stopped_flag attribute for self.obj

_derive_target_group(**kwargs)[source]

Get the target_group attribute for self.obj, then fetch the full group object

_derive_verify_enabled(**kwargs)[source]

Determine if this action has verification enabled

_fix_group(g, **kwargs)[source]

Sets ID to null on a group object and all of it’s sub_groups, needed for 6.5

_post_init(**kwargs)[source]

Post init class setup

finished_eq_passed_loop(callbacks={}, **kwargs)[source]

Method to poll Result Info for self.obj until the percentage of ‘finished_count’ out of ‘self.passed_count’ is greater than or equal to self.complete_pct

  • finished_count is calculated from a full GetResultData call that is parsed into self.action_result_map
  • self.passed_count is calculated by the question asked before this method is called. that question has no selects, but has a group that is the same group as the action for this object
run(callbacks={}, **kwargs)[source]

Poll for action data and issue callbacks.

Parameters:

callbacks : dict

  • Callbacks should be a dict with any of these members:
    • ‘SeenProgressChanged’
    • ‘SeenAnswersComplete’
    • ‘FinishedProgressChanged’
    • ‘FinishedAnswersComplete’
  • Each callback should be a function that accepts:
    • ‘poller’: a poller instance
    • ‘pct’: a percent complete
    • ‘kwargs’: a dict of other args

Notes

  • Any callback can choose to get data from the session by calling pytan.poller.QuestionPoller.get_result_data() or new info by calling pytan.poller.QuestionPoller.get_result_info()
  • Any callback can choose to stop the poller by calling pytan.poller.QuestionPoller.stop()
  • Polling will be stopped only when one of the callbacks calls the pytan.poller.QuestionPoller.stop() method or the answers are complete.
  • Any callbacks can call pytan.poller.QuestionPoller.setPercentCompleteThreshold() to change what “done” means on the fly
seen_eq_passed_loop(callbacks={}, **kwargs)[source]

Method to poll Result Info for self.obj until the percentage of ‘seen_count’ out of ‘self.passed_count’ is greater than or equal to self.complete_pct

  • seen_count is calculated from an aggregate GetResultData
  • self.passed_count is calculated by the question asked before this method is called. that question has no selects, but has a group that is the same group as the action for this object
class pytan.pollers.QuestionPoller(handler, obj, **kwargs)[source]

Bases: object

A class to poll the progress of a Question.

The primary function of this class is to poll for result info for a question, and fire off events:

  • ProgressChanged
  • AnswersChanged
  • AnswersComplete
Parameters:

handler : pytan.handler.Handler

  • PyTan handler to use for GetResultInfo calls

obj : taniumpy.object_types.question.Question

  • object to poll for progress

polling_secs : int, optional

  • default: 5
  • Number of seconds to wait in between GetResultInfo loops

complete_pct : int/float, optional

  • default: 99
  • Percentage of mr_tested out of estimated_total to consider the question “done”

override_timeout_secs : int, optional

  • default: 0
  • If supplied and not 0, timeout in seconds instead of when object expires

override_estimated_total : int, optional

  • instead of getting number of systems that should see this question from result_info.estimated_total, use this number

force_passed_done_count : int, optional

  • when this number of systems have passed the right hand side of the question, consider the question complete
COMPLETE_PCT_DEFAULT = 99

default value for self.complete_pct

EXPIRATION_ATTR = 'expiration'

attribute of self.obj that contains the expiration for this object

EXPIRY_FALLBACK_SECS = 600

If the EXPIRATION_ATTR of obj can’t be automatically determined, then this is used as a fallback for timeout - polling will failed after this many seconds if completion not reached

OBJECT_TYPE

valid type of object that can be passed in as obj to __init__

alias of Question

OVERRIDE_TIMEOUT_SECS_DEFAULT = 0

default value for self.override_timeout_secs

POLLING_SECS_DEFAULT = 5

default value for self.polling_secs

STR_ATTRS = ['object_info', 'polling_secs', 'override_timeout_secs', 'complete_pct', 'expiration']

Class attributes to include in __str__ output

_debug_locals(fname, flocals)[source]

Method to print out locals for a function if self.DEBUG_METHOD_LOCALS is True

_derive_attribute(attr, fallback='', **kwargs)[source]

Derive an attributes value from self.obj

Will re-fetch self.obj if the attribute is not set

Parameters:

attr : string

string of attribute name to fetch from self.obj

fallback : string

value to fallback to if it still can’t be accessed after re-fetching the obj if fallback is None, an exception will be raised

Returns:

val : perspective

The value of the attr from self.obj

_derive_expiration(**kwargs)[source]

Derive the expiration datetime string from a object

Will generate a datetime string from self.EXPIRY_FALLBACK_SECS if unable to get the expiration from the object (self.obj) itself.

_derive_object_info(**kwargs)[source]

Derive self.object_info from self.obj

_post_init(**kwargs)[source]

Post init class setup

_refetch_obj(**kwargs)[source]

Utility method to re-fetch a object

This is used in the case that the obj supplied does not have all the metadata available

_stop = False

Controls whether a run() loop should stop or not

get_result_data(**kwargs)[source]

Simple utility wrapper around pytan.handler.Handler.get_result_data()

Returns:result_data : taniumpy.object_types.result_set.ResultSet
get_result_info(**kwargs)[source]

Simple utility wrapper around pytan.handler.Handler.get_result_info()

Parameters:

gri_retry_count : int, optional

  • default: 10
  • Number of times to re-try GetResultInfo when estimated_total comes back as 0
Returns:

result_info : taniumpy.object_types.result_info.ResultInfo

handler = None

The Handler object for this poller

obj = None

The object for this poller

passed_eq_est_total_loop(callbacks={}, **kwargs)[source]

Method to poll Result Info for self.obj until the percentage of ‘passed’ out of ‘estimated_total’ is greater than or equal to self.complete_pct

result_info = None

This will be updated with the ResultInfo object during run() calls

run(callbacks={}, **kwargs)[source]

Poll for question data and issue callbacks.

Parameters:

callbacks : dict

  • Callbacks should be a dict with any of these members:
    • ‘ProgressChanged’
    • ‘AnswersChanged’
    • ‘AnswersComplete’
  • Each callback should be a function that accepts:
    • ‘poller’: a poller instance
    • ‘pct’: a percent complete
    • ‘kwargs’: a dict of other args

gri_retry_count : int, optional

  • default: 10
  • Number of times to re-try GetResultInfo when estimated_total comes back as 0

Notes

  • Any callback can choose to get data from the session by calling poller.get_result_data() or new info by calling poller.get_result_info()
  • Any callback can choose to stop the poller by calling poller.stop()
  • Polling will be stopped only when one of the callbacks calls the stop() method or the answers are complete.
  • Any callback can call setPercentCompleteThreshold to change what “done” means on the fly
run_callback(callbacks, callback, pct, **kwargs)[source]

Utility method to find a callback in callbacks dict and run it

set_complect_pct(val)[source]

Set the complete_pct to a new value

Parameters:

val : int/float

float value representing the new percentage to consider self.obj complete

setup_logging()[source]

Setup loggers for this object

stop()[source]
class pytan.pollers.SSEPoller(handler, export_id, **kwargs)[source]

Bases: pytan.pollers.QuestionPoller

A class to poll the progress of a Server Side Export.

The primary function of this class is to poll for status of server side exports.

Parameters:

handler : pytan.handler.Handler

PyTan handler to use for GetResultInfo calls

export_id : str

  • ID of server side export

polling_secs : int, optional

  • default: 2
  • Number of seconds to wait in between status check loops

timeout_secs : int, optional

  • default: 600
  • timeout in seconds for waiting for status completion, 0 does not time out
POLLING_SECS_DEFAULT = 2

default value for self.polling_secs

STR_ATTRS = ['export_id', 'polling_secs', 'timeout_secs', 'sse_status']

Class attributes to include in __str__ output

TIMEOUT_SECS_DEFAULT = 600

default value for self.timeout_secs

_post_init(**kwargs)[source]

Post init class setup

export_id = None

The export_id for this poller

get_sse_data(**kwargs)[source]

Function to get the data of a server side export

Constructs a URL via: export/${export_id}.gz and performs an authenticated HTTP get

get_sse_status(**kwargs)[source]

Function to get the status of a server side export

Constructs a URL via: export/${export_id}.status and performs an authenticated HTTP get

run(**kwargs)[source]

Poll for server side export status

sse_status_has_completed_loop(**kwargs)[source]

Method to poll the status file for a server side export until it contains ‘Completed’

2.4. pytan.constants

PyTan Constants

This contains a number of constants that drive PyTan.

pytan.constants.DEBUG_FORMAT = '[%(lineno)-5d - %(filename)20s:%(funcName)s()] %(asctime)s\n%(levelname)-8s %(name)s %(message)s'

Logging format for debugformat=True

pytan.constants.EXPORT_MAPS = {'ResultSet': {'xml': [], 'json': [], 'csv': [{'valid_list_types': ['str', 'unicode'], 'key': 'header_sort', 'valid_types': [<type 'bool'>, <type 'list'>, <type 'tuple'>]}, {'valid_list_types': ['taniumpy.Sensor'], 'key': 'sensors', 'valid_types': [<type 'list'>, <type 'tuple'>]}, {'valid_list_types': [], 'key': 'header_add_sensor', 'valid_types': [<type 'bool'>]}, {'valid_list_types': [], 'key': 'header_add_type', 'valid_types': [<type 'bool'>]}, {'valid_list_types': [], 'key': 'expand_grouped_columns', 'valid_types': [<type 'bool'>]}]}, 'BaseType': {'xml': [{'valid_list_types': [], 'key': 'minimal', 'valid_types': [<type 'bool'>]}], 'json': [{'valid_list_types': [], 'key': 'include_type', 'valid_types': [<type 'bool'>]}, {'valid_list_types': [], 'key': 'explode_json_string_values', 'valid_types': [<type 'bool'>]}], 'csv': [{'valid_list_types': ['str', 'unicode'], 'key': 'header_sort', 'valid_types': [<type 'bool'>, <type 'list'>, <type 'tuple'>]}, {'valid_list_types': [], 'key': 'explode_json_string_values', 'valid_types': [<type 'bool'>]}]}}
Maps a given TaniumPy object to the list of supported export formats for each object type, and the valid optional arguments for each export format. Optional arguments construct:
  • key: the optional argument name itself
  • valid_types: the valid python types that are allowed to be passed as a value to key
  • valid_list_types: the valid python types in str format that are allowed to be passed in a list, if list is one of the valid_types
pytan.constants.FILTER_MAPS = [{'operator': 'Less', 'not_flag': 0, 'help': 'Filter for less than VALUE', 'human': ['<', 'less', 'lt', 'less than']}, {'operator': 'Less', 'not_flag': 1, 'help': 'Filter for not less than VALUE', 'human': ['!<', 'notless', 'not less', 'not less than']}, {'operator': 'LessEqual', 'not_flag': 0, 'help': 'Filter for less than or equal to VALUE', 'human': ['<=', 'less equal', 'lessequal', 'le']}, {'operator': 'LessEqual', 'not_flag': 1, 'help': 'Filter for not less than or equal to VALUE', 'human': ['!<=', 'not less equal', 'not lessequal']}, {'operator': 'Greater', 'not_flag': 0, 'help': 'Filter for greater than VALUE', 'human': ['>', 'greater', 'gt', 'greater than']}, {'operator': 'Greater', 'not_flag': 1, 'help': 'Filter for not greater than VALUE', 'human': ['!>', 'not greater', 'notgreater', 'not greater than']}, {'operator': 'GreaterEqual', 'not_flag': 0, 'help': 'Filter for greater than or equal to VALUE', 'human': ['=>', 'greater equal', 'greaterequal', 'ge']}, {'operator': 'GreaterEqual', 'not_flag': 1, 'help': 'Filter for not greater than VALUE', 'human': ['!=>', 'not greater equal', 'notgreaterequal']}, {'operator': 'Equal', 'not_flag': 0, 'help': 'Filter for equals to VALUE', 'human': ['=', 'equal', 'equals', 'eq']}, {'operator': 'Equal', 'not_flag': 1, 'help': 'Filter for not equals to VALUE', 'human': ['!=', 'not equal', 'notequal', 'not equals', 'notequals', 'ne']}, {'pre_value': '.*', 'not_flag': 0, 'help': 'Filter for contains VALUE (adds .* before and after VALUE)', 'post_value': '.*', 'human': ['contains'], 'operator': 'RegexMatch'}, {'pre_value': '.*', 'not_flag': 1, 'help': 'Filter for does not contain VALUE (adds .* before and after VALUE)', 'post_value': '.*', 'human': ['does not contain', 'doesnotcontain', 'not contains', 'notcontains'], 'operator': 'RegexMatch'}, {'operator': 'RegexMatch', 'not_flag': 0, 'post_value': '.*', 'human': ['starts with', 'startswith'], 'help': 'Filter for starts with VALUE (adds .* after VALUE)'}, {'operator': 'RegexMatch', 'not_flag': 1, 'post_value': '.*', 'human': ['does not start with', 'doesnotstartwith', 'not starts with', 'notstartswith'], 'help': 'Filter for does not start with VALUE (adds .* after VALUE)'}, {'operator': 'RegexMatch', 'pre_value': '.*', 'not_flag': 0, 'help': 'Filter for ends with VALUE (adds .* before VALUE)', 'human': ['ends with', 'endswith']}, {'operator': 'RegexMatch', 'pre_value': '.*', 'not_flag': 1, 'help': 'Filter for does bit end with VALUE (adds .* before VALUE)', 'human': ['does not end with', 'doesnotendwith', 'not ends with', 'notstartswith']}, {'operator': 'RegexMatch', 'not_flag': 1, 'help': 'Filter for non regular expression match for VALUE', 'human': ['is not', 'not regex', 'notregex', 'not regex match', 'notregexmatch', 'nre']}, {'operator': 'RegexMatch', 'not_flag': 0, 'help': 'Filter for regular expression match for VALUE', 'human': ['is', 'regex', 'regex match', 'regexmatch', 're']}]
Maps a given set of human strings into the various filter attributes used by the SOAP API. Also used to verify that a manually supplied filter via a definition is valid. Construct:
  • human: a list of human strings that can be used after ‘, that‘. Ex: ‘, that contains value
  • operator: the filter operator used by the SOAP API when building a filter that matches human
  • not_flag: the value to set on not_flag when building a filter that matches human
  • pre_value: the prefix to add to the value when building a filter
  • post_value: the postfix to add to the value when building a filter
pytan.constants.FILTER_RE = ',\\s*that'

The regex that is used to find filters in a string. Ex: Sensor1, that contains blah

pytan.constants.GET_OBJ_MAP = {'user': {'search': ['id'], 'all': 'UserList', 'manual': True, 'multi': None, 'single': 'User', 'create_json': True, 'delete': True}, 'whitelisted_url': {'search': [], 'all': 'WhiteListedUrlList', 'manual': True, 'multi': None, 'single': 'WhiteListedUrlList', 'create_json': True, 'delete': True}, 'saved_question': {'search': ['id', 'name'], 'all': 'SavedQuestionList', 'manual': True, 'multi': None, 'single': 'SavedQuestion', 'create_json': True, 'delete': True}, 'group': {'search': ['id', 'name'], 'all': 'GroupList', 'manual': True, 'multi': 'GroupList', 'single': 'Group', 'create_json': True, 'delete': True}, 'package': {'manual': True, 'single': 'PackageSpec', 'all': 'PackageSpec', 'search': ['id', 'name'], 'allfix': 'PackageSpecList', 'multi': None, 'create_json': True, 'delete': True}, 'question': {'search': ['id'], 'all': 'QuestionList', 'manual': False, 'multi': None, 'single': 'Question', 'create_json': True, 'delete': False}, 'client': {'search': [], 'all': 'ClientStatus', 'manual': True, 'multi': None, 'single': None, 'create_json': False, 'delete': False}, 'saved_action': {'search': ['id', 'name'], 'all': 'SavedActionList', 'manual': True, 'multi': 'SavedActionList', 'single': 'SavedAction', 'create_json': False, 'delete': False}, 'action': {'search': ['id'], 'all': 'ActionList', 'manual': False, 'multi': None, 'single': 'Action', 'create_json': True, 'delete': False}, 'sensor': {'search': ['id', 'name', 'hash'], 'all': 'SensorList', 'manual': False, 'multi': 'SensorList', 'single': 'Sensor', 'create_json': True, 'delete': True}, 'setting': {'search': ['id', 'name'], 'all': 'SystemSettingList', 'manual': True, 'multi': 'SystemSettingList', 'single': 'SystemSetting', 'create_json': False, 'delete': False}, 'userrole': {'search': [], 'all': 'UserRoleList', 'manual': True, 'multi': None, 'single': None, 'create_json': False, 'delete': False}}
Maps an object type from a human friendly string into various aspects:
  • single: The TaniumPy object used to find singular instances of this object type
  • multi: The TaniumPy object used to find multiple instances of this object type
  • all: The TaniumPy object used to find all instances of this object type
  • search: The list of attributes that can be used with the Tanium SOAP API for searches
  • manual: Whether or not this object type is allowed to do a manual search, that is – allow the user to specify an attribute that is not in search, which will get ALL objects of that type then search for a match based on attribute values for EVERY key/value pair supplied
  • delete: Whether or not this object type can be deleted
  • create_json: Whether or not this object type can be created by importing from JSON
pytan.constants.HANDLER_ARG_DEFAULTS = {'username': None, 'gmt_log': False, 'host': None, 'debugformat': False, 'loglevel': 0, 'password': None, 'port': 443, 'session_id': None}

Map of handler arguments and their defaults

pytan.constants.INFO_FORMAT = '%(asctime)s %(levelname)-8s %(name)s: %(message)s'

Logging format for debugformat=False

pytan.constants.LOG_LEVEL_MAPS = [(0, {'method_debug': 'DEBUG', 'stats': 'DEBUG'}, 'Sets all loggers to only output at WARNING or above except for stats & method_debug'), (1, {'pytan.pollers.ActionPoller': 'INFO', 'pytan.pollers.SSEPoller': 'INFO', 'pytan.pollers.QuestionPoller': 'INFO', 'pytan': 'INFO'}, 'Pytan poller loggers show output at INFO or above'), (2, {'pytan.pollers.ActionPoller': 'DEBUG', 'pytan.pollers.SSEPoller': 'DEBUG', 'pytan.pollers.ActionPoller.progress': 'INFO', 'pytan.pollers.QuestionPoller': 'DEBUG', 'pytan.handler': 'INFO', 'pytan.pollers.QuestionPoller.progress': 'INFO', 'pytan.pollers.SSEPoller.progress': 'INFO', 'pytan': 'DEBUG'}, 'Pytan handler logger show output at INFO or above, poller logs at DEBUG or above, and poller progress logs at INFO or above'), (3, {'pytan.handler': 'DEBUG', 'pytan.pollers.QuestionPoller.resolver': 'INFO', 'pytan.pollers.QuestionPoller.progress': 'DEBUG', 'pytan.pollers.ActionPoller.resolver': 'INFO', 'pytan.pollers.SSEPoller.resolver': 'INFO', 'pytan.pollers.ActionPoller.progress': 'DEBUG', 'pytan.pollers.SSEPoller.progress': 'DEBUG'}, 'Pytan handler logger show output at DEBUG or above, poller progress at DEBUG or above, and poller resolver at INFO or above'), (4, {'pytan.pollers.ActionPoller.resolver': 'DEBUG', 'pytan.pollers.SSEPoller.resolver': 'DEBUG', 'pytan.pollers.QuestionPoller.resolver': 'DEBUG', 'pytan.handler.ask_manual': 'DEBUG'}, 'Pytan ask manual logger show output at DEBUG or above and poller resolver at DEBUG or above'), (5, {'pytan.handler.ask_manual_human': 'DEBUG'}, 'Pytan ask manual human logger show output at DEBUG or above'), (6, {'pytan.handler.timing': 'DEBUG', 'XMLCleaner': 'DEBUG'}, 'Pytan timing and XMLCleaner loggers show output at DEBUG or above'), (7, {'pytan.sessions.Session': 'DEBUG'}, 'Taniumpy session loggers show output at DEBUG or above'), (8, {'pytan.sessions.Session.auth': 'DEBUG'}, 'PyTan session authentication loggers show output at DEBUG or above'), (9, {'pytan.sessions.Session.http': 'DEBUG'}, 'PyTan session http loggers show output at DEBUG or above'), (10, {'pytan.handler.prettybody': 'DEBUG'}, 'Pytan handler pretty XML body loggers show output at DEBUG or above'), (11, {'pytan.sessions.Session.http.body': 'DEBUG'}, 'PyTan session raw XML body loggers show output at DEBUG or above'), (12, {'requests': 'DEBUG', 'requests.packages.urllib3.util.retry': 'DEBUG', 'requests.packages.urllib3.poolmanager': 'DEBUG', 'requests.packages.urllib3.connectionpool': 'DEBUG', 'requests.packages.urllib3': 'DEBUG'}, 'Requests package show logging at DEBUG or above')]
Map for loglevel(int) -> logger -> logger level(logging.INFO|WARN|DEBUG|...). Higher loglevels will include all levels up to and including that level. Contains a list of tuples, each tuple consisting of:
  • int, loglevel
  • dict, {{logger_name: logger_level}} for this loglevel
  • str, description of this loglevel
pytan.constants.OPTION_MAPS = [{'destination': 'filter', 'help': 'Make the filter do a case insensitive match', 'attrs': {'ignore_case_flag': 1}, 'human': 'ignore_case', 'valid_type': <type 'int'>}, {'destination': 'filter', 'help': 'Make the filter do a case sensitive match', 'attrs': {'ignore_case_flag': 0}, 'human': 'match_case', 'valid_type': <type 'int'>}, {'destination': 'filter', 'help': 'Make the filter match any value', 'attrs': {'all_values_flag': 0, 'all_times_flag': 0}, 'human': 'match_any_value', 'valid_type': <type 'int'>}, {'destination': 'filter', 'help': 'Make the filter match all values', 'attrs': {'all_values_flag': 1, 'all_times_flag': 1}, 'human': 'match_all_values', 'valid_type': <type 'int'>}, {'help': 'Re-fetch cached values older than N seconds', 'destination': 'filter', 'valid_type': <type 'int'>, 'human': 'max_data_age', 'human_type': 'seconds', 'attr': 'max_age_seconds'}, {'attr': 'value_type', 'destination': 'filter', 'valid_type': <type 'str'>, 'valid_values': 'pytan.constants.SENSOR_TYPE_MAP.values()', 'human': 'value_type', 'human_type': 'value_type', 'help': 'Make the filter consider the value type as VALUE_TYPE'}, {'destination': 'group', 'help': "Use 'and' for all of the filters supplied", 'attrs': {'and_flag': 1}, 'human': 'and', 'valid_type': <type 'int'>}, {'destination': 'group', 'help': "Use 'or' for all of the filters supplied", 'attrs': {'and_flag': 0}, 'human': 'or', 'valid_type': <type 'int'>}]
Maps a given human string into the various options for filters used by the SOAP API. Also used to verify that a manually supplied option via a definition is valid. Construct:
  • human: the human string that can be used after ‘opt:‘. Ex: ‘opt:value_type:value
  • destination: the type of object this option can be applied to (filter or group)
  • attrs: the attributes and their values used by the SOAP API when building a filter with an option that matches human
  • attr: the attribute used by the SOAP API when building a filter with an option that matches human. value is pulled from after a : when only attr exists for an option map, and not attrs.
  • valid_values: if supplied, the list of valid values for this option
  • valid_type: performs type checking on the value supplied to verify it is correct
  • human_type: the human string for the value type if the option requires a value
pytan.constants.OPTION_RE = ',\\s*opt:'

The regex that is used to find options in a string. Ex: Sensor1, that contains blah, opt:ignore_case, opt:max_data_age:3600

pytan.constants.PARAM_DELIM = '||'

The string to surround a parameter with when passing parameters to the SOAP API for a sensor in a question. Ex: ||parameter_key||

pytan.constants.PARAM_KEY_SPLIT = '='

The string that is used to split parameter key from parameter value. Ex: key1=value1

pytan.constants.PARAM_RE = '(?<!\\\\)\\{(.*?)(?<!\\\\)\\}'

The regex that is used to parse parameters from a human string. Ex: ala {key1=value1}

pytan.constants.PARAM_SPLIT_RE = '(?<!\\\\),'

The regex that is used to split multiple parameters. Ex: key1=value1, key2=value2

pytan.constants.PYTAN_KEY = 'mT1er@iUa1kP9pelSW'

Key used for obfuscation/de-obfsucation

pytan.constants.PYTAN_USER_CONFIG = '~/.pytan_config.json'

Default path to file to use for Handler parameter overrides

pytan.constants.Q_OBJ_MAP = {'manual': {'handler': 'ask_manual'}, 'saved': {'handler': 'ask_saved'}, 'parsed': {'handler': 'ask_parsed'}, '_manual': {'handler': '_ask_manual'}}

Maps a question type from a human friendly string into the handler method that supports each type

pytan.constants.REQ_KWARGS = ['hide_errors_flag', 'include_answer_times_flag', 'row_counts_only_flag', 'aggregate_over_time_flag', 'most_recent_flag', 'include_hashes_flag', 'hide_no_results_flag', 'use_user_context_flag', 'script_data', 'return_lists_flag', 'return_cdata_flag', 'pct_done_limit', 'context_id', 'sample_frequency', 'sample_start', 'sample_count', 'suppress_scripts', 'suppress_object_list', 'row_start', 'row_count', 'sort_order', 'filter_string', 'filter_not_flag', 'recent_result_buckets', 'cache_id', 'cache_expiration', 'cache_sort_fields', 'include_user_details', 'include_hidden_flag', 'use_error_objects', 'use_json', 'json_pretty_print', 'cache_filters']

A list of arguments that will be pulled from any respective kwargs for most calls to taniumpy.session.Session

pytan.constants.SELECTORS = ['id', 'name', 'hash']

The search selectors that can be extracted from a string. Ex: name:Sensor1, or id:1, or hash:1111111

pytan.constants.SENSOR_TYPE_MAP = {0: 'Hash', 1: 'String', 2: 'Version', 3: 'NumericDecimal', 4: 'BESDate', 5: 'IPAddress', 6: 'WMIDate', 7: 'TimeDiff', 8: 'DataSize', 9: 'NumericInteger', 10: 'VariousDate', 11: 'RegexMatch', 12: 'LastOperatorType'}

Maps a Result type from the Tanium SOAP API from an int to a string

pytan.constants.SSE_CRASH_MAP = ['6.5.314.4300']

Mapping of versions to watch out for crashes/handle bugs for server side export

pytan.constants.SSE_FORMAT_MAP = [('csv', '0', 0), ('xml', '1', 1), ('xml_obj', '1', 1), ('cef', '2', 2)]

Mapping of human friendly strings to API integers for server side export

pytan.constants.SSE_RESTRICT_MAP = {1: ['6.5.314.4300'], 2: ['6.5.314.4300']}

Mapping of API integers for server side export format to version support

pytan.constants.TIME_FORMAT = '%Y-%m-%dT%H:%M:%S'

Tanium’s format for date time strings

2.5. pytan.utils

Collection of classes and methods used throughout pytan

class pytan.utils.SplitStreamHandler[source]

Bases: logging.Handler

Custom logging.Handler class that sends all messages that are logging.INFO and below to STDOUT, and all messages that are logging.WARNING and above to STDERR

emit(record)[source]
pytan.utils.apply_options_obj(options, obj, dest)[source]

Updates an object with options

Parameters:

options : dict

  • dict containing options definition

obj : taniumpy.object_types.base.BaseType

  • TaniumPy object to apply options to

dest : list of str

  • list of valid destinations (i.e. filter or group)
Returns:

obj : taniumpy.object_types.base.BaseType

  • TaniumPy object updated with attributes from options
pytan.utils.build_group_obj(q_filter_defs, q_option_defs)[source]

Creates a Group object from q_filter_defs and q_option_defs

Parameters:

q_filter_defs : list of dict

  • List of dict that are question filter definitions

q_option_defs : dict

  • dict of question filter options
Returns:

group_obj : taniumpy.object_types.group.Group

pytan.utils.build_manual_q(selectlist_obj, group_obj)[source]

Creates a Question object from selectlist_obj and group_obj

Parameters:

selectlist_obj : taniumpy.object_types.select_list.SelectList

  • SelectList object to add to Question object

group_obj : taniumpy.object_types.group.Group

  • Group object to add to Question object
Returns:

add_q_obj : taniumpy.object_types.question.Question

  • Question object built from selectlist_obj and group_obj
pytan.utils.build_metadatalist_obj(properties, nameprefix='')[source]

Creates a MetadataList object from properties

Parameters:

properties : list of list of strs

  • list of lists, each list having two strs - str 1: property key, str2: property value

nameprefix : str

  • prefix to insert in front of property key when creating MetadataItem
Returns:

metadatalist_obj : taniumpy.object_types.metadata_list.MetadataList

pytan.utils.build_param_obj(key, val, delim='')[source]

Creates a Parameter object from key and value, surrounding key with delim

Parameters:

key : str

  • key to use for parameter

value : str

  • value to use for parameter

delim : str

  • str to surround key with when adding to parameter object
Returns:

param_obj : taniumpy.object_types.parameter.Parameter

  • Parameter object built from key and val
pytan.utils.build_param_objlist(obj, user_params, delim='', derive_def=False, empty_ok=False)[source]

Creates a ParameterList object from user_params

Parameters:

obj : taniumpy.object_types.base.BaseType

  • TaniumPy object to verify parameters against

user_params : dict

  • dict describing key and value of user supplied params

delim : str

  • str to surround key with when adding to parameter object

derive_def : bool, optional

  • False: Do not derive default values, and throw a pytan.exceptions.HandlerError if user did not supply a value for a given parameter
  • True: Try to derive a default value for each parameter if user did not supply one

empty_ok : bool, optional

  • False: If user did not supply a value for a given parameter, throw a pytan.exceptions.HandlerError
  • True: If user did not supply a value for a given parameter, do not add the parameter to the ParameterList object
Returns:

param_objlist : taniumpy.object_types.parameter_list.ParameterList

ParameterList object with list of taniumpy.object_types.parameter.Parameter built from user_params

pytan.utils.build_selectlist_obj(sensor_defs)[source]

Creates a SelectList object from sensor_defs

Parameters:

sensor_defs : list of dict

  • List of dict that are sensor definitions
Returns:

select_objlist : taniumpy.object_types.select_list.SelectList

pytan.utils.calc_percent(percent, whole)[source]

Utility method for getting percentage of whole

Parameters:

percent: int, float

whole: int, float

Returns:

int : the percentage of whole

pytan.utils.calculate_question_start_time(q)[source]

Caclulates the start time of a question by doing q.expiration - q.expire_seconds

Parameters:

q : taniumpy.object_types.question.Question

  • Question object to calculate start time for
Returns:

tuple : str, datetime

  • a tuple containing the start time first in str format for Tanium Server API, second in datetime object format
pytan.utils.change_console_format(debug=False)[source]

Changes the logging format for console handler to pytan.constants.DEBUG_FORMAT or pytan.constants.INFO_FORMAT

Parameters:

debug : bool, optional

pytan.utils.check_dictkey(d, key, valid_types, valid_list_types)[source]

Yet another method to check a dictionary for a key

Parameters:

d : dict

  • dictionary to check for key

key : str

  • key to check for in d

valid_types : list of str

  • list of str of valid types for key

valid_list_types : list of str

  • if key is a list, validate that all values of list are in valid_list_types
pytan.utils.check_for_help(kwargs)[source]

Utility method to check for any help arguments and raise a PytanHelp exception with the appropriate help

Parameters:

kwargs : dict

  • dict of keyword args
pytan.utils.chk_def_key(def_dict, key, keytypes, keysubtypes=None, req=False)[source]

Checks that def_dict has key

Parameters:

def_dict : dict

  • Definition dictionary

key : str

  • key to check for in def_dict

keytypes : list of str

  • list of str of valid types for key

keysubtypes : list of str

  • if key is a dict or list, validate that all values of dict or list are in keysubtypes

req : bool

pytan.utils.clean_kwargs(kwargs, keys=None)[source]

Removes each key from kwargs dict if found

Parameters:

kwargs : dict

  • dict of keyword args

keys : list of str, optional

  • default: [‘obj’, ‘pytan_help’, ‘objtype’]
  • list of strs of keys to remove from kwargs
Returns:

clean_kwargs : dict

  • the new dict of kwargs with keys removed
pytan.utils.copy_obj(obj, skip_attrs=None)[source]

Returns a new class of obj with with out any attributes in skip_attrs specified

Parameters:

obj : taniumpy.object_types.base.BaseType

  • Object to copy

skip_attrs : list of str

  • default: None
  • list of attribute str’s to skip copying over to new object, will default to [] if None
Returns:

new_obj : taniumpy.object_types.base.BaseType

  • Copied object with attributes in skip_attrs skipped
pytan.utils.copy_package_obj_for_action(obj, skip_attrs=None)[source]

Returns a new class of package obj with with out any attributes in skip_attrs specified

Parameters:

obj : taniumpy.object_types.base.BaseType

  • Object to copy

skip_attrs : list of str

  • default: None
  • list of attribute str’s to skip copying over to new object, default if None: [‘id’, ‘deleted_flag’, ‘available_time’, ‘creation_time’, ‘modification_time’, ‘source_id’]
Returns:

new_obj : taniumpy.object_types.base.BaseType

  • Copied object with attributes in skip_attrs skipped
pytan.utils.datetime_to_timestr(dt)[source]

Get a timestr for dt

Parameters:

dt : datetime.datetime

  • datetime object
Returns:

timestr: str

  • the timestr for dt in taniums format
pytan.utils.dehumanize_package(package)[source]

Turns a package str into a package definition

Parameters:

package : str

  • A str that describes a package and optionally a selector and/or parameters
Returns:

package_def : dict

  • dict parsed from sensors
pytan.utils.dehumanize_question_filters(question_filters)[source]

Turns a question_filters str or list of str into a question filter definition

Parameters:

question_filters : str, list of str

  • A str or list of str that describes a sensor for a question filter(s) and optionally a selector and/or filter
Returns:

question_filter_defs : list of dict

  • list of dict parsed from question_filters
pytan.utils.dehumanize_question_options(question_options)[source]

Turns a question_options str or list of str into a question option definition

Parameters:

question_options : str, list of str

  • A str or list of str that describes question options
Returns:

question_option_defs : list of dict

  • list of dict parsed from question_options
pytan.utils.dehumanize_sensors(sensors, key='sensors', empty_ok=True)[source]

Turns a sensors str or list of str into a sensor definition

Parameters:

sensors : str, list of str

  • A str or list of str that describes a sensor(s) and optionally a selector, parameters, filter, and/or options

key : str, optional

  • Name of key that user should have provided sensors as

empty_ok : bool, optional

Returns:

sensor_defs : list of dict

  • list of dict parsed from sensors
pytan.utils.derive_param_default(obj_param)[source]

Derive a parameter default

Parameters:

obj_param : dict

  • parameter dict from TaniumPy object
Returns:

def_val : str

  • default value derived from obj_param
pytan.utils.empty_obj(taniumpy_object)[source]

Validate that a given TaniumPy object is not empty

Parameters:

taniumpy_object : taniumpy.object_types.base.BaseType

  • object to check if empty
Returns:

bool

  • True if taniumpy_object is considered empty, False otherwise
pytan.utils.eval_timing(c)[source]

Yet another method to time things – c will be evaluated and timing information will be printed out

pytan.utils.extract_filter(s)[source]

Extracts a filter from str s

Parameters:

s : str

  • A str that may or may not have a filter identified by ‘, that HUMAN VALUE’
Returns:

s : str

  • str s without the parsed_filter included

parsed_filter : dict

  • filter attributes mapped from filter from s if any found
pytan.utils.extract_options(s)[source]

Extracts options from str s

Parameters:

s : str

  • A str that may or may not have options identified by ‘, opt:name[:value]’
Returns:

s : str

  • str s without the parsed_options included

parsed_options : list

  • options extracted from s if any found
pytan.utils.extract_params(s)[source]

Extracts parameters from str s

Parameters:

s : str

  • A str that may or may not have parameters identified by {key=value}
Returns:

s : str

  • str s without the parsed_params included

parsed_params : list

  • parameters extracted from s if any found
pytan.utils.extract_selector(s)[source]

Extracts a selector from str s

Parameters:

s : str

  • A str that may or may not have a selector in the beginning in the form of id:, name:, or :hash – if no selector found, name will be assumed as the default selector
Returns:

s : str

  • str s without the parsed_selector included

parsed_selector : str

  • selector extracted from s, or ‘name’ if none found
pytan.utils.func_timing(f)[source]

Decorator to add timing information around a function

pytan.utils.get_all_loggers()[source]

Gets all loggers currently known to pythons logging system`

pytan.utils.get_all_pytan_loggers()[source]

Gets all loggers currently known to pythons logging system that exist in pytan.constants.LOG_LEVEL_MAPS

Creates loggers for any pytan loggers that do not exist yet

pytan.utils.get_dict_list_len(d, keys=[], negate=False)[source]

Gets the sum of each list in dict d

Parameters:

d : dict of str

  • dict to sums of

keys : list of str

  • list of keys to get sums of, if empty gets a sum of all keys

negate : bool

  • only used if keys supplied
  • False : get the sums of d that do match keys
  • True : get the sums of d that do not match keys
Returns:

list_len : int

  • sum of lists in d that match keys
pytan.utils.get_filter_obj(sensor_def)[source]

Creates a Filter object from sensor_def

Parameters:

sensor_def : dict

  • dict containing sensor definition
Returns:

filter_obj : taniumpy.object_types.filter.Filter

  • Filter object created from sensor_def
pytan.utils.get_kwargs_int(key, default=None, **kwargs)[source]

Gets key from kwargs and validates it is an int

Parameters:

key : str

  • key to get from kwargs

default : int, optional

  • default value to use if key not found in kwargs

kwargs : dict

  • kwargs to get key from
Returns:

val : int

value from key, or default if supplied

pytan.utils.get_now()[source]

Get current time in human friendly format

Returns:

str :

str of current time return from human_time()

pytan.utils.get_obj_map(objtype)[source]

Gets an object map for objtype

Parameters:

objtype : str

Returns:

obj_map : dict

pytan.utils.get_obj_params(obj)[source]

Get the parameters from a TaniumPy object and JSON load them

obj : taniumpy.object_types.base.BaseType
  • TaniumPy object to get parameters from
Returns:

params : dict

  • JSON loaded dict of parameters from obj
pytan.utils.get_percentage(part, whole)[source]

Utility method for getting percentage of part out of whole

Parameters:

part: int, float

whole: int, float

Returns:

int : the percentage of part out of whole

pytan.utils.get_q_obj_map(qtype)[source]

Gets an object map for qtype

Parameters:

qtype : str

Returns:

obj_map : dict

pytan.utils.get_taniumpy_obj(obj_map)[source]

Gets a taniumpy object from obj_map

Parameters:

obj_map : str

  • str of taniumpy object to fetch
Returns:

obj : taniumpy.object_types.base.BaseType

  • matching taniumpy object for obj_map
pytan.utils.human_time(t, tformat='%Y_%m_%d-%H_%M_%S-%Z')[source]

Get time in human friendly format

Parameters:

t : int, float, time

  • either a unix epoch or struct_time object to convert to string

tformat : str, optional

  • format of string to convert time to
Returns:

str :

  • t converted to str
pytan.utils.is_dict(l)[source]

returns True if l is a dictionary, False if not

pytan.utils.is_list(l)[source]

returns True if l is a list, False if not

pytan.utils.is_num(l)[source]

returns True if l is a number, False if not

pytan.utils.is_str(l)[source]

returns True if l is a string, False if not

pytan.utils.jsonify(v, indent=2, sort_keys=True)[source]

Turns python object v into a pretty printed JSON string

Parameters:

v : object

  • python object to convert to JSON

indent : int, 2

  • number of spaces to indent JSON string when pretty printing

sort_keys : bool, True

  • sort keys of JSON string when pretty printing
Returns:

str :

  • JSON pretty printed string
pytan.utils.load_param_json_file(parameters_json_file)[source]

Opens a json file and sanity checks it for use as a parameters element for a taniumpy object

Parameters:

parameters_json_file : str

  • path to JSON file that describes an API object
Returns:

obj

  • contents of parameters_json_file de-serialized
pytan.utils.load_taniumpy_from_json(json_file)[source]

Opens a json file and parses it into an taniumpy object

Parameters:

json_file : str

  • path to JSON file that describes an API object
Returns:

obj : taniumpy.object_types.base.BaseType

  • TaniumPy object converted from json file
pytan.utils.log_session_communication(h)[source]

Uses xml_pretty() to pretty print the last request and response bodies from the session object in h to the logging system

Parameters:

h : Handler object

  • Handler object with session object containing last request and response body
pytan.utils.map_filter(filter_str)[source]

Maps a filter str against constants.FILTER_MAPS

Parameters:

filter_str : str

  • filter_str str that should be validated
Returns:

filter_attrs : dict

  • dict containing mapped filter attributes for SOAP API
pytan.utils.map_option(opt, dest)[source]

Maps an opt str against constants.OPTION_MAPS

Parameters:

opt : str

  • option str that should be validated

dest : list of str

  • list of valid destinations (i.e. filter or group)
Returns:

opt_attrs : dict

  • dict containing mapped option attributes for SOAP API
pytan.utils.map_options(options, dest)[source]

Maps a list of options using map_option()

Parameters:

options : list of str

  • list of str that should be validated

dest : list of str

  • list of valid destinations (i.e. filter or group)
Returns:

mapped_options : dict

  • dict of all mapped_options
pytan.utils.parse_defs(defname, deftypes, strconv=None, empty_ok=True, defs=None, **kwargs)[source]

Parses and validates defs into new_defs

Parameters:

defname : str

  • Name of definition

deftypes : list of str

  • list of valid types that defs can be

strconv : str

  • if supplied, and defs is a str, turn defs into a dict with key = strconv, value = defs

empty_ok : bool

  • True: defs is allowed to be empty
  • False: defs is not allowed to be empty
Returns:

new_defs : list of dict

  • parsed and validated defs
pytan.utils.parse_versioning(server_version)[source]

Parses server_version into a dictionary

Parameters:

server_version : str

  • str of server version
Returns:

dict

  • dict of parsed tanium server version containing keys: major, minor, revision, and build
pytan.utils.plugin_zip(p)[source]

Maps columns to values for each row in a plugins sql_response and returns a list of dicts

Parameters:

p : taniumpy.object_types.plugin.Plugin

  • plugin object
Returns:

dict

  • the columns and result_rows of the sql_response in Plugin object zipped up into a dictionary
pytan.utils.port_check(address, port, timeout=5)[source]

Check if address:port can be reached within timeout

Parameters:

address : str

  • hostname/ip address to check port on

port : int

  • port to check on address

timeout : int, optional

  • timeout after N seconds of not being able to connect
Returns:

socket or False :

  • if connection succeeds, the socket object is returned, else False is returned
pytan.utils.print_log_levels()[source]

Prints info about each loglevel from pytan.constants.LOG_LEVEL_MAPS

pytan.utils.remove_logging_handler(name='all')[source]

Removes a logging handler

Parameters:

name : str

  • name of logging handler to remove. if name == ‘all’ then all logging handlers are removed
pytan.utils.seconds_from_now(secs=0, tz='utc')[source]

Get time in Tanium SOAP API format secs from now

Parameters:

secs : int

  • seconds from now to get time str

tz : str, optional

  • time zone to return string in, default is ‘utc’ - supplying anything else will supply local time
Returns:

str :

  • time secs from now in Tanium SOAP API format
pytan.utils.set_all_loglevels(level='DEBUG')[source]

Sets all loggers that the logging system knows about to a given logger level

pytan.utils.set_log_levels(loglevel=0)[source]

Enables loggers based on loglevel and pytan.constants.LOG_LEVEL_MAPS

Parameters:

loglevel : int, optional

  • loglevel to match against each item in pytan.constants.LOG_LEVEL_MAPS - each item that is greater than or equal to loglevel will have the according loggers set to their respective levels identified there-in.
pytan.utils.setup_console_logging(gmt_tz=True)[source]

Creates a console logging handler using logging.StreamHandler(sys.stdout)

pytan.utils.shrink_obj(obj, attrs=None)[source]

Returns a new class of obj with only id/name/hash defined

Parameters:

obj : taniumpy.object_types.base.BaseType

  • Object to shrink

attrs : list of str

  • default: None
  • list of attribute str’s to copy over to new object, will default to [‘name’, ‘id’, ‘hash’] if None
Returns:

new_obj : taniumpy.object_types.base.BaseType

  • Shrunken object
pytan.utils.spew(t)[source]

Prints a string based on DEBUG_OUTPUT bool

Parameters:

t : str

  • string to debug print
pytan.utils.test_app_port(host, port)[source]

Validates that host:port can be reached using port_check()

Parameters:

host : str

  • hostname/ip address to check port on

port : int

  • port to check on host
Raises:

pytan.exceptions.HandlerError : pytan.exceptions.HandlerError

  • if host:port can not be reached
pytan.utils.timestr_to_datetime(timestr)[source]

Get a datetime.datetime object for timestr

Parameters:

timestr : str

  • date & time in taniums format
Returns:

datetime.datetime

  • the datetime object for the timestr
pytan.utils.val_package_def(package_def)[source]

Validates package definitions

Ensures package definition has a selector, and if a package definition has a params key, that key is valid

Parameters:

package_def : dict

  • package definition
pytan.utils.val_q_filter_defs(q_filter_defs)[source]

Validates question filter definitions

Ensures each question filter definition has a selector, and if a question filter definition has a filter key, that key is valid

Parameters:

q_filter_defs : list of dict

  • list of question filter definitions
pytan.utils.val_sensor_defs(sensor_defs)[source]

Validates sensor definitions

Ensures each sensor definition has a selector, and if a sensor definition has a params, options, or filter key, that each key is valid

Parameters:

sensor_defs : list of dict

  • list of sensor definitions
pytan.utils.vig_decode(key, string)[source]

De-obfuscates a string with a key using Vigenere cipher.

Only useful for obfuscation, not real security!!

Parameters:

key : str

  • key that string is scrambled with

string : str

  • string to unscramble with key
Returns:

decoded_string : str

  • decoded string

Notes

This will only work with strings that have been encoded with vig_encode(). “normal” strings will be returned as-is.

pytan.utils.vig_encode(key, string)[source]

Obfuscates a string with a key using Vigenere cipher.

Only useful for obfuscation, not real security!!

Parameters:

key : str

  • key to scrambled string with

string : str

  • string to scramble with key
Returns:

encoded_string : str

  • encoded string
pytan.utils.xml_pretty(x, pretty=True, indent=' ', **kwargs)[source]

Uses xmltodict to pretty print an XML str x

Parameters:

x : str

  • XML string to pretty print
Returns:

str :

  • The pretty printed string of x
pytan.utils.xml_pretty_resultobj(x)[source]

Uses xmltodict to pretty print an the result-object element in XML str x

Parameters:

x : str

  • XML string to pretty print
Returns:

str :

  • The pretty printed string of result-object in x
pytan.utils.xml_pretty_resultxml(x)[source]

Uses xmltodict to pretty print an the ResultXML element in XML str x

Parameters:

x : str

  • XML string to pretty print
Returns:

str :

  • The pretty printed string of ResultXML in x

2.6. pytan.binsupport

Collection of classes and methods used throughout pytan for command line support

class pytan.binsupport.CustomArgFormat(prog, indent_increment=2, max_help_position=24, width=None)[source]

Bases: argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter

Multiple inheritance Formatter class for argparse.ArgumentParser.

If a argparse.ArgumentParser class uses this as it’s Formatter class, it will show the defaults for each argument in the help output

class pytan.binsupport.CustomArgParse(*args, **kwargs)[source]

Bases: argparse.ArgumentParser

Custom argparse.ArgumentParser class which does a number of things:

  • Uses pytan.utils.CustomArgFormat as it’s Formatter class, if none was passed in
  • Prints help if there is an error
  • Prints the help for any subparsers that exist
error(message)[source]
print_help(**kwargs)[source]
class pytan.binsupport.HistoryConsole(locals=None, filename='<console>', histfile='/Users/jolsen/.console-history', **kwargs)[source]

Bases: code.InteractiveConsole

Class that provides an interactive python console with full auto complete, history, and history file support.

Examples

>>> HistoryConsole()
import_readline()[source]
read_history(histfile)[source]
setup_atexit_write_history(histfile)[source]
setup_autocomplete()[source]
write_history(histfile)[source]
pytan.binsupport.add_ask_report_argparser(parser)[source]

Method to extend a pytan.utils.CustomArgParse class for command line scripts with arguments for scripts that need to supply export format subparsers for asking questions.

pytan.binsupport.add_file_log(logfile, debug=False)[source]

Utility to add a log file from python’s logging module

pytan.binsupport.add_get_object_report_argparser(parser)[source]

Method to extend a pytan.utils.CustomArgParse class for command line scripts with arguments for scripts that need to supply export format subparsers for getting objects.

pytan.binsupport.add_report_file_options(parser)[source]

Method to extend a pytan.utils.CustomArgParse class for command line scripts with arguments for scripts that need to supply export file and directory options.

pytan.binsupport.csvdictwriter(rows_list, **kwargs)[source]

returns the rows_list (list of dicts) as a CSV string

pytan.binsupport.debug_list(debuglist)[source]

Utility function to print the variables for a list of objects

pytan.binsupport.debug_obj(debugobj)[source]

Utility function to print the variables for an object

pytan.binsupport.filter_filename(filename)[source]

Utility to filter a string into a valid filename

pytan.binsupport.filter_sensors(sensors, filter_platforms=[], filter_categories=[])[source]

Utility to filter a list of sensors for specific platforms and/or categories

pytan.binsupport.filter_sourced_sensors(sensors)[source]

Utility to filter out all sensors that have a source_id specified (i.e. they are temp sensors created by the API)

pytan.binsupport.get_all_headers(rows_list)[source]

Utility to get all the keys for a list of dicts

pytan.binsupport.get_grp_opts(parser, grp_names)[source]

Used to get arguments in parser that match argument group names in grp_names

Parameters:

parser : argparse.ArgParse

  • ArgParse object

grp_names : list of str

  • list of str of argument group names to get arguments for
Returns:

grp_opts : list of str

  • list of arguments gathered from argument group names in grp_names
pytan.binsupport.input_prompts(args)[source]

Utility function to prompt for username, password, and host if empty

pytan.binsupport.introspect(obj, depth=0)[source]

Utility function to dump all info about an object

pytan.binsupport.parse_sensor_platforms(sensor)[source]

Utility to create a list of platforms for a given sensor

pytan.binsupport.print_obj(d, indent=0)[source]

Pretty print a dictionary

pytan.binsupport.process_approve_saved_action_args(parser, handler, args)[source]

Process command line args supplied by user for approving a saved action

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args

  • args object from parsing parser
Returns:

approve_action

pytan.binsupport.process_ask_manual_args(parser, handler, args)[source]

Process command line args supplied by user for ask manual

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
Returns:

response

pytan.binsupport.process_ask_parsed_args(parser, handler, args)[source]

Process command line args supplied by user for ask parsed

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
Returns:

response

pytan.binsupport.process_ask_saved_args(parser, handler, args)[source]

Process command line args supplied by user for ask saved

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
Returns:

response

pytan.binsupport.process_create_group_args(parser, handler, args)[source]

Process command line args supplied by user for create group object

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
Returns:

response : taniumpy.object_types.base.BaseType

pytan.binsupport.process_create_json_object_args(parser, handler, obj, args)[source]

Process command line args supplied by user for create json object

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

obj : str

  • Object type for create json object

args : args object

  • args parsed from parser
Returns:

response : taniumpy.object_types.base.BaseType

pytan.binsupport.process_create_package_args(parser, handler, args)[source]

Process command line args supplied by user for create package object

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
Returns:

response : taniumpy.object_types.base.BaseType

pytan.binsupport.process_create_sensor_args(parser, handler, args)[source]

Process command line args supplied by user for create sensor object

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
Returns:

response : taniumpy.object_types.base.BaseType

pytan.binsupport.process_create_user_args(parser, handler, args)[source]

Process command line args supplied by user for create user object

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
Returns:

response : taniumpy.object_types.base.BaseType

pytan.binsupport.process_create_whitelisted_url_args(parser, handler, args)[source]

Process command line args supplied by user for create group object

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
Returns:

response : taniumpy.object_types.base.BaseType

pytan.binsupport.process_delete_object_args(parser, handler, obj, args)[source]

Process command line args supplied by user for delete object

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

obj : str

  • Object type for delete object

args : args object

  • args parsed from parser
Returns:

response : taniumpy.object_types.base.BaseType

pytan.binsupport.process_deploy_action_args(parser, handler, args)[source]

Process command line args supplied by user for deploy action

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
Returns:

response

pytan.binsupport.process_get_object_args(parser, handler, obj, args, report=True)[source]

Process command line args supplied by user for get object

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

obj : str

  • Object type for get object

args : args object

  • args parsed from parser
Returns:

response : taniumpy.object_types.base.BaseType

pytan.binsupport.process_get_results_args(parser, handler, args)[source]

Process command line args supplied by user for getting results

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args

  • args object from parsing parser
Returns:

report_path, report_contents : tuple

pytan.binsupport.process_get_saved_question_history_args(parser, handler, args)[source]

Process command line args supplied by user for getting saved question history

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
Returns:

response : taniumpy.object_types.base.BaseType

pytan.binsupport.process_handler_args(parser, args)[source]

Process command line args supplied by user for handler

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

args : args

  • args parsed from parser
Returns:

h : pytan.handler.Handler

  • Handler object
pytan.binsupport.process_print_sensors_args(parser, handler, args)[source]

Process command line args supplied by user for printing sensors

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
pytan.binsupport.process_print_server_info_args(parser, handler, args)[source]

Process command line args supplied by user for printing server info

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
pytan.binsupport.process_pytan_shell_args(parser, handler, args)[source]

Process command line args supplied by user for a python shell

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
pytan.binsupport.process_stop_action_args(parser, handler, args)[source]

Process command line args supplied by user for stopping an action

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args

  • args object from parsing parser
Returns:

stop_action

pytan.binsupport.process_tsat_args(parser, handler, args)[source]

Process command line args supplied by user for tsat

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
pytan.binsupport.process_write_pytan_user_config_args(parser, handler, args)[source]

Process command line args supplied by user for writing pytan user config

Parameters:

parser : argparse.ArgParse

  • ArgParse object used to parse all_args

handler : pytan.handler.Handler

  • Instance of Handler created from command line args

args : args object

  • args parsed from parser
pytan.binsupport.remove_file_log(logfile)[source]

Utility to remove a log file from python’s logging module

pytan.binsupport.setup_approve_saved_action_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to approve saved actions.

pytan.binsupport.setup_ask_manual_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to ask manual questions.

pytan.binsupport.setup_ask_parsed_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to ask parsed questions.

pytan.binsupport.setup_ask_saved_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to ask saved questions.

pytan.binsupport.setup_create_group_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to create a group.

pytan.binsupport.setup_create_json_object_argparser(obj, doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to create objects from json files.

pytan.binsupport.setup_create_package_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to create a package.

pytan.binsupport.setup_create_sensor_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to create a sensor.

pytan.binsupport.setup_create_user_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to create a user.

pytan.binsupport.setup_create_whitelisted_url_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to create a whitelisted_url.

pytan.binsupport.setup_delete_object_argparser(obj, doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to delete objects.

pytan.binsupport.setup_deploy_action_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to deploy actions.

pytan.binsupport.setup_get_object_argparser(obj, doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to get objects.

pytan.binsupport.setup_get_results_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to get results for questions or actions.

pytan.binsupport.setup_get_saved_question_history_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to get saved question history.

pytan.binsupport.setup_parent_parser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser() and return a parser object for adding arguments to

pytan.binsupport.setup_parser(desc, help=False)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts that use pytan. This establishes the basic arguments that are needed by all such scripts, such as:

  • –help
  • –username
  • –password
  • –host
  • –port
  • –loglevel
  • –debugformat
pytan.binsupport.setup_print_sensors_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to print server info.

pytan.binsupport.setup_print_server_info_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to print sensor info.

pytan.binsupport.setup_pytan_shell_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to create a python shell.

pytan.binsupport.setup_stop_action_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to stop actions.

pytan.binsupport.setup_tsat_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to get objects.

pytan.binsupport.setup_write_pytan_user_config_argparser(doc)[source]

Method to setup the base pytan.utils.CustomArgParse class for command line scripts using pytan.utils.setup_parser(), then add specific arguments for scripts that use pytan to write a pytan user config file.

pytan.binsupport.version_check(reqver)[source]

Allows scripts using pytan to validate the version of the script aginst the version of pytan

Parameters:

reqver : str

  • string containing version number to check against Exception
Raises:

VersionMismatchError : Exception

2.7. pytan.exceptions

Provides exceptions for the pytan module.

exception pytan.exceptions.AuthorizationError[source]

Bases: exceptions.Exception

Exception thrown for authorization errors in pytan.sessions

exception pytan.exceptions.BadResponseError[source]

Bases: exceptions.Exception

Exception thrown for BadResponse messages from Tanium in pytan.sessions

exception pytan.exceptions.DefinitionParserError[source]

Bases: exceptions.Exception

Exception thrown for errors while parsing definitions from pytan.handler

exception pytan.exceptions.HandlerError[source]

Bases: exceptions.Exception

Exception thrown for errors in pytan.handler

exception pytan.exceptions.HttpError[source]

Bases: exceptions.Exception

Exception thrown for HTTP errors in pytan.sessions

exception pytan.exceptions.HumanParserError[source]

Bases: exceptions.Exception

Exception thrown for errors while parsing human strings from pytan.handler

exception pytan.exceptions.NotFoundError[source]

Bases: exceptions.Exception

Exception thrown for Not Found messages from Tanium in pytan.handler

exception pytan.exceptions.PickerError[source]

Bases: exceptions.Exception

Exception thrown for picker errors in pytan.handler

exception pytan.exceptions.PollingError[source]

Bases: exceptions.Exception

Exception thrown for errors in pytan.polling

exception pytan.exceptions.PytanHelp[source]

Bases: exceptions.Exception

Exception thrown when printing out help

exception pytan.exceptions.RunFalse[source]

Bases: exceptions.Exception

Exception thrown when run=False from pytan.handler.Handler.deploy_action()

exception pytan.exceptions.ServerParseError[source]

Bases: exceptions.Exception

Exception thrown for server parsing errors in pytan.handler

exception pytan.exceptions.ServerSideExportError[source]

Bases: exceptions.Exception

Exception thrown for server side export errors in pytan.handler

exception pytan.exceptions.TimeoutException[source]

Bases: exceptions.Exception

Exception thrown for timeout errors in pytan.polling

exception pytan.exceptions.UnsupportedVersionError[source]

Bases: exceptions.Exception

Exception thrown for version checks in pytan.handler

exception pytan.exceptions.VersionMismatchError[source]

Bases: exceptions.Exception

Exception thrown for version_check in pytan.utils

exception pytan.exceptions.VersionParseError[source]

Bases: exceptions.Exception

Exception thrown for server version parsing errors in pytan.handler

2.8. pytan.xml_clean

This is a regex based XML cleaner that will replace unsupported characters

pytan.xml_clean.DEFAULT_REPLACEMENT = u'\ufffd'

The default character to use when replacing characters

pytan.xml_clean.INVALID_UNICODE_RAW_RE = u'[^\t\n\r -\ud7ff\ue000-\ufffd]'

The raw regex string to use when replacing invalid characters

pytan.xml_clean.INVALID_UNICODE_RE = <_sre.SRE_Pattern object>

The regex object to use when replacing invalid characters

pytan.xml_clean.RESTRICTED_UNICODE_RAW_RE = u'[\x7f-\x84\x86-\x9f\ufdd0-\ufdef]'

The raw regex string to use when replacing restricted characters

pytan.xml_clean.RESTRICTED_UNICODE_RE = <_sre.SRE_Pattern object>

The regex object to use when replacing restricted characters

pytan.xml_clean.XML_1_0_RESTRICTED_HEX = [[127, 132], [134, 159], [64976, 65007]]
Restricted/discouraged Unicode characters for XML documents:
[#x7F-#x84], [#x86-#x9F], [#xFDD0-#xFDEF], [#x1FFFE-#x1FFFF], [#x2FFFE-#x2FFFF], [#x3FFFE-#x3FFFF], [#x4FFFE-#x4FFFF], [#x5FFFE-#x5FFFF], [#x6FFFE-#x6FFFF], [#x7FFFE-#x7FFFF], [#x8FFFE-#x8FFFF], [#x9FFFE-#x9FFFF], [#xAFFFE-#xAFFFF], [#xBFFFE-#xBFFFF], [#xCFFFE-#xCFFFF], [#xDFFFE-#xDFFFF], [#xEFFFE-#xEFFFF], [#xFFFFE-#xFFFFF], [#x10FFFE-#x10FFFF]

Source: http://www.w3.org/TR/REC-xml/#NT-Char

pytan.xml_clean.XML_1_0_VALID_HEX = [[9], [10], [13], [32, 55295], [57344, 65533]]
Valid Unicode characters for XML documents:
(any Unicode character, excluding the surrogate blocks, FFFE, and FFFF) #x9, #xA, #xD, [#x20-#xD7FF], [#xE000-#xFFFD], [#x10000-#x10FFFF]

Source: http://www.w3.org/TR/REC-xml/#NT-Char

pytan.xml_clean.replace_invalid_unicode(text, replacement=None)[source]

Replaces invalid unicode characters with replacement

Parameters:

text : str

  • str to clean

replacement : str, optional

  • default: None
  • if invalid characters found, they will be replaced with this
  • if not supplied, will default to DEFAULT_REPLACEMENT
Returns:

str, cnt, RE : tuple

  • str : the cleaned version of text
  • cnt : the number of replacements that took place
  • RE : the regex object that was used to do the replacements
pytan.xml_clean.replace_restricted_unicode(text, replacement=None)[source]

Replaces restricted unicode characters with replacement

Parameters:

text : str

  • str to clean

replacement : str, optional

  • default: None
  • if restricted characters found, they will be replaced with this
  • if not supplied, will default to DEFAULT_REPLACEMENT
Returns:

str, cnt, RE : tuple

  • str : the cleaned version of text
  • cnt : the number of replacements that took place
  • RE : the regex object that was used to do the replacements
pytan.xml_clean.xml_cleaner(s, encoding='utf-8', clean_restricted=True, log_clean_messages=True, log_bad_characters=False, replacement=None, **kwargs)[source]

Removes invalid /restricted characters per XML 1.0 spec

Parameters:

s : str

  • str to clean

encoding : str, optional

  • default: ‘utf-8’
  • encoding of s

clean_restricted : bool, optional

  • default: True
  • remove restricted characters from s or not

log_clean_messages : bool, optional

  • default: True
  • log messages using python logging or not

log_bad_characters : bool, optional

  • default: False
  • log bad character matches or not
Returns:

str

  • the cleaned version of s