Skip to content

Commit fbcdd82

Browse files
committed
Merge branch 'develop' into py3-code-migration
2 parents 8c90d1e + 7c9468f commit fbcdd82

File tree

9 files changed

+102
-36
lines changed

9 files changed

+102
-36
lines changed

.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ scheme=https
1111
# Your version of Splunk (default: 6.2)
1212
version=9.0
1313
# Bearer token for authentication
14-
#bearerToken="<Bearer-token>"
14+
#splunkToken="<Bearer-token>"
1515
# Session key for authentication
16-
#sessionKey="<Session-Key>"
16+
#token="<Session-Key>"

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@
1414
* Refactored Code throwing `deprecation` warnings
1515
* Refactored Code violating Pylint rules
1616

17+
## Version 1.7.3
18+
19+
### Bug fixes
20+
* [#493](https://github.com/splunk/splunk-sdk-python/pull/493) Fixed file permission for event_writer.py file [[issue#487](https://github.com/splunk/splunk-sdk-python/issues/487)]
21+
* [#500](https://github.com/splunk/splunk-sdk-python/pull/500) Replaced index_field with accelerated_field for kvstore [[issue#497](https://github.com/splunk/splunk-sdk-python/issues/497)]
22+
* [#502](https://github.com/splunk/splunk-sdk-python/pull/502) Updated check for IPv6 addresses
23+
24+
### Minor changes
25+
* [#490](https://github.com/splunk/splunk-sdk-python/pull/490) Added ACL properties update feature
26+
* [#495](https://github.com/splunk/splunk-sdk-python/pull/495) Added Splunk 8.1 in GitHub Actions Matrix
27+
* [#485](https://github.com/splunk/splunk-sdk-python/pull/485) Added test case for cookie persistence
28+
* [#503](https://github.com/splunk/splunk-sdk-python/pull/503) README updates on accessing "service" instance in CSC and ModularInput apps
29+
* [#504](https://github.com/splunk/splunk-sdk-python/pull/504) Updated authentication token names in docs to reduce confusion
30+
* [#494](https://github.com/splunk/splunk-sdk-python/pull/494) Reuse splunklib.__version__ in handler.request
31+
1732
## Version 1.7.2
1833

1934
### Minor changes

README.md

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
# The Splunk Enterprise Software Development Kit for Python
55

6-
#### Version 1.7.2
6+
#### Version 1.7.3
77

88
The Splunk Enterprise Software Development Kit (SDK) for Python contains library code designed to enable developers to build applications using the Splunk platform.
99

@@ -30,7 +30,7 @@ Here's what you need to get going with the Splunk Enterprise SDK for Python.
3030

3131
* Splunk Enterprise 9.0 or 8.2
3232

33-
The Splunk Enterprise SDK for Python has been tested with Splunk Enterprise 9.0 and 8.2
33+
The Splunk Enterprise SDK for Python has been tested with Splunk Enterprise 9.0, 8.2 and 8.1
3434

3535
If you haven't already installed Splunk Enterprise, download it [here](http://www.splunk.com/download).
3636
For more information, see the Splunk Enterprise [_Installation Manual_](https://docs.splunk.com/Documentation/Splunk/latest/Installation).
@@ -111,9 +111,9 @@ here is an example of .env file:
111111
# Your version of Splunk Enterprise
112112
version=9.0
113113
# Bearer token for authentication
114-
#bearerToken=<Bearer-token>
114+
#splunkToken=<Bearer-token>
115115
# Session key for authentication
116-
#sessionKey=<Session-Key>
116+
#token=<Session-Key>
117117

118118
#### SDK examples
119119

@@ -209,7 +209,39 @@ class GeneratorTest(GeneratingCommand):
209209
checkpoint_dir = inputs.metadata["checkpoint_dir"]
210210
```
211211

212-
#### Optional:Set up logging for splunklib
212+
### Access service object in Custom Search Command & Modular Input apps
213+
214+
#### Custom Search Commands
215+
* The service object is created from the Splunkd URI and session key passed to the command invocation the search results info file.
216+
* Service object can be accessed using `self.service` in `generate`/`transform`/`stream`/`reduce` methods depending on the Custom Search Command.
217+
* For Generating Custom Search Command
218+
```python
219+
def generate(self):
220+
# other code
221+
222+
# access service object that can be used to connect Splunk Service
223+
service = self.service
224+
# to get Splunk Service Info
225+
info = service.info
226+
```
227+
228+
229+
230+
#### Modular Inputs app:
231+
* The service object is created from the Splunkd URI and session key passed to the command invocation on the modular input stream respectively.
232+
* It is available as soon as the `Script.stream_events` method is called.
233+
```python
234+
def stream_events(self, inputs, ew):
235+
# other code
236+
237+
# access service object that can be used to connect Splunk Service
238+
service = self.service
239+
# to get Splunk Service Info
240+
info = service.info
241+
```
242+
243+
244+
### Optional:Set up logging for splunklib
213245
+ The default level is WARNING, which means that only events of this level and above will be visible
214246
+ To change a logging level we can call setup_logging() method and pass the logging level as an argument.
215247
+ Optional: we can also pass log format and date format string as a method argument to modify default format

scripts/templates/env.template

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ scheme=$scheme
1111
# Your version of Splunk (default: 6.2)
1212
version=$version
1313
# Bearer token for authentication
14-
#bearerToken=<Bearer-token>
14+
#splunkToken=<Bearer-token>
1515
# Session key for authentication
16-
#sessionKey=<Session-Key>
16+
#token=<Session-Key>

splunklib/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,5 @@ def assertRegex(self, *args, **kwargs):
7474
return getattr(self, "assertRegex")(*args, **kwargs)
7575

7676

77-
__version_info__ = (1, 7, 2)
78-
77+
__version_info__ = (1, 7, 3)
7978
__version__ = ".".join(map(str, __version_info__))

splunklib/binding.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,10 @@ def _authority(scheme=DEFAULT_SCHEME, host=DEFAULT_HOST, port=DEFAULT_PORT):
348348
"http://splunk.utopia.net:471"
349349
350350
"""
351-
if ':' in host:
352-
# IPv6 addresses must be enclosed in [ ] in order to be well-formed.
351+
# check if host is an IPv6 address and not enclosed in [ ]
352+
if ':' in host and not (host.startswith('[') and host.endswith(']')):
353+
# IPv6 addresses must be enclosed in [ ] in order to be well
354+
# formed.
353355
host = '[' + host + ']'
354356
return UrlEncoded(f"{scheme}://{host}:{port}", skip_encode=True)
355357

splunklib/client.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3700,21 +3700,28 @@ class KVStoreCollections(Collection):
37003700
def __init__(self, service):
37013701
Collection.__init__(self, service, 'storage/collections/config', item=KVStoreCollection)
37023702

3703-
def create(self, name, indexes={}, fields={}, **kwargs):
3703+
def __getitem__(self, item):
3704+
res = Collection.__getitem__(self, item)
3705+
for k, v in res.content.items():
3706+
if "accelerated_fields" in k:
3707+
res.content[k] = json.loads(v)
3708+
return res
3709+
3710+
def create(self, name, accelerated_fields={}, fields={}, **kwargs):
37043711
"""Creates a KV Store Collection.
37053712
37063713
:param name: name of collection to create
37073714
:type name: ``string``
3708-
:param indexes: dictionary of index definitions
3709-
:type indexes: ``dict``
3715+
:param accelerated_fields: dictionary of accelerated_fields definitions
3716+
:type accelerated_fields: ``dict``
37103717
:param fields: dictionary of field definitions
37113718
:type fields: ``dict``
37123719
:param kwargs: a dictionary of additional parameters specifying indexes and field definitions
37133720
:type kwargs: ``dict``
37143721
37153722
:return: Result of POST request
37163723
"""
3717-
for k, v in list(indexes.items()):
3724+
for k, v in list(accelerated_fields.items()):
37183725
if isinstance(v, dict):
37193726
v = json.dumps(v)
37203727
kwargs['index.' + k] = v
@@ -3732,18 +3739,18 @@ def data(self):
37323739
"""
37333740
return KVStoreCollectionData(self)
37343741

3735-
def update_index(self, name, value):
3736-
"""Changes the definition of a KV Store index.
3742+
def update_accelerated_field(self, name, value):
3743+
"""Changes the definition of a KV Store accelerated_field.
37373744
3738-
:param name: name of index to change
3745+
:param name: name of accelerated_fields to change
37393746
:type name: ``string``
3740-
:param value: new index definition
3741-
:type value: ``dict`` or ``string``
3747+
:param value: new accelerated_fields definition
3748+
:type value: ``dict``
37423749
37433750
:return: Result of POST request
37443751
"""
37453752
kwargs = {}
3746-
kwargs['index.' + name] = value if isinstance(value, str) else json.dumps(value)
3753+
kwargs['accelerated_fields.' + name] = value if isinstance(value, str) else json.dumps(value)
37473754
return self.post(**kwargs)
37483755

37493756
def update_field(self, name, value):

tests/test_binding.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,12 @@ def test_ipv6_host(self):
184184
host="2001:0db8:85a3:0000:0000:8a2e:0370:7334"),
185185
"https://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8089")
186186

187+
def test_ipv6_host_enclosed(self):
188+
self.assertEqual(
189+
binding._authority(
190+
host="[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"),
191+
"https://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:8089")
192+
187193
def test_all_fields(self):
188194
self.assertEqual(
189195
binding._authority(

tests/test_kvstore_conf.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# License for the specific language governing permissions and limitations
1515
# under the License.
1616

17+
import json
1718
from tests import testlib
1819
from splunklib import client
1920

@@ -37,11 +38,26 @@ def test_create_delete_collection(self):
3738
self.confs['test'].delete()
3839
self.assertTrue('test' not in self.confs)
3940

41+
def test_create_fields(self):
42+
self.confs.create('test', accelerated_fields={'ind1':{'a':1}}, fields={'a':'number1'})
43+
self.assertEqual(self.confs['test']['field.a'], 'number1')
44+
self.assertEqual(self.confs['test']['accelerated_fields.ind1'], {"a": 1})
45+
self.confs['test'].delete()
46+
4047
def test_update_collection(self):
4148
self.confs.create('test')
42-
self.confs['test'].post(**{'accelerated_fields.ind1': '{"a": 1}', 'field.a': 'number'})
49+
val = {"a": 1}
50+
self.confs['test'].post(**{'accelerated_fields.ind1': json.dumps(val), 'field.a': 'number'})
4351
self.assertEqual(self.confs['test']['field.a'], 'number')
44-
self.assertEqual(self.confs['test']['accelerated_fields.ind1'], '{"a": 1}')
52+
self.assertEqual(self.confs['test']['accelerated_fields.ind1'], {"a": 1})
53+
self.confs['test'].delete()
54+
55+
def test_update_accelerated_fields(self):
56+
self.confs.create('test', accelerated_fields={'ind1':{'a':1}})
57+
self.assertEqual(self.confs['test']['accelerated_fields.ind1'], {'a': 1})
58+
# update accelerated_field value
59+
self.confs['test'].update_accelerated_field('ind1', {'a': -1})
60+
self.assertEqual(self.confs['test']['accelerated_fields.ind1'], {'a': -1})
4561
self.confs['test'].delete()
4662

4763
def test_update_fields(self):
@@ -70,17 +86,6 @@ def test_overlapping_collections(self):
7086
self.confs['test'].delete()
7187
self.confs['test'].delete()
7288

73-
"""
74-
def test_create_accelerated_fields_fields(self):
75-
self.confs.create('test', indexes={'foo': '{"foo": 1}', 'bar': {'bar': -1}}, **{'field.foo': 'string'})
76-
self.assertEqual(self.confs['test']['accelerated_fields.foo'], '{"foo": 1}')
77-
self.assertEqual(self.confs['test']['field.foo'], 'string')
78-
self.assertRaises(client.HTTPError, lambda: self.confs['test'].post(**{'accelerated_fields.foo': 'THIS IS INVALID'}))
79-
self.assertEqual(self.confs['test']['accelerated_fields.foo'], '{"foo": 1}')
80-
self.confs['test'].update_accelerated_fields('foo', '')
81-
self.assertEqual(self.confs['test']['accelerated_fields.foo'], None)
82-
"""
83-
8489
def tearDown(self):
8590
if 'test' in self.confs:
8691
self.confs['test'].delete()

0 commit comments

Comments
 (0)