From d4687b5a3e3db3ab44818c6e270f984ce382f024 Mon Sep 17 00:00:00 2001 From: "igor.grzankowski" <@splunk.com> Date: Thu, 23 Oct 2025 16:15:25 +0200 Subject: [PATCH 1/2] replication optional --- inventory/splunk_defaults_linux.yml | 1 + inventory/splunk_defaults_windows.yml | 1 + .../tasks/indexer_clustering.yml | 18 +++++++++++++++++- roles/splunk_indexer/tasks/setup_multisite.yml | 17 ++++++++++++++++- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/inventory/splunk_defaults_linux.yml b/inventory/splunk_defaults_linux.yml index 374204ac..f55ce977 100644 --- a/inventory/splunk_defaults_linux.yml +++ b/inventory/splunk_defaults_linux.yml @@ -97,6 +97,7 @@ splunk: search_factor: 3 replication_factor: 3 replication_port: 9887 + replication_ssl: False dfs: enable: False port: 9000 diff --git a/inventory/splunk_defaults_windows.yml b/inventory/splunk_defaults_windows.yml index f3f49bb5..6f049f9d 100644 --- a/inventory/splunk_defaults_windows.yml +++ b/inventory/splunk_defaults_windows.yml @@ -95,6 +95,7 @@ splunk: search_factor: 3 replication_factor: 3 replication_port: 9887 + replication_ssl: False multisite_replication_factor_origin: 2 multisite_replication_factor_total: 3 multisite_search_factor_origin: 1 diff --git a/roles/splunk_indexer/tasks/indexer_clustering.yml b/roles/splunk_indexer/tasks/indexer_clustering.yml index 4f5811ac..58686e12 100644 --- a/roles/splunk_indexer/tasks/indexer_clustering.yml +++ b/roles/splunk_indexer/tasks/indexer_clustering.yml @@ -3,7 +3,7 @@ vars: splunk_instance_address: "{{ splunk.cluster_master_url }}" -- name: Set current node as indexer cluster peer +- name: Set current node as indexer cluster peer (non-SSL replication) command: "{{ splunk.exec }} edit cluster-config -mode slave -master_uri '{{ cert_prefix }}://{{ splunk.cluster_master_url }}:{{ splunk.svc_port }}' -replication_port {{ splunk.idxc.replication_port }} -secret '{{ splunk.idxc.pass4SymmKey }}' -auth '{{ splunk.admin_user }}:{{ splunk.password }}'" become: yes become_user: "{{ splunk.user }}" @@ -12,6 +12,22 @@ until: task_result.rc == 0 retries: "{{ retry_num }}" delay: "{{ retry_delay }}" + when: not splunk.idxc.replication_ssl | default(false) | bool + ignore_errors: yes + notify: + - Restart the splunkd service + no_log: "{{ hide_password }}" + +- name: Set current node as indexer cluster peer (SSL replication) + command: "{{ splunk.exec }} edit cluster-config -mode slave -master_uri '{{ cert_prefix }}://{{ splunk.cluster_master_url }}:{{ splunk.svc_port }}' -secret '{{ splunk.idxc.pass4SymmKey }}' -auth '{{ splunk.admin_user }}:{{ splunk.password }}'" + become: yes + become_user: "{{ splunk.user }}" + register: task_result_ssl + changed_when: task_result_ssl.rc == 0 + until: task_result_ssl.rc == 0 + retries: "{{ retry_num }}" + delay: "{{ retry_delay }}" + when: splunk.idxc.replication_ssl | default(false) | bool ignore_errors: yes notify: - Restart the splunkd service diff --git a/roles/splunk_indexer/tasks/setup_multisite.yml b/roles/splunk_indexer/tasks/setup_multisite.yml index 8f371bfa..fa105aa8 100644 --- a/roles/splunk_indexer/tasks/setup_multisite.yml +++ b/roles/splunk_indexer/tasks/setup_multisite.yml @@ -7,7 +7,7 @@ set_fact: multisite_master_uri: "{{ cert_prefix }}://{{ splunk.multisite_master }}:{{ splunk.svc_port }}" -- name: Setup Peers with Associated Site +- name: Setup Peers with Associated Site (non-SSL replication) command: "{{ splunk.exec }} edit cluster-config -mode slave -site {{ splunk.site }} -master_uri {{ multisite_master_uri }} -replication_port {{ splunk.idxc.replication_port }} -auth {{ splunk.admin_user }}:{{ splunk.password }} -secret {{ splunk.idxc.pass4SymmKey }}" become: yes become_user: "{{ splunk.user }}" @@ -16,6 +16,21 @@ until: task_result.rc == 0 retries: "{{ retry_num }}" delay: "{{ retry_delay }}" + when: not splunk.idxc.replication_ssl | default(false) | bool + notify: + - Restart the splunkd service + no_log: "{{ hide_password }}" + +- name: Setup Peers with Associated Site (SSL replication) + command: "{{ splunk.exec }} edit cluster-config -mode slave -site {{ splunk.site }} -master_uri {{ multisite_master_uri }} -auth {{ splunk.admin_user }}:{{ splunk.password }} -secret {{ splunk.idxc.pass4SymmKey }}" + become: yes + become_user: "{{ splunk.user }}" + register: task_result_ssl + changed_when: task_result_ssl.rc == 0 + until: task_result_ssl.rc == 0 + retries: "{{ retry_num }}" + delay: "{{ retry_delay }}" + when: splunk.idxc.replication_ssl | default(false) | bool notify: - Restart the splunkd service no_log: "{{ hide_password }}" From 2f22e00ed2fa49169e9fe57dbb059d0443f4127e Mon Sep 17 00:00:00 2001 From: Gabriel J Mendoza Date: Wed, 10 Dec 2025 16:45:23 -0500 Subject: [PATCH 2/2] CSPL-4007: Fixing found bug that involves replication port config getting overwritten. --- inventory/environ.py | 19 ++++++++++++++++++- tests/small/test_environ.py | 6 ++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/inventory/environ.py b/inventory/environ.py index 66d51de3..9b90c1d7 100755 --- a/inventory/environ.py +++ b/inventory/environ.py @@ -700,7 +700,11 @@ def parseUrl(url, vars_scope): def merge_dict(dict1, dict2, path=None): """ - Merge two dictionaries such that all the keys in dict2 overwrite those in dict1 + Merge two dictionaries such that all the keys in dict2 overwrite those in dict1. + + Special handling: + - If dict1[key] is a dict and dict2[key] is None (empty YAML section), preserve dict1[key] + - If dict1[key] is a dict and dict2[key] is a list, merge list items into dict1[key] """ if path is None: path = [] for key in dict2: @@ -709,6 +713,19 @@ def merge_dict(dict1, dict2, path=None): merge_dict(dict1[key], dict2[key], path + [str(key)]) elif isinstance(dict1[key], list) and isinstance(dict2[key], list): dict1[key] += dict2[key] + elif isinstance(dict1[key], dict) and dict2[key] is None: + # Preserve dict1[key] when dict2[key] is None (empty YAML section) + # This prevents losing default values when ConfigMap has empty sections + pass + elif isinstance(dict1[key], dict) and isinstance(dict2[key], list): + # Handle list-based format: merge each list item (dict) into dict1[key] + # This supports ConfigMap formats like: + # idxc: + # - secret: value1 + # - pass4SymmKey: value2 + for item in dict2[key]: + if isinstance(item, dict): + merge_dict(dict1[key], item, path + [str(key)]) else: dict1[key] = dict2[key] else: diff --git a/tests/small/test_environ.py b/tests/small/test_environ.py index 78632a5f..071fff41 100644 --- a/tests/small/test_environ.py +++ b/tests/small/test_environ.py @@ -1065,6 +1065,12 @@ def test_parseUrl(url, vars_scope, output): ({"nested": {"x": 10, "array": [1, 2]}}, {"nested": {"y": 20, "array": [3, 4, 5]}}, {"nested": {"x": 10, "y": 20, "array": [1, 2, 3, 4, 5]}}), # Targeted github bug ({"splunk": {"conf": [{"key": "fileA", "content": {"a": "b", "c": "d"}}]}}, {"splunk": {"conf": [{"key": "fileB", "content": {"e": "f", "g": "h"}}]}}, {"splunk": {"conf": [{"key": "fileA", "content": {"a": "b", "c": "d"}}, {"key": "fileB", "content": {"e": "f", "g": "h"}}]}}), + # CSPL-4007: When dict2[key] is None (empty YAML section), preserve dict1[key] + ({"splunk": {"idxc": {"replication_port": 9887, "secret": None}}}, {"splunk": {"idxc": None}}, {"splunk": {"idxc": {"replication_port": 9887, "secret": None}}}), + # CSPL-4007: When dict2[key] is a list of dicts, merge each item into dict1[key] + ({"splunk": {"idxc": {"replication_port": 9887, "secret": None}}}, {"splunk": {"idxc": [{"secret": "mysecret"}, {"pass4SymmKey": "mykey"}]}}, {"splunk": {"idxc": {"replication_port": 9887, "secret": "mysecret", "pass4SymmKey": "mykey"}}}), + # CSPL-4007: Deep nested None preservation + ({"a": {"b": {"c": 1, "d": 2}}}, {"a": {"b": None}}, {"a": {"b": {"c": 1, "d": 2}}}), ] ) def test_merge_dict(dict1, dict2, result):