Skip to content
This repository was archived by the owner on Nov 21, 2019. It is now read-only.
This repository is currently being migrated. It's locked while the migration is in progress.

Commit 8c910d0

Browse files
author
Jim Olsen
committed
2.1.7 conflict merge
2 parents 5cc072b + d82ca89 commit 8c910d0

18 files changed

+2051
-491
lines changed

BUILD/doc/source/conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
master_doc = 'index'
7272

7373
# General information about the project.
74-
copyright = u'2015, Tanium'
74+
copyright = u'2015, Tanium Inc.'
7575

7676
# The version info for the project you're documenting, acts as replacement for
7777
# |version| and |release|, also used in various other places throughout the

CHANGELOG.md

+308-234
Large diffs are not rendered by default.
+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#!/usr/bin/env python -i
2+
# -*- mode: Python; tab-width: 4; indent-tabs-mode: nil; -*-
3+
# ex: set tabstop=4
4+
# Please do not change the two lines above. See PEP 8, PEP 263.
5+
'''Provides an example workflow for how to deploy actions when require_action_approval == 1'''
6+
__author__ = 'Jim Olsen <[email protected]>'
7+
__version__ = '2.1.7'
8+
9+
pytan_loc = '~/gh/pytan'
10+
11+
import os
12+
import sys
13+
14+
sys.dont_write_bytecode = True
15+
sys.path.append(os.path.join(os.path.expanduser(pytan_loc), 'lib'))
16+
17+
my_file = os.path.abspath(sys.argv[0])
18+
my_name = os.path.splitext(os.path.basename(my_file))[0]
19+
my_dir = os.path.dirname(my_file)
20+
parent_dir = os.path.dirname(my_dir)
21+
lib_dir = os.path.join(parent_dir, 'lib')
22+
path_adds = [lib_dir]
23+
[sys.path.append(aa) for aa in path_adds if aa not in sys.path]
24+
25+
import pytan
26+
import pytan.binsupport
27+
28+
import time
29+
import logging
30+
31+
32+
@pytan.utils.func_timing
33+
def wait_for_new_action(saved_action_id):
34+
while True:
35+
# re-fetch the saved action in order to get the updated last_action attribute
36+
saved_action = handler.get('saved_action', id=saved_action_id)[0]
37+
# fetch the full object of the last action created by the saved action
38+
full_action_object = handler.get('action', id=saved_action.last_action.id)[0]
39+
if full_action_object.status != 'Pending':
40+
print 'DEBUG: new action created by saved_action: {}'.format(full_action_object)
41+
return full_action_object
42+
print 'DEBUG: action is still in Pending status, new action not yet created: {} / {}'.format(full_action_object, full_action_object.status)
43+
time.sleep(1)
44+
45+
46+
if __name__ == "__main__":
47+
pytan.binsupport.version_check(reqver=__version__)
48+
49+
setupmethod = getattr(pytan.binsupport, 'setup_pytan_shell_argparser')
50+
responsemethod = getattr(pytan.binsupport, 'process_pytan_shell_args')
51+
52+
parser = setupmethod(doc=__doc__)
53+
args = parser.parse_args()
54+
55+
handler = pytan.binsupport.process_handler_args(parser=parser, args=args)
56+
response = responsemethod(parser=parser, handler=handler, args=args)
57+
58+
# bump log level up to 2 so we can see poller timing logs
59+
pytan.utils.set_log_levels(loglevel=2)
60+
61+
# enable timing logger for func_timing:
62+
logging.getLogger('pytan.handler.timing').setLevel(getattr(logging, 'DEBUG'))
63+
64+
# establish a package name with params
65+
pkg_name = "Custom Tagging - Add Tags{$1=\{test\}}"
66+
67+
# deploy the action with that package but set get_results to False so that it immediately returns and does not poll the action that is created by the saved action that will always be in Pending status
68+
deployed_action = handler.deploy_action(package=pkg_name, run=True, get_results=False)
69+
70+
# get the action_object that was created by the platform on behalf of the saved_action, which should have a status of 'Pending' due to require_action_approval = 1
71+
pending_action_obj = deployed_action['action_object']
72+
73+
# prove that the action created by the saved action before approval is "Pending"
74+
print "DEBUG: action created by platform: {}, status: {}".format(pending_action_obj.id, pending_action_obj.status)
75+
76+
# get the saved_action_object that was created by the platform
77+
unapproved_saved_action = deployed_action['saved_action_object']
78+
79+
# prove that the saved_action created by the platform is not yet approved
80+
print "DEBUG: saved_action approved_flag before approval: {}".format(unapproved_saved_action.approved_flag)
81+
82+
# approve the saved action
83+
saved_action_approval = handler.approve_saved_action(id=unapproved_saved_action.id)
84+
85+
# prove that the saved_action created by the platform is now approved
86+
print "DEBUG: saved_action approved_flag after approval: {}".format(saved_action_approval.approved_flag)
87+
88+
# wait for the saved action to create a new action after approval
89+
full_running_action_obj = wait_for_new_action(unapproved_saved_action.id)
90+
91+
# create an Action Poller for the new action
92+
poller = pytan.pollers.ActionPoller(handler=handler, obj=full_running_action_obj)
93+
94+
# run the poller
95+
poller.run()

EXAMPLES/POC/export_action_objects.py

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env python
2+
# -*- mode: Python; tab-width: 4; indent-tabs-mode: nil; -*-
3+
# ex: set tabstop=4
4+
# Please do not change the two lines above. See PEP 8, PEP 263.
5+
'''Exports an action, its source package, and its temp package to json format for troubleshooting'''
6+
__author__ = 'Jim Olsen <[email protected]>'
7+
__version__ = '2.1.6'
8+
9+
# change me to the location of PyTan!
10+
pytan_loc = '~/gh/pytan'
11+
12+
import os
13+
import sys
14+
import traceback
15+
16+
sys.dont_write_bytecode = True
17+
sys.path.append(os.path.join(os.path.expanduser(pytan_loc), 'lib'))
18+
19+
my_file = os.path.abspath(sys.argv[0])
20+
my_name = os.path.splitext(os.path.basename(my_file))[0]
21+
my_dir = os.path.dirname(my_file)
22+
parent_dir = os.path.dirname(my_dir)
23+
lib_dir = os.path.join(parent_dir, 'lib')
24+
path_adds = [lib_dir]
25+
[sys.path.append(aa) for aa in path_adds if aa not in sys.path]
26+
27+
import pytan
28+
import pytan.binsupport
29+
30+
if __name__ == "__main__":
31+
pytan.binsupport.version_check(reqver=__version__)
32+
33+
parser = pytan.binsupport.setup_parent_parser(doc=__doc__)
34+
arggroup_name = 'Export Action Objects Options'
35+
get_object_group = parser.add_argument_group(arggroup_name)
36+
get_object_group.add_argument(
37+
'--id',
38+
required=True,
39+
action='append',
40+
default=[],
41+
dest='id',
42+
help='id of action to export objects for',
43+
)
44+
45+
args = parser.parse_args()
46+
47+
handler = pytan.binsupport.process_handler_args(parser=parser, args=args)
48+
49+
try:
50+
action = handler.get('action', id=args.id)[0]
51+
except Exception as e:
52+
traceback.print_exc()
53+
print "\n\nError occurred: {}".format(e)
54+
sys.exit(100)
55+
56+
e = handler.export_to_report_file(action, 'json')
57+
print "Found action: {}, exported to: {}".format(action, e[0])
58+
59+
try:
60+
action_pkg = handler.get('package', id=action.package_spec.id, include_hidden_flag=1)[0]
61+
except Exception as e:
62+
traceback.print_exc()
63+
print "\n\nError occurred: {}".format(e)
64+
sys.exit(100)
65+
66+
e = handler.export_to_report_file(action_pkg, 'json')
67+
print "Found package for action: {}, exported to: {}".format(action_pkg, e[0])

EXAMPLES/POC/find_content_matches.py

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/usr/bin/env python
2+
# -*- mode: Python; tab-width: 4; indent-tabs-mode: nil; -*-
3+
# ex: set tabstop=4
4+
# Please do not change the two lines above. See PEP 8, PEP 263.
5+
'''Provides the ability to find all sensors that reference a given set of strings in their scripts, and all saved actions that reference those same sensors'''
6+
__author__ = 'Jim Olsen <[email protected]>'
7+
__version__ = '2.1.6'
8+
9+
# change me to the location of PyTan!
10+
pytan_loc = '~/gh/pytan'
11+
12+
# modify me for the list of string matches
13+
match_strings = [
14+
"ldap://",
15+
]
16+
17+
import os
18+
import sys
19+
20+
sys.dont_write_bytecode = True
21+
sys.path.append(os.path.join(os.path.expanduser(pytan_loc), 'lib'))
22+
23+
my_file = os.path.abspath(sys.argv[0])
24+
my_name = os.path.splitext(os.path.basename(my_file))[0]
25+
my_dir = os.path.dirname(my_file)
26+
parent_dir = os.path.dirname(my_dir)
27+
lib_dir = os.path.join(parent_dir, 'lib')
28+
path_adds = [lib_dir]
29+
[sys.path.append(aa) for aa in path_adds if aa not in sys.path]
30+
31+
import pytan
32+
import pytan.binsupport
33+
34+
if __name__ == "__main__":
35+
pytan.binsupport.version_check(reqver=__version__)
36+
37+
setupmethod = getattr(pytan.binsupport, 'setup_pytan_shell_argparser')
38+
responsemethod = getattr(pytan.binsupport, 'process_pytan_shell_args')
39+
40+
parser = setupmethod(doc=__doc__)
41+
args = parser.parse_args()
42+
43+
handler = pytan.binsupport.process_handler_args(parser=parser, args=args)
44+
response = responsemethod(parser=parser, handler=handler, args=args)
45+
46+
all_sensors = handler.get_all('sensor', include_hidden_flag=1)
47+
matched_sensors = [
48+
x
49+
for x in all_sensors
50+
for y in x.queries
51+
for z in match_strings
52+
if z.lower() in y.script.lower()
53+
]
54+
55+
m = "Found {} sensors that reference any of these strings: {}".format
56+
print m(len(matched_sensors), ', '.join(match_strings))
57+
58+
for x in matched_sensors:
59+
m = "Matched Sensor -- ID: {}, Name: {}".format
60+
print m(x.id, x.name)
61+
62+
all_saved_actions = handler.get_all('saved_action', include_hidden_flag=1)

EXAMPLES/POC/get_client_filter.py

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/usr/bin/env python
2+
# -*- mode: Python; tab-width: 4; indent-tabs-mode: nil; -*-
3+
# ex: set tabstop=4
4+
# Please do not change the two lines above. See PEP 8, PEP 263.
5+
'''Gets clients using a filter that only returns clients that have registered within a certain time'''
6+
__author__ = 'Jim Olsen <[email protected]>'
7+
__version__ = '2.1.6'
8+
9+
# change me to the location of PyTan!
10+
pytan_loc = '~/gh/pytan'
11+
12+
import os
13+
import sys
14+
15+
sys.dont_write_bytecode = True
16+
sys.path.append(os.path.join(os.path.expanduser(pytan_loc), 'lib'))
17+
18+
my_file = os.path.abspath(sys.argv[0])
19+
my_name = os.path.splitext(os.path.basename(my_file))[0]
20+
my_dir = os.path.dirname(my_file)
21+
parent_dir = os.path.dirname(my_dir)
22+
lib_dir = os.path.join(parent_dir, 'lib')
23+
path_adds = [lib_dir]
24+
[sys.path.append(aa) for aa in path_adds if aa not in sys.path]
25+
26+
import pytan
27+
import pytan.binsupport
28+
import taniumpy
29+
30+
31+
def get_clients_filter(handler, minutes=5):
32+
kwargs = {}
33+
if minutes:
34+
cache_filter = taniumpy.CacheFilter()
35+
cache_filter.field = 'last_registration'
36+
cache_filter.type = 'Date'
37+
cache_filter.operator = 'Greater'
38+
cache_filter.not_flag = False
39+
last_registration = -(minutes * 60)
40+
cache_filter.value = pytan.utils.seconds_from_now(last_registration)
41+
42+
cache_filter_list = taniumpy.CacheFilterList()
43+
cache_filter_list.append(cache_filter)
44+
# cache_filter_list_body = cache_filter_list.toSOAPBody()
45+
kwargs['cache_filters'] = cache_filter_list
46+
47+
search_spec = taniumpy.SystemStatusList()
48+
clients = handler.session.find(search_spec, **kwargs)
49+
return clients
50+
51+
52+
if __name__ == "__main__":
53+
pytan.binsupport.version_check(reqver=__version__)
54+
55+
setupmethod = getattr(pytan.binsupport, 'setup_pytan_shell_argparser')
56+
responsemethod = getattr(pytan.binsupport, 'process_pytan_shell_args')
57+
58+
parser = setupmethod(doc=__doc__)
59+
parser.add_argument(
60+
'-m',
61+
'--minutes',
62+
required=False,
63+
action='store',
64+
dest='minutes',
65+
type=int,
66+
default=5,
67+
help='Only return clients that have registered in the last minutes',
68+
)
69+
args = parser.parse_args()
70+
71+
handler = pytan.binsupport.process_handler_args(parser=parser, args=args)
72+
response = responsemethod(parser=parser, handler=handler, args=args)
73+
74+
clients = get_clients_filter(handler, minutes=args.minutes)
75+
print clients

EXAMPLES/POC/sensor_cleanup.py

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#!/usr/bin/env python -i
2+
# -*- mode: Python; tab-width: 4; indent-tabs-mode: nil; -*-
3+
# ex: set tabstop=4
4+
# Please do not change the two lines above. See PEP 8, PEP 263.
5+
'''Provides an interactive console with pytan available as handler'''
6+
__author__ = 'Jim Olsen <[email protected]>'
7+
__version__ = '2.1.5'
8+
9+
import os
10+
import sys
11+
sys.dont_write_bytecode = True
12+
13+
# change me to the location of PyTan!
14+
pytan_loc = '~/gh/pytan'
15+
sys.path.append(os.path.join(os.path.expanduser(pytan_loc), 'lib'))
16+
17+
my_file = os.path.abspath(sys.argv[0])
18+
my_name = os.path.splitext(os.path.basename(my_file))[0]
19+
my_dir = os.path.dirname(my_file)
20+
parent_dir = os.path.dirname(my_dir)
21+
lib_dir = os.path.join(parent_dir, 'lib')
22+
path_adds = [lib_dir]
23+
[sys.path.append(aa) for aa in path_adds if aa not in sys.path]
24+
25+
import pytan
26+
import pytan.binsupport
27+
28+
# List your sensors here that are exact name matches for sensors that should not be deleted
29+
KEEP_LIST = [
30+
'Folder Exists',
31+
]
32+
33+
# List your sensor categories that are exact matches for sensor categories that should not be deleted
34+
KEEP_CATEGORIES = [
35+
'Reserved',
36+
]
37+
38+
# Set this to True to actually delete, set to False to just report on what would be deleted
39+
ACTUALLY_DELETE = False
40+
41+
if __name__ == "__main__":
42+
pytan.binsupport.version_check(reqver=__version__)
43+
44+
setupmethod = getattr(pytan.binsupport, 'setup_pytan_shell_argparser')
45+
parser = setupmethod(doc=__doc__)
46+
args = parser.parse_args()
47+
48+
handler = pytan.binsupport.process_handler_args(parser=parser, args=args)
49+
50+
all_sensors = handler.get_all('sensor', include_hidden_flag=1)
51+
print "-- {} sensors in total".format(len(all_sensors))
52+
53+
to_be_deleted = [
54+
x for x in all_sensors
55+
if x.name not in KEEP_LIST
56+
and x.category not in KEEP_CATEGORIES
57+
]
58+
print "-- {} sensors to be deleted".format(len(to_be_deleted))
59+
60+
for s in to_be_deleted:
61+
print "!! Sensor ID {s.id!r}, name: {s.name!r} to be deleted!".format(s=s)
62+
if ACTUALLY_DELETE:
63+
handler.session.delete(s)
64+
print "-- Sensor ID {s.id!r}, name: {s.name!r} deleted!".format(s=s)

LICENSE

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2015 [Tanium, Inc. 2015]
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in
11+
all copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

0 commit comments

Comments
 (0)