Skip to content

Release/1.6.6 #234

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Dec 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0442acc
Add return code for invalid args block
lybroman-splk Jun 5, 2018
0e0d872
Added headers argument to get requests so that additional headers can…
abroglesc Jun 6, 2018
8bcf9d9
Added the option of always adding a particular header to a request. A…
abroglesc Jun 13, 2018
353d773
Adding additional comments to denote that a headers object is possibl…
abroglesc Jun 13, 2018
0a4ac01
Merge pull request #212 from splunk/master
fantavlik Jun 26, 2018
9ba6b37
auto-doc all class constructor parameters
Jun 28, 2018
711b895
Merge pull request #209 from abroglesc/additional-headers-get-method
shakeelmohamed Jun 28, 2018
16a9b84
Merge pull request #213 from splunk/docs/fix-modinputs
tdhellmann Jun 29, 2018
f989819
Merge pull request #204 from lybroman/add_return_code_for_invalid_arg…
tdhellmann Aug 17, 2018
b9de11d
Searchcommands: add full support for unicode
Sep 27, 2018
6894ef5
update assertion
Sep 27, 2018
c6b7457
Merge pull request #222 from splunk/bugfix/search-commands-unicode
shakeelmohamed Sep 27, 2018
fa2f7f5
Merge branch 'master' into develop
shakeelmohamed Oct 10, 2018
0eb516e
Make the explorer example compatible w/ Python 3
shakeelmohamed Oct 10, 2018
5ab6d2f
Merge pull request #224 from splunk/examples/explorer-six-compat
shakeelmohamed Oct 10, 2018
55802f4
Update binding.py
kimox2 Oct 23, 2018
5092663
Merge pull request #227 from kimox2/master
shakeelmohamed Oct 26, 2018
9372638
Run CI against Splunk 7.2
Oct 30, 2018
3ef3a66
tests: relax restart timeout
Oct 31, 2018
ef33349
Merge pull request #228 from splunk/ci/splunk-7.2
shakeelmohamed Oct 31, 2018
35ca774
Fix ssl verify to require certs when true (#233)
dan1 Dec 4, 2018
10303f4
Preparing Release 1.6.6
dan1 Dec 5, 2018
08b7163
Cleaned up CHANGELOG.md
dan1 Dec 5, 2018
967653c
Update version to 1.6.6 in User-Agent header
dan1 Dec 5, 2018
ff4cf9b
Rev version of examples/searchcommands_app/setup.py to 1.6.6
dan1 Dec 5, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ dist/
examples/searchcommands_app/package/default/commands.conf
examples/searchcommands_app/package/bin/packages
tests/searchcommands/apps/app_with_logging_configuration/*.log
*.observed
*.observed
venv/
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ before_install:
- mkdir -p $SPLUNK_HOME/var/log/splunk

env:
- SPLUNK_VERSION=6.6-sdk
- SPLUNK_VERSION=7.0-sdk
- SPLUNK_VERSION=7.2-sdk

language: python

Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Splunk SDK for Python Changelog

## Versiom 1.6.6

### Bug fixes

* Fix ssl verify to require certs when true

### Minor changes

* Make the explorer example compatible w/ Python 3
* Add full support for unicode in SearchCommands
* Add return code for invalid_args block

## Version 1.6.5

### Bug fixes
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[![Build Status](https://travis-ci.org/splunk/splunk-sdk-python.svg?branch=master)](https://travis-ci.org/splunk/splunk-sdk-python)
# The Splunk Software Development Kit for Python

#### Version 1.6.5
#### Version 1.6.6

The Splunk Software Development Kit (SDK) for Python contains library code and
examples designed to enable developers to build applications using Splunk.
Expand Down
2 changes: 2 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,5 @@

# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'

autoclass_content = 'both'
5 changes: 3 additions & 2 deletions examples/explorer/explorer.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
except ImportError:
raise Exception("Add the SDK repository to your PYTHONPATH to run the examples "
"(e.g., export PYTHONPATH=~/splunk-sdk-python.")
import urllib

from splunklib.six.moves import urllib

PORT = 8080

Expand Down Expand Up @@ -57,7 +58,7 @@ def main(argv):
args.append(('owner', opts.kwargs['owner']))

# Encode these arguments
args = urllib.urlencode(args)
args = urllib.parse.urlencode(args)

# Launch the browser
webbrowser.open("file://%s" % os.path.join(os.getcwd(), "explorer.html?%s" % args))
Expand Down
30 changes: 16 additions & 14 deletions examples/explorer/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@

from __future__ import absolute_import
from __future__ import print_function
import splunklib.six.moves.SimpleHTTPServer
import splunklib.six.moves.socketserver
import urllib2
import sys
import StringIO
from splunklib import six
import os

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))

from splunklib.six import iteritems
from splunklib.six.moves import socketserver, SimpleHTTPServer, StringIO, urllib

PORT = 8080

class RedirectHandler(six.moves.SimpleHTTPServer.SimpleHTTPRequestHandler):

class RedirectHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
redirect_url, headers = self.get_url_and_headers()
if redirect_url is None:
Expand Down Expand Up @@ -83,13 +85,13 @@ def make_request(self, url, method, data, headers):

try:
# Make the request
request = urllib2.Request(url, data, headers)
request = urllib.Request(url, data, headers)
request.get_method = lambda: method
response = urllib2.urlopen(request)
response = urllib.urlopen(request)

# We were successful, so send the response code
self.send_response(response.code, message=response.msg)
for key, value in six.iteritems(dict(response.headers)):
for key, value in iteritems(dict(response.headers)):
# Optionally log the headers
#self.log_message("%s: %s" % (key, value))

Expand All @@ -105,16 +107,16 @@ def make_request(self, url, method, data, headers):

# Copy the response to the output
self.copyfile(response, self.wfile)
except urllib2.HTTPError as e:
except urllib.HTTPError as e:
# On errors, log the response code and message
self.log_message("Code: %s (%s)", e.code, e.msg)

for key, value in six.iteritems(dict(e.hdrs)):
for key, value in iteritems(dict(e.hdrs)):
# On errors, we always log the headers
self.log_message("%s: %s", key, value)

response_text = e.fp.read()
response_file = StringIO.StringIO(response_text)
response_file = StringIO(response_text)

# On errors, we also log the response text
self.log_message("Response: %s", response_text)
Expand All @@ -135,10 +137,10 @@ def make_request(self, url, method, data, headers):
# Finally, send the error itself
self.copyfile(response_file, self.wfile)

class ReuseableSocketTCPServer(six.moves.socketserver.TCPServer):
class ReuseableSocketTCPServer(socketserver.TCPServer):
def __init__(self, *args, **kwargs):
self.allow_reuse_address = True
six.moves.socketserver.TCPServer.__init__(self, *args, **kwargs)
socketserver.TCPServer.__init__(self, *args, **kwargs)

def serve(port = PORT):
Handler = RedirectHandler
Expand Down
2 changes: 1 addition & 1 deletion examples/searchcommands_app/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ def run(self):
setup(
description='Custom Search Command examples',
name=os.path.basename(project_dir),
version='1.6.5',
version='1.6.6',
author='Splunk, Inc.',
author_email='devinfo@splunk.com',
url='http://github.com/splunk/splunk-sdk-python',
Expand Down
2 changes: 1 addition & 1 deletion splunklib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@

from __future__ import absolute_import
from splunklib.six.moves import map
__version_info__ = (1, 6, 5)
__version_info__ = (1, 6, 6)
__version__ = ".".join(map(str, __version_info__))
60 changes: 38 additions & 22 deletions splunklib/binding.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,30 @@
"""

from __future__ import absolute_import

import io
import logging
import socket
import ssl
from io import BytesIO

from splunklib.six.moves import urllib
import io
import sys

from base64 import b64encode
from contextlib import contextmanager
from datetime import datetime
from functools import wraps
from io import BytesIO
from xml.etree.ElementTree import XML

from splunklib import six
from splunklib.six import StringIO
from splunklib.six.moves import urllib

from contextlib import contextmanager
from .data import record

from xml.etree.ElementTree import XML
from splunklib import six
try:
from xml.etree.ElementTree import ParseError
except ImportError as e:
from xml.parsers.expat import ExpatError as ParseError

from .data import record

__all__ = [
"AuthenticationError",
Expand Down Expand Up @@ -449,6 +449,8 @@ class Context(object):
:type username: ``string``
:param password: The password for the Splunk account.
:type password: ``string``
:param headers: List of extra HTTP headers to send (optional).
:type headers: ``list`` of 2-tuples.
:param handler: The HTTP request handler (optional).
:returns: A ``Context`` instance.

Expand All @@ -465,7 +467,8 @@ class Context(object):
c = binding.Context(cookie="splunkd_8089=...")
"""
def __init__(self, handler=None, **kwargs):
self.http = HttpLib(handler, kwargs.get("verify", True))
self.http = HttpLib(handler, kwargs.get("verify", False), key_file=kwargs.get("key_file"),
cert_file=kwargs.get("cert_file")) # Default to False for backward compat
self.token = kwargs.get("token", _NoAuthenticationToken)
if self.token is None: # In case someone explicitly passes token=None
self.token = _NoAuthenticationToken
Expand All @@ -478,6 +481,7 @@ def __init__(self, handler=None, **kwargs):
self.password = kwargs.get("password", "")
self.basic = kwargs.get("basic", False)
self.autologin = kwargs.get("autologin", False)
self.additional_headers = kwargs.get("headers", [])

# Store any cookies in the self.http._cookies dict
if "cookie" in kwargs and kwargs['cookie'] not in [None, _NoAuthenticationToken]:
Expand Down Expand Up @@ -613,7 +617,7 @@ def delete(self, path_segment, owner=None, app=None, sharing=None, **query):

@_authentication
@_log_duration
def get(self, path_segment, owner=None, app=None, sharing=None, **query):
def get(self, path_segment, owner=None, app=None, headers=None, sharing=None, **query):
"""Performs a GET operation from the REST path segment with the given
namespace and query.

Expand All @@ -636,6 +640,8 @@ def get(self, path_segment, owner=None, app=None, sharing=None, **query):
:type owner: ``string``
:param app: The app context of the namespace (optional).
:type app: ``string``
:param headers: List of extra HTTP headers to send (optional).
:type headers: ``list`` of 2-tuples.
:param sharing: The sharing mode of the namespace (optional).
:type sharing: ``string``
:param query: All other keyword arguments, which are used as query
Expand Down Expand Up @@ -663,10 +669,14 @@ def get(self, path_segment, owner=None, app=None, sharing=None, **query):
c.logout()
c.get('apps/local') # raises AuthenticationError
"""
if headers is None:
headers = []

path = self.authority + self._abspath(path_segment, owner=owner,
app=app, sharing=sharing)
logging.debug("GET request to %s (body: %s)", path, repr(query))
response = self.http.get(path, self._auth_headers, **query)
all_headers = headers + self.additional_headers + self._auth_headers
response = self.http.get(path, all_headers, **query)
return response

@_authentication
Expand Down Expand Up @@ -738,7 +748,7 @@ def post(self, path_segment, owner=None, app=None, sharing=None, headers=None, *

path = self.authority + self._abspath(path_segment, owner=owner, app=app, sharing=sharing)
logging.debug("POST request to %s (body: %s)", path, repr(query))
all_headers = headers + self._auth_headers
all_headers = headers + self.additional_headers + self._auth_headers
response = self.http.post(path, all_headers, **query)
return response

Expand Down Expand Up @@ -804,7 +814,7 @@ def request(self, path_segment, method="GET", headers=None, body="",
path = self.authority \
+ self._abspath(path_segment, owner=owner,
app=app, sharing=sharing)
all_headers = headers + self._auth_headers
all_headers = headers + self.additional_headers + self._auth_headers
logging.debug("%s request to %s (headers: %s, body: %s)",
method, path, str(all_headers), repr(body))
response = self.http.request(path,
Expand Down Expand Up @@ -858,6 +868,7 @@ def login(self):
self.authority + self._abspath("/services/auth/login"),
username=self.username,
password=self.password,
headers=self.additional_headers,
cookie="1") # In Splunk 6.2+, passing "cookie=1" will return the "set-cookie" header

body = response.body.read()
Expand Down Expand Up @@ -968,6 +979,8 @@ def connect(**kwargs):
:type username: ``string``
:param password: The password for the Splunk account.
:type password: ``string``
:param headers: List of extra HTTP headers to send (optional).
:type headers: ``list`` of 2-tuples.
:param autologin: When ``True``, automatically tries to log in again if the
session terminates.
:type autologin: ``Boolean``
Expand Down Expand Up @@ -1108,8 +1121,11 @@ class HttpLib(object):

If using the default handler, SSL verification can be disabled by passing verify=False.
"""
def __init__(self, custom_handler=None, verify=True):
self.handler = handler(verify=verify) if custom_handler is None else custom_handler
def __init__(self, custom_handler=None, verify=False, key_file=None, cert_file=None):
if custom_handler is None:
self.handler = handler(verify=verify, key_file=key_file, cert_file=cert_file)
else:
self.handler = custom_handler
self._cookies = {}

def delete(self, url, headers=None, **kwargs):
Expand Down Expand Up @@ -1190,7 +1206,7 @@ def post(self, url, headers=None, **kwargs):
# to support the receivers/stream endpoint.
if 'body' in kwargs:
# We only use application/x-www-form-urlencoded if there is no other
# Content-Type header present. This can happen in cases where we
# Content-Type header present. This can happen in cases where we
# send requests as application/json, e.g. for KV Store.
if len([x for x in headers if x[0].lower() == "content-type"]) == 0:
headers.append(("Content-Type", "application/x-www-form-urlencoded"))
Expand Down Expand Up @@ -1280,8 +1296,8 @@ def peek(self, size):

def close(self):
"""Closes this response."""
if _connection:
_connection.close()
if self._connection:
self._connection.close()
self._response.close()

def read(self, size = None):
Expand Down Expand Up @@ -1317,7 +1333,7 @@ def readinto(self, byte_array):
return bytes_read


def handler(key_file=None, cert_file=None, timeout=None, verify=True):
def handler(key_file=None, cert_file=None, timeout=None, verify=False):
"""This class returns an instance of the default HTTP request handler using
the values you provide.

Expand All @@ -1341,7 +1357,7 @@ def connect(scheme, host, port):
if cert_file is not None: kwargs['cert_file'] = cert_file

# If running Python 2.7.9+, disable SSL certificate validation
if (sys.version_info >= (2,7,9) and key_file is None and cert_file is None) or not verify:
if (sys.version_info >= (2,7,9) and key_file is None and cert_file is None) and not verify:
kwargs['context'] = ssl._create_unverified_context()
return six.moves.http_client.HTTPSConnection(host, port, **kwargs)
raise ValueError("unsupported scheme: %s" % scheme)
Expand All @@ -1352,7 +1368,7 @@ def request(url, message, **kwargs):
head = {
"Content-Length": str(len(body)),
"Host": host,
"User-Agent": "splunk-sdk-python/1.6.5",
"User-Agent": "splunk-sdk-python/1.6.6",
"Accept": "*/*",
"Connection": "Close",
} # defaults
Expand Down
Loading