From 0724a3d1bf34a84887953956a29ffd2db7990f78 Mon Sep 17 00:00:00 2001 From: Wellington Castello Date: Sat, 5 Jan 2019 22:51:44 -0800 Subject: [PATCH 1/6] Use __ when **query params are like owner/app/... When one of the query parameters is, for instance, owner, app or sharing, as when sending a POST request to the + /acl for updating permissions, this call would normally fail because those are stripped out of the actual self.http.post() and used only for self._abspath(). This is a workaround for calling post() with those parameters starting with __. The query dict is then rebuilt stripping the __ so that in the end both self._abspath() and self.http.post() can receive owner, app and sharing arguments. --- splunklib/binding.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/splunklib/binding.py b/splunklib/binding.py index 5a29387fd..d9eb439c1 100644 --- a/splunklib/binding.py +++ b/splunklib/binding.py @@ -746,6 +746,8 @@ def post(self, path_segment, owner=None, app=None, sharing=None, headers=None, * if headers is None: headers = [] + query = { key.lstrip('__'): val for key, val in query.items() } + 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.additional_headers + self._auth_headers From 0ea49cac11b0a21fab9f43e9184169ae0819c048 Mon Sep 17 00:00:00 2001 From: Wellington Castello Date: Sat, 5 Jan 2019 22:56:51 -0800 Subject: [PATCH 2/6] Add an access_update() method to Entity This access_update() uses service.post() as changed in https://github.com/wcastello/splunk-sdk-python/commit/0724a3d1bf34a84887953956a29ffd2db7990f78 --- splunklib/client.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/splunklib/client.py b/splunklib/client.py index 1e624ba42..146a56e81 100644 --- a/splunklib/client.py +++ b/splunklib/client.py @@ -1040,6 +1040,29 @@ def access(self): ``owner``, ``app``, and ``sharing``. """ return self.state.access + + def access_update(self, **kwargs): + """Updates the server with the ACL along arguments you specify. + + :param kwargs: ACL specific arguments (optional). + :type kwargs: ``dict`` + + :return: The entity this method is called on. + :rtype: class:`Entity` + + **Example**:: + + import splunklib.client as client + s = client.connect(...) + search = s.apps['search'] + search.access_update(**{'owner': 'new_owner', 'perms.read': 'admin, power', perms.write: '*'}) + """ + kwargs = {'__' + key if key == 'owner' or key == 'app' or key == 'sharing' else key: val for key, val in kwargs.items()} + kwargs['__owner'] = kwargs.get('__owner', self.access.get('owner')) + kwargs['__app'] = kwargs.get('__app', self.access.get('app')) + kwargs['__sharing'] = kwargs.get('__sharing', self.access('sharing')) + self.service.post(self.path + 'acl', **kwargs) + return self @property def content(self): From 6d9462cb5ad352892d2a5b6fbdc0d5b6b15e4e1d Mon Sep 17 00:00:00 2001 From: Wellington Castello Date: Sat, 5 Jan 2019 23:21:29 -0800 Subject: [PATCH 3/6] Change __ to _dup__ prefix to avoid conflicts --- splunklib/binding.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/splunklib/binding.py b/splunklib/binding.py index d9eb439c1..0077a3dfe 100644 --- a/splunklib/binding.py +++ b/splunklib/binding.py @@ -746,7 +746,7 @@ def post(self, path_segment, owner=None, app=None, sharing=None, headers=None, * if headers is None: headers = [] - query = { key.lstrip('__'): val for key, val in query.items() } + query = { key.lstrip('_dup__'): val for key, val in query.items() } path = self.authority + self._abspath(path_segment, owner=owner, app=app, sharing=sharing) logging.debug("POST request to %s (body: %s)", path, repr(query)) From d5dd4a2d78baea37b967f88a3e920d4348356d01 Mon Sep 17 00:00:00 2001 From: Wellington Castello Date: Sat, 5 Jan 2019 23:25:33 -0800 Subject: [PATCH 4/6] Use _dup__ as per service.post for app/sharing/... Use _dup__ as per service.post for app/sharing/owner arguments that need to be sent to http.post() --- splunklib/client.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/splunklib/client.py b/splunklib/client.py index 146a56e81..fa52681b3 100644 --- a/splunklib/client.py +++ b/splunklib/client.py @@ -1057,10 +1057,10 @@ def access_update(self, **kwargs): search = s.apps['search'] search.access_update(**{'owner': 'new_owner', 'perms.read': 'admin, power', perms.write: '*'}) """ - kwargs = {'__' + key if key == 'owner' or key == 'app' or key == 'sharing' else key: val for key, val in kwargs.items()} - kwargs['__owner'] = kwargs.get('__owner', self.access.get('owner')) - kwargs['__app'] = kwargs.get('__app', self.access.get('app')) - kwargs['__sharing'] = kwargs.get('__sharing', self.access('sharing')) + kwargs = {'_dup__' + key if key == 'owner' or key == 'app' or key == 'sharing' else key: val for key, val in kwargs.items()} + kwargs['_dup__owner'] = kwargs.get('_dup__owner', self.access.get('owner')) + kwargs['_dup__app'] = kwargs.get('_dup__app', self.access.get('app')) + kwargs['_dup__sharing'] = kwargs.get('_dup__sharing', self.access('sharing')) self.service.post(self.path + 'acl', **kwargs) return self From e5fb7272cac5763fe9c48fc88d4a612230ed313f Mon Sep 17 00:00:00 2001 From: Wellington Castello Date: Sun, 6 Jan 2019 00:00:57 -0800 Subject: [PATCH 5/6] replace() instead of lstrip() my bad, lstrip() clearly doesn't make sense as it takes chars as arguments not a full prefix so 'password'.lstrip('_dup__') == 'assword' --- splunklib/binding.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/splunklib/binding.py b/splunklib/binding.py index 0077a3dfe..f3e07c5cc 100644 --- a/splunklib/binding.py +++ b/splunklib/binding.py @@ -746,7 +746,7 @@ def post(self, path_segment, owner=None, app=None, sharing=None, headers=None, * if headers is None: headers = [] - query = { key.lstrip('_dup__'): val for key, val in query.items() } + query = { key.replace('_dup__', ''): val for key, val in query.items() } path = self.authority + self._abspath(path_segment, owner=owner, app=app, sharing=sharing) logging.debug("POST request to %s (body: %s)", path, repr(query)) From d6cd7acde63d9437fe55c8a6acd1194520bcf6b3 Mon Sep 17 00:00:00 2001 From: Wellington Castello Date: Sun, 6 Jan 2019 00:03:50 -0800 Subject: [PATCH 6/6] missed .get() missed .get on self.access for 'sharing' --- splunklib/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/splunklib/client.py b/splunklib/client.py index fa52681b3..3e245404a 100644 --- a/splunklib/client.py +++ b/splunklib/client.py @@ -1060,7 +1060,7 @@ def access_update(self, **kwargs): kwargs = {'_dup__' + key if key == 'owner' or key == 'app' or key == 'sharing' else key: val for key, val in kwargs.items()} kwargs['_dup__owner'] = kwargs.get('_dup__owner', self.access.get('owner')) kwargs['_dup__app'] = kwargs.get('_dup__app', self.access.get('app')) - kwargs['_dup__sharing'] = kwargs.get('_dup__sharing', self.access('sharing')) + kwargs['_dup__sharing'] = kwargs.get('_dup__sharing', self.access.get('sharing')) self.service.post(self.path + 'acl', **kwargs) return self