Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 18 additions & 1 deletion inventory/environ.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down
1 change: 1 addition & 0 deletions inventory/splunk_defaults_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ splunk:
search_factor: 3
replication_factor: 3
replication_port: 9887
replication_ssl: False
dfs:
enable: False
port: 9000
Expand Down
1 change: 1 addition & 0 deletions inventory/splunk_defaults_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 17 additions & 1 deletion roles/splunk_indexer/tasks/indexer_clustering.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}"
Expand All @@ -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
Expand Down
17 changes: 16 additions & 1 deletion roles/splunk_indexer/tasks/setup_multisite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}"
Expand All @@ -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 }}"
Expand Down
6 changes: 6 additions & 0 deletions tests/small/test_environ.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down