@@ -559,8 +559,8 @@ def parse(self, query, **kwargs):
559
559
:return: A semantic map of the parsed search query.
560
560
"""
561
561
if self .splunk_version >= (9 ,):
562
- return self .get ("search/v2/parser" , q = query , ** kwargs )
563
- return self .post ("search/parser" , q = query , ** kwargs )
562
+ return self .post ("search/v2/parser" , q = query , ** kwargs )
563
+ return self .get ("search/parser" , q = query , ** kwargs )
564
564
565
565
def restart (self , timeout = None ):
566
566
"""Restarts this Splunk instance.
@@ -793,6 +793,13 @@ def get(self, path_segment="", owner=None, app=None, sharing=None, **query):
793
793
app = app , sharing = sharing )
794
794
# ^-- This was "%s%s" % (self.path, path_segment).
795
795
# That doesn't work, because self.path may be UrlEncoded.
796
+
797
+ # Search API v2 fallback to v1:
798
+ # - In v2, /results_preview, /events and /results do not support search params.
799
+ # - Fallback from v2 to v1 if Splunk Version is < 9.
800
+ if (PATH_JOBS_V2 in path and 'search' in query and path .endswith (tuple (["results_preview" , "events" , "results" ]))) or self .service .splunk_version < (9 ,):
801
+ path = path .replace (PATH_JOBS_V2 , PATH_JOBS )
802
+
796
803
return self .service .get (path ,
797
804
owner = owner , app = app , sharing = sharing ,
798
805
** query )
@@ -845,13 +852,20 @@ def post(self, path_segment="", owner=None, app=None, sharing=None, **query):
845
852
apps.get('nonexistant/path') # raises HTTPError
846
853
s.logout()
847
854
apps.get() # raises AuthenticationError
848
- """
855
+ """
849
856
if path_segment .startswith ('/' ):
850
857
path = path_segment
851
858
else :
852
859
if not self .path .endswith ('/' ) and path_segment != "" :
853
860
self .path = self .path + '/'
854
861
path = self .service ._abspath (self .path + path_segment , owner = owner , app = app , sharing = sharing )
862
+
863
+ # Search API v2 fallback to v1:
864
+ # - In v2, /results_preview, /events and /results do not support search params.
865
+ # - Fallback from v2 to v1 if Splunk Version is < 9.
866
+ if (PATH_JOBS_V2 in path and 'search' in query and path .endswith (tuple (["results_preview" , "events" , "results" ]))) or self .service .splunk_version < (9 ,):
867
+ path = path .replace (PATH_JOBS_V2 , PATH_JOBS )
868
+
855
869
return self .service .post (path , owner = owner , app = app , sharing = sharing , ** query )
856
870
857
871
@@ -2661,14 +2675,17 @@ def oneshot(self, path, **kwargs):
2661
2675
2662
2676
2663
2677
class Job (Entity ):
2664
-
2665
2678
"""This class represents a search job."""
2666
- def __init__ (self , service , sid , defaultPath , ** kwargs ):
2667
-
2668
- # Don't provide a path, allow it to be dynamically generated
2669
- Entity .__init__ (self , service , '' , skip_refresh = True , ** kwargs )
2679
+ def __init__ (self , service , sid , ** kwargs ):
2680
+ # Default to v2 in Splunk Version 9+
2681
+ path = "{path}{sid}"
2682
+ path = path .format (path = PATH_JOBS_V2 , sid = sid )
2683
+ # Fallback to v1 if Splunk Version < 9
2684
+ if service .splunk_version < (9 ,):
2685
+ path = path .format (path = PATH_JOBS , sid = sid )
2686
+
2687
+ Entity .__init__ (self , service , path , skip_refresh = True , ** kwargs )
2670
2688
self .sid = sid
2671
- self .defaultPath = defaultPath + sid + '/'
2672
2689
2673
2690
# The Job entry record is returned at the root of the response
2674
2691
def _load_atom_entry (self , response ):
@@ -2680,7 +2697,7 @@ def cancel(self):
2680
2697
:return: The :class:`Job`.
2681
2698
"""
2682
2699
try :
2683
- self .post (self . defaultPath + "control" , action = "cancel" )
2700
+ self .post ("control" , action = "cancel" )
2684
2701
except HTTPError as he :
2685
2702
if he .status == 404 :
2686
2703
# The job has already been cancelled, so
@@ -2695,7 +2712,7 @@ def disable_preview(self):
2695
2712
2696
2713
:return: The :class:`Job`.
2697
2714
"""
2698
- self .post (self . defaultPath + "control" , action = "disablepreview" )
2715
+ self .post ("control" , action = "disablepreview" )
2699
2716
return self
2700
2717
2701
2718
def enable_preview (self ):
@@ -2705,7 +2722,7 @@ def enable_preview(self):
2705
2722
2706
2723
:return: The :class:`Job`.
2707
2724
"""
2708
- self .post (self . defaultPath + "control" , action = "enablepreview" )
2725
+ self .post ("control" , action = "enablepreview" )
2709
2726
return self
2710
2727
2711
2728
def events (self , ** kwargs ):
@@ -2720,19 +2737,14 @@ def events(self, **kwargs):
2720
2737
:return: The ``InputStream`` IO handle to this job's events.
2721
2738
"""
2722
2739
kwargs ['segmentation' ] = kwargs .get ('segmentation' , 'none' )
2723
- path = "{path}{sid}/events"
2724
-
2725
- # Splunk version doesn't support v2 (pre-9.0) or the 'search' arg is included (which is v1 specific)
2726
- if self .splunk_version < (9 ,) or 'search' in kwargs :
2727
- return self .get (path .format (PATH_JOBS , self .sid ), ** kwargs ).body
2728
- return self .get (path .format (PATH_JOBS_V2 , self .sid ), ** kwargs ).body
2740
+ return self .get ("events" , ** kwargs ).body
2729
2741
2730
2742
def finalize (self ):
2731
2743
"""Stops the job and provides intermediate results for retrieval.
2732
2744
2733
2745
:return: The :class:`Job`.
2734
2746
"""
2735
- self .post (self . defaultPath + "control" , action = "finalize" )
2747
+ self .post ("control" , action = "finalize" )
2736
2748
return self
2737
2749
2738
2750
def is_done (self ):
@@ -2753,7 +2765,7 @@ def is_ready(self):
2753
2765
:rtype: ``boolean``
2754
2766
2755
2767
"""
2756
- response = self .get (self . defaultPath )
2768
+ response = self .get ()
2757
2769
if response .status == 204 :
2758
2770
return False
2759
2771
self ._state = self .read (response )
@@ -2774,7 +2786,7 @@ def pause(self):
2774
2786
2775
2787
:return: The :class:`Job`.
2776
2788
"""
2777
- self .post (self . defaultPath + "control" , action = "pause" )
2789
+ self .post ("control" , action = "pause" )
2778
2790
return self
2779
2791
2780
2792
def results (self , ** query_params ):
@@ -2813,12 +2825,7 @@ def results(self, **query_params):
2813
2825
:return: The ``InputStream`` IO handle to this job's results.
2814
2826
"""
2815
2827
query_params ['segmentation' ] = query_params .get ('segmentation' , 'none' )
2816
- path = "{path}{sid}/results"
2817
-
2818
- # Splunk version doesn't support v2 (pre-9.0) or the 'search' arg is included (which is v1 specific)
2819
- if self .splunk_version < (9 ,) or 'search' in query_params :
2820
- return self .get (path .format (PATH_JOBS , self .sid ), ** query_params ).body
2821
- return self .get (path .format (PATH_JOBS_V2 , self .sid ), ** query_params ).body
2828
+ return self .get ("results" , ** query_params ).body
2822
2829
2823
2830
def preview (self , ** query_params ):
2824
2831
"""Returns a streaming handle to this job's preview search results.
@@ -2859,12 +2866,7 @@ def preview(self, **query_params):
2859
2866
:return: The ``InputStream`` IO handle to this job's preview results.
2860
2867
"""
2861
2868
query_params ['segmentation' ] = query_params .get ('segmentation' , 'none' )
2862
- path = "{path}{sid}/results_preview"
2863
-
2864
- # Splunk version doesn't support v2 (pre-9.0) or the 'search' arg is included (which is v1 specific)
2865
- if self .splunk_version < (9 ,) or 'search' in query_params :
2866
- return self .get (path .format (PATH_JOBS , self .sid ), ** query_params ).body
2867
- return self .get (path .format (PATH_JOBS_V2 , self .sid ), ** query_params ).body
2869
+ return self .get ("results_preview" , ** query_params ).body
2868
2870
2869
2871
def searchlog (self , ** kwargs ):
2870
2872
"""Returns a streaming handle to this job's search log.
@@ -2877,7 +2879,7 @@ def searchlog(self, **kwargs):
2877
2879
2878
2880
:return: The ``InputStream`` IO handle to this job's search log.
2879
2881
"""
2880
- return self .get (self . defaultPath + "search.log" , ** kwargs ).body
2882
+ return self .get ("search.log" , ** kwargs ).body
2881
2883
2882
2884
def set_priority (self , value ):
2883
2885
"""Sets this job's search priority in the range of 0-10.
@@ -2890,7 +2892,7 @@ def set_priority(self, value):
2890
2892
2891
2893
:return: The :class:`Job`.
2892
2894
"""
2893
- self .post (self . defaultPath + 'control' , action = "setpriority" , priority = value )
2895
+ self .post ('control' , action = "setpriority" , priority = value )
2894
2896
return self
2895
2897
2896
2898
def summary (self , ** kwargs ):
@@ -2904,7 +2906,7 @@ def summary(self, **kwargs):
2904
2906
2905
2907
:return: The ``InputStream`` IO handle to this job's summary.
2906
2908
"""
2907
- return self .get (self . defaultPath + "summary" , ** kwargs ).body
2909
+ return self .get ("summary" , ** kwargs ).body
2908
2910
2909
2911
def timeline (self , ** kwargs ):
2910
2912
"""Returns a streaming handle to this job's timeline results.
@@ -2917,15 +2919,15 @@ def timeline(self, **kwargs):
2917
2919
2918
2920
:return: The ``InputStream`` IO handle to this job's timeline.
2919
2921
"""
2920
- return self .get (self . defaultPath + "timeline" , ** kwargs ).body
2922
+ return self .get ("timeline" , ** kwargs ).body
2921
2923
2922
2924
def touch (self ):
2923
2925
"""Extends the expiration time of the search to the current time (now) plus
2924
2926
the time-to-live (ttl) value.
2925
2927
2926
2928
:return: The :class:`Job`.
2927
2929
"""
2928
- self .post (self . defaultPath + "control" , action = "touch" )
2930
+ self .post ("control" , action = "touch" )
2929
2931
return self
2930
2932
2931
2933
def set_ttl (self , value ):
@@ -2937,15 +2939,15 @@ def set_ttl(self, value):
2937
2939
2938
2940
:return: The :class:`Job`.
2939
2941
"""
2940
- self .post (self . defaultPath + "control" , action = "setttl" , ttl = value )
2942
+ self .post ("control" , action = "setttl" , ttl = value )
2941
2943
return self
2942
2944
2943
2945
def unpause (self ):
2944
2946
"""Resumes the current search, if paused.
2945
2947
2946
2948
:return: The :class:`Job`.
2947
2949
"""
2948
- self .post (self . defaultPath + "control" , action = "unpause" )
2950
+ self .post ("control" , action = "unpause" )
2949
2951
return self
2950
2952
2951
2953
@@ -2954,7 +2956,7 @@ class Jobs(Collection):
2954
2956
collection using :meth:`Service.jobs`."""
2955
2957
def __init__ (self , service ):
2956
2958
# Splunk 9 introduces the v2 endpoint
2957
- if self .splunk_version >= (9 ,):
2959
+ if service .splunk_version >= (9 ,):
2958
2960
path = PATH_JOBS_V2
2959
2961
else :
2960
2962
path = PATH_JOBS
@@ -2995,7 +2997,7 @@ def create(self, query, **kwargs):
2995
2997
raise TypeError ("Cannot specify exec_mode=oneshot; use the oneshot method instead." )
2996
2998
response = self .post (search = query , ** kwargs )
2997
2999
sid = _load_sid (response )
2998
- return Job (self .service , sid , self . path )
3000
+ return Job (self .service , sid )
2999
3001
3000
3002
def export (self , query , ** params ):
3001
3003
"""Runs a search and immediately starts streaming preview events. This method returns a streaming handle to
@@ -3796,4 +3798,4 @@ def batch_save(self, *documents):
3796
3798
3797
3799
data = json .dumps (documents )
3798
3800
3799
- return json .loads (self ._post ('batch_save' , headers = KVStoreCollectionData .JSON_HEADER , body = data ).body .read ().decode ('utf-8' ))
3801
+ return json .loads (self ._post ('batch_save' , headers = KVStoreCollectionData .JSON_HEADER , body = data ).body .read ().decode ('utf-8' ))
0 commit comments