Skip to content

Commit 0a6e1a5

Browse files
author
Shakeel Mohamed
committed
Merge branch 'master' into develop
2 parents c7d74f9 + 49d7c3d commit 0a6e1a5

File tree

10 files changed

+74
-11
lines changed

10 files changed

+74
-11
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*coverage_html_report*
66
.coverage
77
.coverage.*
8+
.python-version
89
__stdout__
910
docs/_build
1011
build/
@@ -18,4 +19,5 @@ examples/*/metadata
1819
tests/searchcommands_data/log/
1920
tests/searchcommands_data/output/
2021
examples/searchcommands_app/searchcommand_app.log
21-
Test Results*.html
22+
Test Results*.html
23+
tests/searchcommands/data/app/app.log

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Splunk SDK for Python Changelog
22

3+
## Version 1.3.1
4+
5+
### Bug fixes
6+
7+
* Hot fix to `binding.py` to work with Python 2.7.9, which introduced SSL certificate validation by default as outlined in [PEP 476](https://www.python.org/dev/peps/pep-0476).
8+
* Update `async`, `handler_proxy`, and `handler_urllib2` examples to work with Python 2.7.9 by disabling SSL certificate validation by default.
39

410
## Version 1.3.0
511

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# The Splunk Software Development Kit for Python
22

3-
#### Version 1.3.0
3+
#### Version 1.3.1
44

55
The Splunk Software Development Kit (SDK) for Python contains library code and
66
examples designed to enable developers to build applications using Splunk.

examples/async/async.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import sys, os, datetime
2424
import urllib
25+
import ssl
2526
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))
2627

2728
import splunklib.binding as binding
@@ -171,7 +172,12 @@ def request(url, message, **kwargs):
171172
method = message.get("method", "GET")
172173

173174
# Note that we do not support proxies in this example
174-
opener = urllib2.build_opener()
175+
# If running Python 2.7.9+, disable SSL certificate validation
176+
if sys.version_info >= (2, 7, 9):
177+
unverified_ssl_handler = urllib2.HTTPSHandler(context=ssl._create_unverified_context())
178+
opener = urllib2.build_opener(unverified_ssl_handler)
179+
else:
180+
opener = urllib2.build_opener()
175181

176182
# Unfortunately, we need to use the hack of
177183
# "overriding" `request.get_method` to specify

examples/handlers/handler_proxy.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from pprint import pprint
3030
from StringIO import StringIO
3131
import sys, os
32+
import ssl
3233
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))
3334
import urllib2
3435

@@ -52,9 +53,15 @@ def request(url, message, **kwargs):
5253
method = message['method'].lower()
5354
data = message.get('body', "") if method == 'post' else None
5455
headers = dict(message.get('headers', []))
55-
context = urllib2.Request(url, data, headers)
56+
req = urllib2.Request(url, data, headers)
5657
try:
57-
response = urllib2.urlopen(context)
58+
response = urllib2.urlopen(req)
59+
except urllib2.URLError, response:
60+
# If running Python 2.7.9+, disable SSL certificate validation and try again
61+
if sys.version_info >= (2, 7, 9):
62+
response = urllib2.urlopen(req, context=ssl._create_unverified_context())
63+
else:
64+
raise
5865
except urllib2.HTTPError, response:
5966
pass # Propagate HTTP errors via the returned response message
6067
return {

examples/handlers/handler_urllib2.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import sys, os
2222
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))
2323
import urllib2
24+
import ssl
2425

2526
import splunklib.client as client
2627

@@ -34,9 +35,13 @@ def request(url, message, **kwargs):
3435
method = message['method'].lower()
3536
data = message.get('body', "") if method == 'post' else None
3637
headers = dict(message.get('headers', []))
37-
context = urllib2.Request(url, data, headers)
38+
# If running Python 2.7.9+, disable SSL certificate validation
39+
req = urllib2.Request(url, data, headers)
3840
try:
39-
response = urllib2.urlopen(context)
41+
if sys.version_info >= (2, 7, 9):
42+
response = urllib2.urlopen(req, context=ssl._create_unverified_context())
43+
else:
44+
response = urllib2.urlopen(req)
4045
except urllib2.HTTPError, response:
4146
pass # Propagate HTTP errors via the returned response message
4247
return {

setup.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ def run_test_suite():
3434
unittest.TextTestRunner().run(suite)
3535
os.chdir(original_cwd)
3636

37+
def run_test_suite_with_junit_output():
38+
try:
39+
import unittest2 as unittest
40+
except ImportError:
41+
import unittest
42+
import xmlrunner
43+
original_cwd = os.path.abspath(os.getcwd())
44+
os.chdir('tests')
45+
suite = unittest.defaultTestLoader.discover('.')
46+
xmlrunner.XMLTestRunner(output='../test-reports').run(suite)
47+
os.chdir(original_cwd)
3748

3849
class CoverageCommand(Command):
3950
"""setup.py command to run code coverage of the test suite."""
@@ -73,6 +84,20 @@ def finalize_options(self):
7384
def run(self):
7485
run_test_suite()
7586

87+
class JunitXmlTestCommand(Command):
88+
"""setup.py command to run the whole test suite."""
89+
description = "Run test full test suite with JUnit-formatted output."
90+
user_options = []
91+
92+
def initialize_options(self):
93+
pass
94+
95+
def finalize_options(self):
96+
pass
97+
98+
def run(self):
99+
run_test_suite_with_junit_output()
100+
76101

77102
class DistCommand(Command):
78103
"""setup.py command to create .spl files for modular input and search
@@ -175,6 +200,7 @@ def exclude(path):
175200

176201
cmdclass={'coverage': CoverageCommand,
177202
'test': TestCommand,
203+
'testjunit': JunitXmlTestCommand,
178204
'dist': DistCommand},
179205

180206
description="The Splunk Software Development Kit for Python.",
@@ -202,4 +228,4 @@ def exclude(path):
202228
"Topic :: Software Development :: Libraries :: Python Modules",
203229
"Topic :: Software Development :: Libraries :: Application Frameworks",
204230
],
205-
)
231+
)

splunklib/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414

1515
"""Python library for Splunk."""
1616

17-
__version_info__ = (1, 3, 0)
17+
__version_info__ = (1, 3, 1)
1818
__version__ = ".".join(map(str, __version_info__))
1919

splunklib/binding.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import ssl
3131
import urllib
3232
import io
33+
import sys
3334

3435
from datetime import datetime
3536
from functools import wraps
@@ -1204,6 +1205,10 @@ def connect(scheme, host, port):
12041205
if scheme == "https":
12051206
if key_file is not None: kwargs['key_file'] = key_file
12061207
if cert_file is not None: kwargs['cert_file'] = cert_file
1208+
1209+
# If running Python 2.7.9+, disable SSL certificate validation
1210+
if sys.version_info >= (2,7,9) and key_file is None and cert_file is None:
1211+
kwargs['context'] = ssl._create_unverified_context()
12071212
return httplib.HTTPSConnection(host, port, **kwargs)
12081213
raise ValueError("unsupported scheme: %s" % scheme)
12091214

tests/test_binding.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import testlib
2525
import unittest
2626
import socket
27+
import sys
28+
import ssl
2729

2830
import splunklib.binding as binding
2931
from splunklib.binding import HTTPError, AuthenticationError, UrlEncoded
@@ -435,9 +437,13 @@ def urllib2_handler(url, message, **kwargs):
435437
method = message['method'].lower()
436438
data = message.get('body', "") if method == 'post' else None
437439
headers = dict(message.get('headers', []))
438-
context = urllib2.Request(url, data, headers)
440+
req = urllib2.Request(url, data, headers)
439441
try:
440-
response = urllib2.urlopen(context)
442+
# If running Python 2.7.9+, disable SSL certificate validation
443+
if sys.version_info >= (2, 7, 9):
444+
response = urllib2.urlopen(req, context=ssl._create_unverified_context())
445+
else:
446+
response = urllib2.urlopen(req)
441447
except urllib2.HTTPError, response:
442448
pass # Propagate HTTP errors via the returned response message
443449
return {

0 commit comments

Comments
 (0)