Skip to content

Commit 13dcd5f

Browse files
BREAKING CHANGE: remove btool and replace it with splunk.rest (#441)
**Issue number: [ADDON-79884](https://splunk.atlassian.net/browse/ADDON-79884)** ### PR Type **What kind of change does this PR introduce?** * [ ] Feature * [x] Bug Fix * [ ] Refactoring (no functional or API changes) * [ ] Documentation Update * [ ] Maintenance (dependency updates, CI, etc.) ## Summary ### Changes `solnlib` will no longer use Splunk's `btool`. `btool` was replaced with configuration endpoint from Splunk `splunk.rest` module. Since `session_key` is required for an authorization, `solnlib` no longer supports `get_session_key()` function. Also function `make_splunkhome_path` will now use native Splunk's implementation from `splunk.clilib.bundle_paths` ### User experience It's a breaking change for the user as functions related to getting stanza from config files will now required `app_name` and `session_key` to work properly. If users uses `get_session_key()` from `solnlib` they will need to replace it with their own implementation. ## Checklist introduced new method `_get_conf_stanzas_from_splunk_api` Following functions will now require app_name and/or session_key as a arguments to work: * get_conf_stanza * get_conf_key_value * get_splunkd_uri * get_scheme_from_hec_settings * get_splunkd_access_info * get_splunk_host_info make_splunkhome_path() now uses `splunk.clilib.bundle_paths.make_splunkhome_path` ### Review * [x] self-review - I have performed a self-review of this change according to the [development guidelines](https://splunk.github.io/addonfactory-ucc-generator/contributing/#development-guidelines) * [ ] Changes are documented. The documentation is understandable, examples work [(more info)](https://splunk.github.io/addonfactory-ucc-generator/contributing/#documentation-guidelines) * [x] PR title and description follows the [contributing principles](https://splunk.github.io/addonfactory-ucc-generator/contributing/#pull-requests) * [ ] meeting - I have scheduled a meeting or recorded a demo to explain these changes (if there is a video, put a link below and in the ticket) ### Tests See [the testing doc](https://splunk.github.io/addonfactory-ucc-generator/contributing/#build-and-test). * [ ] Unit - tests have been added/modified to cover the changes * [ ] Smoke - tests have been added/modified to cover the changes * [ ] UI - tests have been added/modified to cover the changes * [x] coverage - I have checked the code coverage of my changes [(see more)](https://splunk.github.io/addonfactory-ucc-generator/contributing/#checking-the-code-coverage) **Demo/meeting:** *Reviewers are encouraged to request meetings or demos if any part of the change is unclear*
2 parents 6c06546 + aeb46d8 commit 13dcd5f

27 files changed

+695
-266
lines changed

docs/release_7_0_0.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Removed usage of btool command from solnlib
2+
3+
As of version 7.0.0, the `btool` command has been removed from solnlib. Configuration stanzas and keys should now be accessed via the REST API.
4+
Additionally, the `splunkenv` module can only be used in environments where Splunk is installed, as it relies on Splunk-specific methods for making internal calls.
5+
6+
## Session key is now mandatory in some of the functions
7+
8+
The affected functions now require a valid `session_key` to operate correctly. While solnlib attempts to retrieve the `session_key` automatically,
9+
there are scenarios—such as within a modular input script—where this is not possible. In such cases, you must explicitly provide the `session_key`
10+
to ensure proper authorization. Affected functions are:
11+
12+
* `get_splunk_host_info`
13+
* `get_splunkd_access_info`
14+
* `get_scheme_from_hec_settings`
15+
* `get_splunkd_uri`
16+
* `get_conf_key_value`
17+
* `get_conf_stanza`
18+
19+
## Changed arguments in `get_conf_key_value` and `get_conf_stanza`
20+
21+
As of version 7.0.0, the following changes have been made to the function:
22+
23+
`get_conf_key_value` now requires 4 mandatory arguments:
24+
25+
* `conf_name`
26+
* `stanza`
27+
* `key`
28+
* `app_name` (new)
29+
30+
`get_conf_stanza` now requires 3 mandatory arguments:
31+
32+
* `conf_name`
33+
* `stanza`
34+
* `app_name` (new)
35+
36+
Both functions also accept the following optional arguments:
37+
38+
* `session_key` - Used for authentication. If not provided, a 401 Unauthorized error may occur depending on the context.
39+
* `users` - Limits results returned by the configuration endpoint. Defaults to `nobody`.
40+
* `raw_output` - If set to `True`, the full decoded JSON response is returned.
41+
This should be enabled when `app_name` is set to the global context `(/-/)`, as the Splunk REST API may return multiple entries in that case.
42+
43+
## The `get_session_key` function has been removed from solnlib
44+
45+
This function relied on reading the `scheme`, `host` and `port` using the deprecated btool utility, which is no longer supported.
46+

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ plugins:
3131
nav:
3232
- Home: index.md
3333
- Release 6.0.0: release_6_0_0.md
34+
- Release 7.0.0: release_7_0_0.md
3435
- References:
3536
- modular_input:
3637
- "checkpointer.py": modular_input/checkpointer.md

solnlib/_settings.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#
2+
# Copyright 2025 Splunk Inc.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
"""This module provide settings that can be used to disable/switch features."""
17+
18+
use_btool = False

solnlib/credentials.py

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,19 @@
1616

1717
"""This module contains Splunk credential related interfaces."""
1818

19-
import json
2019
import re
2120
import warnings
2221
from typing import Dict, List
2322

2423
from splunklib import binding, client
2524

2625
from . import splunk_rest_client as rest_client
27-
from .net_utils import validate_scheme_host_port
28-
from .splunkenv import get_splunkd_access_info
2926
from .utils import retry
3027

3128
__all__ = [
3229
"CredentialException",
3330
"CredentialNotExistException",
3431
"CredentialManager",
35-
"get_session_key",
3632
]
3733

3834

@@ -339,56 +335,3 @@ def _get_all_passwords(self) -> List[Dict[str, str]]:
339335
)
340336
passwords = self._storage_passwords.list(count=-1)
341337
return self._get_clear_passwords(passwords)
342-
343-
344-
@retry(exceptions=[binding.HTTPError])
345-
def get_session_key(
346-
username: str,
347-
password: str,
348-
scheme: str = None,
349-
host: str = None,
350-
port: int = None,
351-
**context: dict,
352-
) -> str:
353-
"""Get splunkd access token.
354-
355-
Arguments:
356-
username: The Splunk account username, which is used to authenticate the Splunk instance.
357-
password: The Splunk account password.
358-
scheme: (optional) The access scheme, default is None.
359-
host: (optional) The host name, default is None.
360-
port: (optional) The port number, default is None.
361-
context: Other configurations for Splunk rest client.
362-
363-
Returns:
364-
Splunk session key.
365-
366-
Raises:
367-
CredentialException: If username/password are invalid.
368-
ValueError: if scheme, host or port are invalid.
369-
370-
Examples:
371-
>>> get_session_key('user', 'password')
372-
"""
373-
validate_scheme_host_port(scheme, host, port)
374-
375-
if any([scheme is None, host is None, port is None]):
376-
scheme, host, port = get_splunkd_access_info()
377-
378-
uri = "{scheme}://{host}:{port}/{endpoint}".format(
379-
scheme=scheme, host=host, port=port, endpoint="services/auth/login"
380-
)
381-
_rest_client = rest_client.SplunkRestClient(
382-
None, "-", "nobody", scheme, host, port, **context
383-
)
384-
try:
385-
response = _rest_client.http.post(
386-
uri, username=username, password=password, output_mode="json"
387-
)
388-
except binding.HTTPError as e:
389-
if e.status != 401:
390-
raise
391-
392-
raise CredentialException("Invalid username/password.")
393-
394-
return json.loads(response.body.read())["sessionKey"]

solnlib/modular_input/event_writer.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import threading
2424
import time
2525
import traceback
26+
import warnings
2627
from abc import ABCMeta, abstractmethod
2728
from random import randint
2829
from typing import List, Union
@@ -39,6 +40,16 @@
3940
__all__ = ["ClassicEventWriter", "HECEventWriter"]
4041

4142

43+
deprecation_msg = (
44+
"Function 'create_from_token' is deprecated and incompatible with 'global_settings_schema=True'. "
45+
"Use 'create_from_token_with_session_key' instead."
46+
)
47+
48+
49+
class FunctionDeprecated(Exception):
50+
pass
51+
52+
4253
class EventWriter(metaclass=ABCMeta):
4354
"""Base class of event writer."""
4455

@@ -233,13 +244,13 @@ def __init__(
233244
scheme, host, hec_port = utils.extract_http_scheme_host_port(hec_uri)
234245
else:
235246
if not all([scheme, host, port]):
236-
scheme, host, port = get_splunkd_access_info()
247+
scheme, host, port = get_splunkd_access_info(self._session_key)
237248
hec_port, hec_token = self._get_hec_config(
238249
hec_input_name, session_key, scheme, host, port, **context
239250
)
240251

241252
if global_settings_schema:
242-
scheme = get_scheme_from_hec_settings()
253+
scheme = get_scheme_from_hec_settings(self._session_key)
243254

244255
if not context.get("pool_connections"):
245256
context["pool_connections"] = 10
@@ -272,6 +283,11 @@ def create_from_token(
272283
Created HECEventWriter.
273284
"""
274285

286+
warnings.warn(deprecation_msg, DeprecationWarning, stacklevel=2)
287+
288+
if global_settings_schema:
289+
raise FunctionDeprecated(deprecation_msg)
290+
275291
return HECEventWriter(
276292
None,
277293
None,

solnlib/server_info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def __init__(
7878
"""
7979
is_localhost = False
8080
if not all([scheme, host, port]) and os.environ.get("SPLUNK_HOME"):
81-
scheme, host, port = get_splunkd_access_info()
81+
scheme, host, port = get_splunkd_access_info(session_key)
8282
is_localhost = (
8383
host == "localhost" or host == "127.0.0.1" or host in ("::1", "[::1]")
8484
)

solnlib/splunk_rest_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ def __init__(
221221
"""
222222
# Only do splunkd URI discovery in SPLUNK env (SPLUNK_HOME is set).
223223
if not all([scheme, host, port]) and os.environ.get("SPLUNK_HOME"):
224-
scheme, host, port = get_splunkd_access_info()
224+
scheme, host, port = get_splunkd_access_info(session_key)
225225
if os.environ.get("SPLUNK_HOME") is None:
226226
if not all([scheme, host, port]):
227227
raise ValueError(

0 commit comments

Comments
 (0)