#!/usr/bin/env python
'''
Unit tests for inventory/environ.py
'''
from __future__ import absolute_import
import os
import sys
import pytest
import requests
from mock import MagicMock, patch, mock_open
FILE_DIR = os.path.dirname(os.path.realpath(__file__))
#FIXTURES_DIR = os.path.join(FILE_DIR, "fixtures")
REPO_DIR = os.path.join(FILE_DIR, "..", "..")
# Add environ.py into path for testing
sys.path.append(os.path.join(REPO_DIR, "inventory"))
import environ
@pytest.mark.parametrize(("regex", "result"),
[
(r"(FOOBAR)", {"foobar": "123"}),
(r"^FOO(.*)", {"bar": "123"}),
]
)
def test_getVars(regex, result):
'''
This method makes the assumption that there will always be a group(1),
So if doing an exact string match, for now group the entire string
'''
with patch("os.environ", new={"FOOBAR": "123", "BARFOO": "456"}):
r = environ.getVars(regex)
assert r == result
@pytest.mark.skip(reason="TODO")
def test_getSplunkInventory():
pass
@patch('environ.loadDefaults', return_value={"splunk": {"http_port": 8000, "build_location": None}})
@patch('environ.overrideEnvironmentVars')
@patch('environ.getSecrets')
@patch('environ.getHEC')
def test_getDefaultVars(mock_overrideEnvironmentVars, mock_loadDefaultSplunkVariables, mock_getSecrets, mock_getHEC):
'''
Unit test for getting our default variables
'''
retval = environ.getDefaultVars()
assert "splunk" in retval
@pytest.mark.parametrize(("default_yml", "os_env", "output"),
[
# Check null parameters
({}, {}, {"opt": None, "home": None, "exec": None, "pid": None}),
# Check default.yml parameters
({"opt": "/opt"}, {}, {"opt": "/opt", "home": None, "exec": None, "pid": None}),
({"home": "/tmp/splunk"}, {}, {"opt": None, "home": "/tmp/splunk", "exec": None, "pid": None}),
({"exec": "/opt/splunk/bin/splunk"}, {}, {"opt": None, "home": None, "exec": "/opt/splunk/bin/splunk", "pid": None}),
({"pid": "/splunk.pid"}, {}, {"opt": None, "home": None, "exec": None, "pid": "/splunk.pid"}),
# Check environment variable parameters
({}, {"SPLUNK_OPT": "/home/"}, {"opt": "/home/", "home": None, "exec": None, "pid": None}),
({}, {"SPLUNK_HOME": "/home/"}, {"opt": None, "home": "/home/", "exec": None, "pid": None}),
({}, {"SPLUNK_EXEC": "/home/splunk.exe"}, {"opt": None, "home": None, "exec": "/home/splunk.exe", "pid": None}),
({}, {"SPLUNK_PID": "/home/splunk.pid"}, {"opt": None, "home": None, "exec": None, "pid": "/home/splunk.pid"}),
# Check the union combination of default.yml + environment variables and order of precedence when overwriting
({"opt": "/home"}, {"SPLUNK_OPT": "/opt"}, {"opt": "/opt", "home": None, "exec": None, "pid": None}),
({"home": "/tmp/splunk"}, {"SPLUNK_HOME": "/opt/splunk"}, {"opt": None, "home": "/opt/splunk", "exec": None, "pid": None}),
({"exec": "/bin/splunk"}, {"SPLUNK_EXEC": "/opt/splunk/bin/splunk"}, {"opt": None, "home": None, "exec": "/opt/splunk/bin/splunk", "pid": None}),
({"pid": "/splunk.pid"}, {"SPLUNK_PID": "/opt/splunk/splunk.pid"}, {"opt": None, "home": None, "exec": None, "pid": "/opt/splunk/splunk.pid"}),
]
)
def test_getSplunkPaths(default_yml, os_env, output):
vars_scope = {"splunk": default_yml}
with patch("os.environ", new=os_env):
environ.getSplunkPaths(vars_scope)
assert type(vars_scope["splunk"]) == dict
assert vars_scope["splunk"] == output
@pytest.mark.parametrize(("default_yml", "os_env", "output"),
[
# Check null parameters
({}, {}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1, "search_factor": 1}),
# Check default.yml parameters
({"idxc": {}}, {}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1, "search_factor": 1}),
({"idxc": {"label": None}}, {}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1, "search_factor": 1}),
({"idxc": {"label": "1234"}}, {}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": "1234", "secret": None, "replication_factor": 1, "search_factor": 1}),
({"idxc": {"secret": None}}, {}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1, "search_factor": 1}),
({"idxc": {"secret": "1234"}}, {}, {"pass4SymmKey": "1234", "discoveryPass4SymmKey": "1234", "label": None, "secret": "1234", "replication_factor": 1, "search_factor": 1}),
({"idxc": {"pass4SymmKey": None}}, {}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1, "search_factor": 1}),
({"idxc": {"pass4SymmKey": "1234"}}, {}, {"pass4SymmKey": "1234", "discoveryPass4SymmKey": "1234", "label": None, "secret": "1234", "replication_factor": 1, "search_factor": 1}),
({"idxc": {"discoveryPass4SymmKey": None}}, {}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1, "search_factor": 1}),
({"idxc": {"discoveryPass4SymmKey": "1234"}}, {}, {"pass4SymmKey": None, "discoveryPass4SymmKey": "1234", "label": None, "secret": None, "replication_factor": 1, "search_factor": 1}),
# Search factor should never exceed replication factor
({"idxc": {"replication_factor": 0, "search_factor": 2}}, {}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 0, "search_factor": 0}),
({"idxc": {"replication_factor": 1, "search_factor": 3}}, {}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1, "search_factor": 1}),
({"idxc": {"replication_factor": "2", "search_factor": 3}}, {}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 2, "search_factor": 2}),
# This should return replication_factor=2 because there are only 2 hosts in the "splunk_indexer" group
({"idxc": {"replication_factor": 3, "search_factor": 1}}, {}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 2, "search_factor": 1}),
# Check environment variable parameters
({}, {"SPLUNK_IDXC_LABEL": ""}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": "", "secret": None, "replication_factor": 1, "search_factor": 1}),
({}, {"SPLUNK_IDXC_LABEL": "abcd"}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": "abcd", "secret": None, "replication_factor": 1, "search_factor": 1}),
({}, {"SPLUNK_IDXC_SECRET": ""}, {"pass4SymmKey": "", "discoveryPass4SymmKey": "", "label": None, "secret": "", "replication_factor": 1, "search_factor": 1}),
({}, {"SPLUNK_IDXC_SECRET": "abcd"}, {"pass4SymmKey": "abcd", "discoveryPass4SymmKey": "abcd", "label": None, "secret": "abcd", "replication_factor": 1, "search_factor": 1}),
({}, {"SPLUNK_IDXC_PASS4SYMMKEY": "abcd"}, {"pass4SymmKey": "abcd", "discoveryPass4SymmKey": "abcd", "label": None, "secret": "abcd", "replication_factor": 1, "search_factor": 1}),
({}, {"SPLUNK_IDXC_REPLICATION_FACTOR": "1"}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1, "search_factor": 1}),
({}, {"SPLUNK_IDXC_REPLICATION_FACTOR": 2, "SPLUNK_IDXC_SEARCH_FACTOR": "1"}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 2, "search_factor": 1}),
({}, {"SPLUNK_IDXC_DISCOVERYPASS4SYMMKEY": "qwerty"}, {"pass4SymmKey": None, "discoveryPass4SymmKey": "qwerty", "label": None, "secret": None, "replication_factor": 1, "search_factor": 1}),
# Check the union combination of default.yml + environment variables and order of precedence when overwriting
({"idxc": {"label": "1234"}}, {"SPLUNK_IDXC_LABEL": "abcd"}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": "abcd", "secret": None, "replication_factor": 1, "search_factor": 1}),
({"idxc": {"secret": "abcd"}}, {"SPLUNK_IDXC_SECRET": "1234"}, {"pass4SymmKey": "1234", "discoveryPass4SymmKey": "1234", "label": None, "secret": "1234", "replication_factor": 1, "search_factor": 1}),
({"idxc": {"pass4SymmKey": "1234"}}, {"SPLUNK_IDXC_PASS4SYMMKEY": "abcd"}, {"pass4SymmKey": "abcd", "discoveryPass4SymmKey": "abcd", "label": None, "secret": "abcd", "replication_factor": 1, "search_factor": 1}),
({"idxc": {"pass4SymmKey": "1234", "discoveryPass4SymmKey": "7890"}}, {"SPLUNK_IDXC_PASS4SYMMKEY": "abcd"}, {"pass4SymmKey": "abcd", "discoveryPass4SymmKey": "7890", "label": None, "secret": "abcd", "replication_factor": 1, "search_factor": 1}),
({"idxc": {"pass4SymmKey": "1234", "discoveryPass4SymmKey": "7890"}}, {"SPLUNK_IDXC_DISCOVERYPASS4SYMMKEY": "zxcv", "SPLUNK_IDXC_PASS4SYMMKEY": "abcd"}, {"pass4SymmKey": "abcd", "discoveryPass4SymmKey": "zxcv", "label": None, "secret": "abcd", "replication_factor": 1, "search_factor": 1}),
({"idxc": {"secret": "abcd"}}, {"SPLUNK_IDXC_SECRET": "1234"}, {"pass4SymmKey": "1234", "discoveryPass4SymmKey": "1234", "label": None, "secret": "1234", "replication_factor": 1, "search_factor": 1}),
({"idxc": {"replication_factor": 3, "search_factor": 3}}, {"SPLUNK_IDXC_REPLICATION_FACTOR": 2}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 2, "search_factor": 2}),
({"idxc": {"replication_factor": 2, "search_factor": 2}}, {"SPLUNK_IDXC_SEARCH_FACTOR": 1}, {"pass4SymmKey": None, "discoveryPass4SymmKey": None, "label": None, "secret": None, "replication_factor": 2, "search_factor": 1}),
]
)
def test_getIndexerClustering(default_yml, os_env, output):
vars_scope = {"splunk": default_yml}
with patch("environ.inventory", {"splunk_indexer": {"hosts": ["a", "b"]}}) as mock_inven:
with patch("os.environ", new=os_env):
environ.getIndexerClustering(vars_scope)
assert type(vars_scope["splunk"]["idxc"]) == dict
assert vars_scope["splunk"]["idxc"] == output
@pytest.mark.parametrize(("default_yml", "os_env", "output"),
[
# Check null parameters
({}, {}, {"pass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1}),
# Check default.yml parameters
({"shc": {}}, {}, {"pass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1}),
({"shc": {"label": None}}, {}, {"pass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1}),
({"shc": {"label": "1234"}}, {}, {"pass4SymmKey": None, "label": "1234", "secret": None, "replication_factor": 1}),
({"shc": {"secret": None}}, {}, {"pass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1}),
({"shc": {"secret": "1234"}}, {}, {"pass4SymmKey": "1234", "label": None, "secret": "1234", "replication_factor": 1}),
({"shc": {"pass4SymmKey": None}}, {}, {"pass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1}),
({"shc": {"pass4SymmKey": "1234"}}, {}, {"pass4SymmKey": "1234", "label": None, "secret": "1234", "replication_factor": 1}),
({"shc": {"replication_factor": 0}}, {}, {"pass4SymmKey": None, "label": None, "secret": None, "replication_factor": 0}),
({"shc": {"replication_factor": 1}}, {}, {"pass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1}),
({"shc": {"replication_factor": "2"}}, {}, {"pass4SymmKey": None, "label": None, "secret": None, "replication_factor": 2}),
# This should return replication_factor=2 because there are only 2 hosts in the "splunk_search_head" group
({"shc": {"replication_factor": 3}}, {}, {"pass4SymmKey": None, "label": None, "secret": None, "replication_factor": 2}),
# Check environment variable parameters
({}, {"SPLUNK_SHC_LABEL": ""}, {"pass4SymmKey": None, "label": "", "secret": None, "replication_factor": 1}),
({}, {"SPLUNK_SHC_LABEL": "abcd"}, {"pass4SymmKey": None,"label": "abcd", "secret": None, "replication_factor": 1}),
({}, {"SPLUNK_SHC_SECRET": ""}, {"pass4SymmKey": "", "label": None, "secret": "", "replication_factor": 1}),
({}, {"SPLUNK_SHC_SECRET": "abcd"}, {"pass4SymmKey": "abcd", "label": None, "secret": "abcd", "replication_factor": 1}),
({}, {"SPLUNK_SHC_PASS4SYMMKEY": "abcd"}, {"pass4SymmKey": "abcd", "label": None, "secret": "abcd", "replication_factor": 1}),
({}, {"SPLUNK_SHC_REPLICATION_FACTOR": "2"}, {"pass4SymmKey": None, "label": None, "secret": None, "replication_factor": 2}),
# Check the union combination of default.yml + environment variables and order of precedence when overwriting
({"shc": {"label": "1234"}}, {"SPLUNK_SHC_LABEL": "abcd"}, {"pass4SymmKey": None, "label": "abcd", "secret": None, "replication_factor": 1}),
({"shc": {"secret": "abcd"}}, {"SPLUNK_SHC_SECRET": "1234"}, {"pass4SymmKey": "1234", "label": None, "secret": "1234", "replication_factor": 1}),
({"shc": {"pass4SymmKey": "1234"}}, {"SPLUNK_SHC_PASS4SYMMKEY": "abcd"}, {"pass4SymmKey": "abcd", "label": None, "secret": "abcd", "replication_factor": 1}),
({"shc": {"replication_factor": 2}}, {"SPLUNK_SHC_REPLICATION_FACTOR": "1"}, {"pass4SymmKey": None, "label": None, "secret": None, "replication_factor": 1}),
]
)
def test_getSearchHeadClustering(default_yml, os_env, output):
vars_scope = {"splunk": default_yml}
with patch("environ.inventory", {"splunk_search_head": {"hosts": ["a", "b"]}}) as mock_inven:
with patch("os.environ", new=os_env):
environ.getSearchHeadClustering(vars_scope)
assert type(vars_scope["splunk"]["shc"]) == dict
assert vars_scope["splunk"]["shc"] == output
@pytest.mark.skip(reason="TODO")
def test_getMultisite():
pass
@pytest.mark.skip(reason="TODO")
def test_getSplunkWebSSL():
pass
@pytest.mark.parametrize(("default_yml", "os_env", "output"),
[
# Check null parameters
({}, {}, {"ca": None, "cert": None, "password": None, "enable": True}),
({"does-not-exist": True}, {}, {"ca": None, "cert": None, "password": None, "enable": True}),
# Check default.yml parameters
({"ssl": {"enable": False}}, {}, {"ca": None, "cert": None, "password": None, "enable": False}),
({"ssl": {"ca": "hi"}}, {}, {"ca": "hi", "cert": None, "password": None, "enable": True}),
({"ssl": {"cert": "hi"}}, {}, {"ca": None, "cert": "hi", "password": None, "enable": True}),
({"ssl": {"password": "hi"}}, {}, {"ca": None, "cert": None, "password": "hi", "enable": True}),
({"ssl": {"ca": "aaa", "cert": "bbb", "password": "ccc", "enable": False}}, {}, {"ca": "aaa", "cert": "bbb", "password": "ccc", "enable": False}),
# Check environment variable parameters
({}, {"SPLUNKD_SSL_CA": "hi"}, {"ca": "hi", "cert": None, "password": None, "enable": True}),
({}, {"SPLUNKD_SSL_CERT": "hi"}, {"ca": None, "cert": "hi", "password": None, "enable": True}),
({}, {"SPLUNKD_SSL_PASSWORD": "hi"}, {"ca": None, "cert": None, "password": "hi", "enable": True}),
({}, {"SPLUNKD_SSL_ENABLE": "true"}, {"ca": None, "cert": None, "password": None, "enable": True}),
({}, {"SPLUNKD_SSL_ENABLE": "false"}, {"ca": None, "cert": None, "password": None, "enable": False}),
({}, {"SPLUNKD_SSL_ENABLE": "False"}, {"ca": None, "cert": None, "password": None, "enable": False}),
# Check the union combination of default.yml + environment variables and order of precedence when overwriting
({"ssl": {"ca": "value1"}}, {"SPLUNKD_SSL_CA": "value2"}, {"ca": "value2", "cert": None, "password": None, "enable": True}),
({"ssl": {"cert": "value1"}}, {"SPLUNKD_SSL_CERT": "value2"}, {"ca": None, "cert": "value2", "password": None, "enable": True}),
({"ssl": {"password": "value1"}}, {"SPLUNKD_SSL_PASSWORD": "value2"}, {"ca": None, "cert": None, "password": "value2", "enable": True}),
({}, {"SPLUNKD_SSL_ENABLE": "true"}, {"ca": None, "cert": None, "password": None, "enable": True}),
({}, {"SPLUNKD_SSL_ENABLE": "false"}, {"ca": None, "cert": None, "password": None, "enable": False}),
({"ssl": {"enable": True}}, {"SPLUNKD_SSL_ENABLE": "FALSE"}, {"ca": None, "cert": None, "password": None, "enable": False}),
({"ssl": {"enable": True}}, {"SPLUNKD_SSL_ENABLE": "FaLsE"}, {"ca": None, "cert": None, "password": None, "enable": False}),
({"ssl": {"enable": False}}, {"SPLUNKD_SSL_ENABLE": ""}, {"ca": None, "cert": None, "password": None, "enable": False}),
]
)
def test_getSplunkdSSL(default_yml, os_env, output):
vars_scope = {"splunk": default_yml}
with patch("os.environ", new=os_env):
environ.getSplunkdSSL(vars_scope)
assert type(vars_scope["splunk"]) == dict
assert type(vars_scope["splunk"]["ssl"]) == dict
assert vars_scope["splunk"]["ssl"] == output
@pytest.mark.parametrize(("default_yml", "os_env", "output"),
[
# Check null parameters - Splunk password is required
({"password": "helloworld"}, {}, {"password": "helloworld", "declarative_admin_password": False, "pass4SymmKey": None, "secret": None}),
# Check default.yml parameters
({"password": "helloworld", "pass4SymmKey": "you-will-never-guess", "secret": None}, {}, {"password": "helloworld", "declarative_admin_password": False, "pass4SymmKey": "you-will-never-guess", "secret": None}),
({"password": "helloworld", "pass4SymmKey": "you-will-never-guess", "secret": "1234"}, {}, {"password": "helloworld", "declarative_admin_password": False, "pass4SymmKey": "you-will-never-guess", "secret": "1234"}),
({"password": "helloworld", "secret": "1234"}, {}, {"password": "helloworld", "declarative_admin_password": False, "pass4SymmKey": None, "secret": "1234"}),
({"password": "helloworld", "declarative_admin_password": True, "pass4SymmKey": "you-will-never-guess", "secret": None}, {}, {"password": "helloworld", "declarative_admin_password": True, "pass4SymmKey": "you-will-never-guess", "secret": None}),
({"password": "helloworld", "declarative_admin_password": True, "pass4SymmKey": "you-will-never-guess", "secret": "1234"}, {}, {"password": "helloworld", "declarative_admin_password": True, "pass4SymmKey": "you-will-never-guess", "secret": "1234"}),
({"password": "helloworld", "declarative_admin_password": True, "secret": "1234"}, {}, {"password": "helloworld", "declarative_admin_password": True, "pass4SymmKey": None, "secret": "1234"}),
# Check environment variable parameters
({"password": None}, {"SPLUNK_PASSWORD": "helloworld", "SPLUNK_PASS4SYMMKEY": "you-will-never-guess"}, {"password": "helloworld", "declarative_admin_password": False, "pass4SymmKey": "you-will-never-guess", "secret": None}),
({"password": None}, {"SPLUNK_PASSWORD": "helloworld", "SPLUNK_PASS4SYMMKEY": "you-will-never-guess", "SPLUNK_SECRET": "1234"}, {"password": "helloworld", "declarative_admin_password": False, "pass4SymmKey": "you-will-never-guess", "secret": "1234"}),
({"password": None}, {"SPLUNK_PASSWORD": "helloworld", "SPLUNK_SECRET": "1234"}, {"password": "helloworld", "declarative_admin_password": False, "pass4SymmKey": None, "secret": "1234"}),
({"password": None}, {"SPLUNK_PASSWORD": "helloworld", "SPLUNK_DECLARATIVE_ADMIN_PASSWORD": "true", "SPLUNK_PASS4SYMMKEY": "you-will-never-guess"}, {"password": "helloworld", "declarative_admin_password": True, "pass4SymmKey": "you-will-never-guess", "secret": None}),
({"password": None}, {"SPLUNK_PASSWORD": "helloworld", "SPLUNK_DECLARATIVE_ADMIN_PASSWORD": "TRUE", "SPLUNK_PASS4SYMMKEY": "you-will-never-guess", "SPLUNK_SECRET": "1234"}, {"password": "helloworld", "declarative_admin_password": True, "pass4SymmKey": "you-will-never-guess", "secret": "1234"}),
# We currently don't support 'yes' as a valid boolean
({"password": None}, {"SPLUNK_PASSWORD": "helloworld", "SPLUNK_DECLARATIVE_ADMIN_PASSWORD": "yes", "SPLUNK_SECRET": "1234"}, {"password": "helloworld", "declarative_admin_password": False, "pass4SymmKey": None, "secret": "1234"})
]
)
def test_getSecrets(default_yml, os_env, output):
vars_scope = {"splunk": default_yml}
with patch("environ.inventory") as mock_inven:
with patch("os.environ", new=os_env):
with patch("environ.os.path") as mock_os_path:
mock_os_path.isfile = MagicMock()
mock_os_path.isfile.return_value = False
environ.getSecrets(vars_scope)
assert vars_scope["splunk"] == output
@pytest.mark.parametrize(("default_yml", "os_env", "output"),
[
# Check when Splunk password is a file
({"password": "/tmp/splunk-password"}, {}, {"password": "worldneversayshiback", "pass4SymmKey": None, "secret": None}),
({"password": "helloworld"}, {"SPLUNK_PASSWORD": "/tmp/splunk-password"}, {"password": "worldneversayshiback", "pass4SymmKey": None, "secret": None}),
]
)
def test_getSecrets_passwordFromFile(default_yml, os_env, output):
file_contents = """
worldneversayshiback
"""
m = mock_open(read_data=file_contents)
vars_scope = {"splunk": default_yml}
with patch("environ.open", m, create=True) as mopen:
with patch("environ.inventory") as mock_inven:
with patch("os.environ", new=os_env):
with patch("os.path") as mock_os_path:
# Make sure that the isfile() check returns True
mock_os_path.isfile = MagicMock()
mock_os_path.isfile.return_value = True
environ.getSecrets(vars_scope)
mopen.assert_called_once()
assert vars_scope["splunk"]["password"] == "worldneversayshiback"
@pytest.mark.parametrize(("default_yml"),
[
# Check null parameters
({}),
({"password": None}),
({"password": ""})
]
)
def test_noSplunkPassword(default_yml):
vars_scope = {"splunk": default_yml}
with pytest.raises(Exception) as exc:
with patch("environ.inventory") as mock_inven:
with patch("os.environ", new={}):
environ.getSecrets(vars_scope)
assert "Splunk password must be supplied!" in str(exc.value)
@pytest.mark.parametrize(("default_yml", "os_env", "output"),
[
# Check null parameters
({}, {}, {"launch": {}}),
# Check default.yml parameters
({"launch": {}}, {}, {"launch": {}}),
({"launch": {"A": "B"}}, {}, {"launch": {"A": "B"}}),
({"launch": {"A": "B", "C": "D"}}, {}, {"launch": {"A": "B", "C": "D"}}),
# Check environment variable parameters
({}, {"SPLUNK_LAUNCH_CONF": None}, {"launch": {}}),
({}, {"SPLUNK_LAUNCH_CONF": ""}, {"launch": {}}),
({}, {"SPLUNK_LAUNCH_CONF": "AAA=BBB"}, {"launch": {"AAA": "BBB"}}),
({}, {"SPLUNK_LAUNCH_CONF": "AAA=BBB,CCC=DDD"}, {"launch": {"AAA": "BBB", "CCC": "DDD"}}),
({}, {"SPLUNK_LAUNCH_CONF": "AAA=BBB=CCC,DDD=EEE=FFF"}, {"launch": {"AAA": "BBB=CCC", "DDD": "EEE=FFF"}}),
# Check both
({"launch": {"A": "B", "C": "D"}}, {"SPLUNK_LAUNCH_CONF": "A=E,C=D"}, {"launch": {"A": "E", "C": "D"}}),
]
)
def test_getLaunchConf(default_yml, os_env, output):
vars_scope = {"splunk": default_yml}
with patch("environ.inventory") as mock_inven:
with patch("os.environ", new=os_env):
environ.getLaunchConf(vars_scope)
assert vars_scope["splunk"] == output
@pytest.mark.parametrize(("value", "separator", "output"),
[
# Check null value
(None, ",", []),
# Check empty value
("", ",", []),
# Check string value
("a", ",", ["a"]),
# Check comma separated string value
("a,b,c", ",", ["a", "b", "c"]),
# Check list value
(["a"], ",", ["a"]),
(["a", "b", "c"], ",", ["a", "b", "c"])
]
)
def test_ensureListValue(value, separator, output):
result = environ.ensureListValue(value, separator)
assert result == output
@pytest.mark.parametrize(("value", "separator", "output"),
[
# Check null value
(None, ",", []),
# Check empty value
("", ",", []),
# Check string value
("a", ",", ["a"]),
# Check comma separated string value
("a,b,c", ",", ["a", "b", "c"]),
# Check comma separated string value with whitespaces
(" a, b,c ", ",", ["a", "b", "c"]),
]
)
def test_splitAndStrip(value, separator, output):
result = environ.splitAndStrip(value, separator)
assert result == output
@pytest.mark.parametrize(("default_yml", "os_env", "output"),
[
# Check null parameters
({}, {}, {"ansible_pre_tasks": [], "ansible_post_tasks": [], "ansible_environment": {}}),
# Check ansible_pre_tasks using defaults or env vars
({"ansible_pre_tasks": ""}, {}, {"ansible_pre_tasks": [], "ansible_post_tasks": [], "ansible_environment": {}}),
({"ansible_pre_tasks": None}, {}, {"ansible_pre_tasks": [], "ansible_post_tasks": [], "ansible_environment": {}}),
({"ansible_pre_tasks": "a"}, {}, {"ansible_pre_tasks": ["a"], "ansible_post_tasks": [], "ansible_environment": {}}),
({"ansible_pre_tasks": ["a"]}, {}, {"ansible_pre_tasks": ["a"], "ansible_post_tasks": [], "ansible_environment": {}}),
({"ansible_pre_tasks": "a,b,c"}, {}, {"ansible_pre_tasks": ["a","b","c"], "ansible_post_tasks": [], "ansible_environment": {}}),
({"ansible_pre_tasks": ["a","b","c"]}, {}, {"ansible_pre_tasks": ["a","b","c"], "ansible_post_tasks": [], "ansible_environment": {}}),
({}, {"SPLUNK_ANSIBLE_PRE_TASKS": "d"}, {"ansible_pre_tasks": ["d"], "ansible_post_tasks": [], "ansible_environment": {}}),
({}, {"SPLUNK_ANSIBLE_PRE_TASKS": "e,f,g"}, {"ansible_pre_tasks": ["e","f","g"], "ansible_post_tasks": [], "ansible_environment": {}}),
({"ansible_pre_tasks": "a,b,c"}, {"SPLUNK_ANSIBLE_PRE_TASKS": "e,f,g"}, {"ansible_pre_tasks": ["e","f","g"], "ansible_post_tasks": [], "ansible_environment": {}}),
({"ansible_pre_tasks": ["a","b","c"]}, {"SPLUNK_ANSIBLE_PRE_TASKS": "e,f,g"}, {"ansible_pre_tasks": ["e","f","g"], "ansible_post_tasks": [], "ansible_environment": {}}),
# Check ansible_post_tasks using defaults or env vars
({"ansible_post_tasks": ""}, {}, {"ansible_pre_tasks": [], "ansible_post_tasks": [], "ansible_environment": {}}),
({"ansible_post_tasks": None}, {}, {"ansible_pre_tasks": [], "ansible_post_tasks": [], "ansible_environment": {}}),
({"ansible_post_tasks": "a"}, {}, {"ansible_pre_tasks": [], "ansible_post_tasks": ["a"], "ansible_environment": {}}),
({"ansible_post_tasks": ["a"]}, {}, {"ansible_pre_tasks": [], "ansible_post_tasks": ["a"], "ansible_environment": {}}),
({"ansible_post_tasks": "a,b,c"}, {}, {"ansible_pre_tasks": [], "ansible_post_tasks": ["a","b","c"], "ansible_environment": {}}),
({"ansible_post_tasks": ["a","b","c"]}, {}, {"ansible_pre_tasks": [], "ansible_post_tasks": ["a","b","c"], "ansible_environment": {}}),
({}, {"SPLUNK_ANSIBLE_POST_TASKS": "d"}, {"ansible_pre_tasks": [], "ansible_post_tasks": ["d"], "ansible_environment": {}}),
({}, {"SPLUNK_ANSIBLE_POST_TASKS": "e,f,g"}, {"ansible_pre_tasks": [], "ansible_post_tasks": ["e","f","g"], "ansible_environment": {}}),
({"ansible_post_tasks": "a,b,c"}, {"SPLUNK_ANSIBLE_POST_TASKS": "e,f,g"}, {"ansible_pre_tasks": [], "ansible_post_tasks": ["e","f","g"], "ansible_environment": {}}),
({"ansible_post_tasks": ["a","b","c"]}, {"SPLUNK_ANSIBLE_POST_TASKS": "e,f,g"}, {"ansible_pre_tasks": [], "ansible_post_tasks": ["e","f","g"], "ansible_environment": {}}),
# Check ansible_environment using defaults or env vars
({"ansible_environment": None}, {}, {"ansible_pre_tasks": [], "ansible_post_tasks": [], "ansible_environment": {}}),
({"ansible_environment": {"a": "b"}}, {}, {"ansible_pre_tasks": [], "ansible_post_tasks": [], "ansible_environment": {"a": "b"}}),
({"ansible_environment": {"a": "b", "d": "e"}}, {}, {"ansible_pre_tasks": [], "ansible_post_tasks": [], "ansible_environment": {"a": "b", "d": "e"}}),
({}, {"SPLUNK_ANSIBLE_ENV": "a=b"}, {"ansible_pre_tasks": [], "ansible_post_tasks": [], "ansible_environment": {"a": "b"}}),
({}, {"SPLUNK_ANSIBLE_ENV": "a=b,x=y"}, {"ansible_pre_tasks": [], "ansible_post_tasks": [], "ansible_environment": {"a": "b", "x": "y"}}),
({"ansible_environment": {"a": "c", "d": "e"}}, {"SPLUNK_ANSIBLE_ENV": "a=b,x=y"}, {"ansible_pre_tasks": [], "ansible_post_tasks": [], "ansible_environment": {"a": "b", "d": "e", "x": "y"}}),
]
)
def test_getAnsibleContext(default_yml, os_env, output):
vars_scope = default_yml
with patch("environ.inventory") as mock_inven:
with patch("os.environ", new=os_env):
environ.getAnsibleContext(vars_scope)
assert vars_scope == output
@pytest.mark.parametrize(("default_yml", "os_env", "splunk_asan"),
[
# Check null parameters
({}, {}, False),
# Check default.yml parameters
({"asan": False}, {}, False),
({"asan": True}, {}, True),
# Check env var parameters
({}, {"SPLUNK_ENABLE_ASAN": ""}, False),
({}, {"SPLUNK_ENABLE_ASAN": "anything"}, True),
# Check both
({"asan": False}, {"SPLUNK_ENABLE_ASAN": ""}, False),
({"asan": True}, {"SPLUNK_ENABLE_ASAN": ""}, False),
({"asan": True}, {"SPLUNK_ENABLE_ASAN": "true"}, True),
({"asan": False}, {"SPLUNK_ENABLE_ASAN": "yes"}, True),
]
)
def test_getASan(default_yml, os_env, splunk_asan):
vars_scope = {"ansible_environment": {}, "splunk": {}}
vars_scope["splunk"] = default_yml
with patch("environ.inventory") as mock_inven:
with patch("os.environ", new=os_env):
environ.getASan(vars_scope)
assert vars_scope["splunk"]["asan"] == splunk_asan
if vars_scope["splunk"]["asan"]:
assert vars_scope["ansible_environment"].get("ASAN_OPTIONS") == "detect_leaks=0"
else:
assert vars_scope["ansible_environment"].get("ASAN_OPTIONS") == None
@pytest.mark.parametrize(("default_yml", "os_env", "result"),
[
# Check null parameters
({}, {}, {"enable": True, "port": 8088, "token": None, "ssl": True}),
# Check default.yml parameters
({"enable": False}, {}, {"enable": False, "port": 8088, "token": None, "ssl": True}),
({"port": 8099}, {}, {"enable": True, "port": 8099, "token": None, "ssl": True}),
({"token": "abcd"}, {}, {"enable": True, "port": 8088, "token": "abcd", "ssl": True}),
({"ssl": False}, {}, {"enable": True, "port": 8088, "token": None, "ssl": False}),
# Check env var parameters
({}, {"SPLUNK_HEC_TOKEN": "qwerty"}, {"enable": True, "port": 8088, "token": "qwerty", "ssl": True}),
({}, {"SPLUNK_HEC_PORT": "9999"}, {"enable": True, "port": 9999, "token": None, "ssl": True}),
({}, {"SPLUNK_HEC_SSL": "true"}, {"enable": True, "port": 8088, "token": None, "ssl": True}),
({}, {"SPLUNK_HEC_SSL": "false"}, {"enable": True, "port": 8088, "token": None, "ssl": False}),
({}, {"SPLUNK_HEC_SSL": "FALSE"}, {"enable": True, "port": 8088, "token": None, "ssl": False}),
# Check both
({"port": 8099}, {"SPLUNK_HEC_PORT": "19999"}, {"enable": True, "port": 19999, "token": None, "ssl": True}),
({"token": "abcd"}, {"SPLUNK_HEC_TOKEN": "fdsa"}, {"enable": True, "port": 8088, "token": "fdsa", "ssl": True}),
({"ssl": True}, {"SPLUNK_HEC_SSL": "fAlSe"}, {"enable": True, "port": 8088, "token": None, "ssl": False}),
]
)
def test_getHEC(default_yml, os_env, result):
vars_scope = {"splunk": {}}
vars_scope["splunk"] = {
"hec": {
"enable": True,
"port": 8088,
"token": None,
"ssl": True
}
}
vars_scope["splunk"]["hec"].update(default_yml)
with patch("environ.inventory") as mock_inven:
with patch("os.environ", new=os_env):
environ.getHEC(vars_scope)
assert vars_scope["splunk"]["hec"] == result
@pytest.mark.parametrize(("default_yml", "os_env", "result"),
[
# Check null parameters
({}, {}, False),
# # Check default.yml parameters
({"disable_popups": False}, {}, False),
({"disable_popups": True}, {}, True),
# # Check env var parameters
({}, {"SPLUNK_DISABLE_POPUPS": "TRUE"}, True),
({}, {"SPLUNK_DISABLE_POPUPS": "true"}, True),
({}, {"SPLUNK_DISABLE_POPUPS": "True"}, True),
({}, {"SPLUNK_DISABLE_POPUPS": "false"}, False),
({}, {"SPLUNK_DISABLE_POPUPS": "False"}, False),
({}, {"SPLUNK_DISABLE_POPUPS": "FALSE"}, False),
# # Check both
({"disable_popups": False}, {"SPLUNK_DISABLE_POPUPS": "TRUE"}, True),
({"disable_popups": False}, {"SPLUNK_DISABLE_POPUPS": "True"}, True),
({"disable_popups": True}, {"SPLUNK_DISABLE_POPUPS": "False"}, False),
({"disable_popups": True}, {"SPLUNK_DISABLE_POPUPS": "FALSE"}, False),
]
)
def test_getDisablePopups(default_yml, os_env, result):
vars_scope = {}
vars_scope["splunk"] = default_yml
with patch("environ.inventory") as mock_inven:
with patch("os.environ", new=os_env):
environ.getDisablePopups(vars_scope)
assert vars_scope["splunk"]["disable_popups"] == result
@pytest.mark.parametrize(("default_yml", "os_env", "result"),
[
# Check null parameters
({}, {}, {"enable": False, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
# Check default.yml parameters
({"enable": True}, {}, {"enable": True, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({"server": "fwd.dsp.com:8888"}, {}, {"enable": False, "server": "fwd.dsp.com:8888", "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({"cert": "path/to/cert.pem"}, {}, {"enable": False, "server": None, "cert": "path/to/cert.pem", "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({"verify": True}, {}, {"enable": False, "server": None, "cert": None, "verify": True, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({"pipeline_name": "abcd"}, {}, {"enable": False, "server": None, "cert": None, "verify": False, "pipeline_name": "abcd", "pipeline_desc": None, "pipeline_spec": None}),
({"pipeline_desc": "abcd"}, {}, {"enable": False, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": "abcd", "pipeline_spec": None}),
({"pipeline_spec": "abcd"}, {}, {"enable": False, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": "abcd"}),
# Check env var parameters
({}, {"SPLUNK_DSP_SERVER": "fwd.dsp.com:9999"}, {"enable": False, "server": "fwd.dsp.com:9999", "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({}, {"SPLUNK_DSP_CERT": "crt.pem"}, {"enable": False, "server": None, "cert": "crt.pem", "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({}, {"SPLUNK_DSP_VERIFY": "yes"}, {"enable": False, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({}, {"SPLUNK_DSP_VERIFY": "true"}, {"enable": False, "server": None, "cert": None, "verify": True, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({}, {"SPLUNK_DSP_VERIFY": "TRUE"}, {"enable": False, "server": None, "cert": None, "verify": True, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({}, {"SPLUNK_DSP_ENABLE": "yes"}, {"enable": False, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({}, {"SPLUNK_DSP_ENABLE": "true"}, {"enable": True, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({}, {"SPLUNK_DSP_ENABLE": "TRUE"}, {"enable": True, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({}, {"SPLUNK_DSP_PIPELINE_NAME": "do"}, {"enable": False, "server": None, "cert": None, "verify": False, "pipeline_name": "do", "pipeline_desc": None, "pipeline_spec": None}),
({}, {"SPLUNK_DSP_PIPELINE_DESC": "re"}, {"enable": False, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": "re", "pipeline_spec": None}),
({}, {"SPLUNK_DSP_PIPELINE_SPEC": "mi"}, {"enable": False, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": "mi"}),
# Check both
({"enable": True}, {"SPLUNK_DSP_ENABLE": "false"}, {"enable": True, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({"enable": False}, {"SPLUNK_DSP_ENABLE": "true"}, {"enable": True, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({"server": "fwd.dsp.com:8888"}, {"SPLUNK_DSP_SERVER": "fwd.dsp.com:9999"}, {"enable": False, "server": "fwd.dsp.com:9999", "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({"cert": "path1/crt.pem"}, {"SPLUNK_DSP_CERT": "path2/cert.pem"}, {"enable": False, "server": None, "cert": "path2/cert.pem", "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({"verify": True}, {"SPLUNK_DSP_VERIFY": "false"}, {"enable": False, "server": None, "cert": None, "verify": True, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({"verify": False}, {"SPLUNK_DSP_VERIFY": "TRUE"}, {"enable": False, "server": None, "cert": None, "verify": True, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": None}),
({"pipeline_name": "abcd"}, {"SPLUNK_DSP_PIPELINE_NAME": "xyz"}, {"enable": False, "server": None, "cert": None, "verify": False, "pipeline_name": "xyz", "pipeline_desc": None, "pipeline_spec": None}),
({"pipeline_desc": "abcd"}, {"SPLUNK_DSP_PIPELINE_DESC": "xyz"}, {"enable": False, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": "xyz", "pipeline_spec": None}),
({"pipeline_spec": "abcd"}, {"SPLUNK_DSP_PIPELINE_SPEC": "xyz"}, {"enable": False, "server": None, "cert": None, "verify": False, "pipeline_name": None, "pipeline_desc": None, "pipeline_spec": "xyz"}),
]
)
def test_getDSP(default_yml, os_env, result):
vars_scope = {"splunk": {}}
vars_scope["splunk"] = {
"dsp": {
"enable": False,
"server": None,
"cert": None,
"verify": False,
"pipeline_name": None,
"pipeline_desc": None,
"pipeline_spec": None,
}
}
vars_scope["splunk"]["dsp"].update(default_yml)
with patch("environ.inventory") as mock_inven:
with patch("os.environ", new=os_env):
environ.getDSP(vars_scope)
assert vars_scope["splunk"]["dsp"] == result
@pytest.mark.parametrize(("es_enablement", "os_env", "result"),
[
(None, {}, ""),
(None, {"SPLUNK_ES_SSL_ENABLEMENT":"strict"}, "--ssl_enablement strict"),
({"ssl_enablement":"auto"}, {}, "--ssl_enablement auto"),
({"ssl_enablement":"strict"}, {}, "--ssl_enablement strict"),
({"ssl_enablement":"ignore"}, {}, "--ssl_enablement ignore"),
({"ssl_enablement":"ignore"}, {"SPLUNK_ES_SSL_ENABLEMENT":"strict"}, "--ssl_enablement strict"),
({"ssl_enablement":"invalid"}, {}, "Exception")
]
)
def test_getESSplunkVariables(es_enablement, os_env, result):
vars_scope = {"splunk": {}}
if es_enablement is not None:
vars_scope["splunk"]["es"] = es_enablement
with patch("environ.inventory") as mock_inven:
with patch("os.environ", new=os_env):
try:
environ.getESSplunkVariables(vars_scope)
assert vars_scope["es_ssl_enablement"] == result
except Exception:
assert result == "Exception"
@pytest.mark.parametrize(("os_env", "license_master_url", "deployer_url", "cluster_master_url", "search_head_captain_url"),
[
({}, "", "", "", ""),
# Check individual environment variables
({"SPLUNK_LICENSE_MASTER_URL": "something"}, "https://something:8089", "", "", ""),
({"SPLUNK_DEPLOYER_URL": "something"}, "", "something", "", ""),
({"SPLUNK_CLUSTER_MASTER_URL": "something"}, "", "", "something", ""),
({"SPLUNK_SEARCH_HEAD_CAPTAIN_URL": "something"}, "", "", "", "something"),
]
)
def test_getDistributedTopology(os_env, license_master_url, deployer_url, cluster_master_url, search_head_captain_url):
vars_scope = {"splunk": {}}
with patch("os.environ", new=os_env):
environ.getDistributedTopology(vars_scope)
assert type(vars_scope["splunk"]["license_master_url"]) == str
assert vars_scope["splunk"]["license_master_url"] == license_master_url
assert type(vars_scope["splunk"]["deployer_url"]) == str
assert vars_scope["splunk"]["deployer_url"] == deployer_url
assert type(vars_scope["splunk"]["cluster_master_url"]) == str
assert vars_scope["splunk"]["cluster_master_url"] == cluster_master_url
assert type(vars_scope["splunk"]["search_head_captain_url"]) == str
assert vars_scope["splunk"]["search_head_captain_url"] == search_head_captain_url
@pytest.mark.parametrize(("default_yml", "os_env", "license_uri", "wildcard_license", "ignore_license", "license_download_dest"),
[
({}, {}, "splunk.lic", False, False, "/tmp/splunk.lic"),
# Check individual environment variables
({}, {"SPLUNK_LICENSE_URI": "http://web/license.lic"}, "http://web/license.lic", False, False, "/tmp/splunk.lic"),
({}, {"SPLUNK_LICENSE_URI": "/mnt/*.lic"}, "/mnt/*.lic", True, False, "/tmp/splunk.lic"),
({}, {"SPLUNK_NFR_LICENSE": "/mnt/nfr.lic"}, "splunk.lic", False, False, "/tmp/splunk.lic"),
({}, {"SPLUNK_IGNORE_LICENSE": ""}, "splunk.lic", False, False, "/tmp/splunk.lic"),
({}, {"SPLUNK_IGNORE_LICENSE": "true"}, "splunk.lic", False, True, "/tmp/splunk.lic"),
({}, {"SPLUNK_IGNORE_LICENSE": "TRUE"}, "splunk.lic", False, True, "/tmp/splunk.lic"),
({}, {"SPLUNK_IGNORE_LICENSE": "false"}, "splunk.lic", False, False, "/tmp/splunk.lic"),
({}, {"SPLUNK_LICENSE_INSTALL_PATH": "/Downloads/"}, "splunk.lic", False, False, "/Downloads/"),
# Check default.yml
({"license_uri": None}, {}, "splunk.lic", False, False, "/tmp/splunk.lic"),
({"license_uri": ""}, {}, "splunk.lic", False, False, "/tmp/splunk.lic"),
({"license_uri": "http://web/license.lic"}, {}, "http://web/license.lic", False, False, "/tmp/splunk.lic"),
({"license_uri": "/mnt/*.lic"}, {}, "/mnt/*.lic", True, False, "/tmp/splunk.lic"),
({"license_uri": "/mnt/nfr.lic"}, {}, "/mnt/nfr.lic", False, False, "/tmp/splunk.lic"),
({"license_uri": "/mnt/1.lic"}, {"SPLUNK_LICENSE_URI": "/mnt/2.lic"}, "/mnt/2.lic", False, False, "/tmp/splunk.lic"),
({"license_download_dest": None}, {}, "splunk.lic", False, False, "/tmp/splunk.lic"),
({"license_download_dest": ""}, {}, "splunk.lic", False, False, "/tmp/splunk.lic"),
({"license_download_dest": "/Downloads/splunk.lic"}, {}, "splunk.lic", False, False, "/Downloads/splunk.lic"),
({"license_download_dest": "/Downloads/splunk.lic"}, {"SPLUNK_LICENSE_INSTALL_PATH": "/mnt/license.file"}, "splunk.lic", False, False, "/mnt/license.file"),
]
)
def test_getLicenses(default_yml, os_env, license_uri, wildcard_license, ignore_license, license_download_dest):
vars_scope = {"splunk": default_yml}
with patch("os.environ", new=os_env):
environ.getLicenses(vars_scope)
assert vars_scope["splunk"]["license_uri"] == license_uri
assert type(vars_scope["splunk"]["wildcard_license"]) == bool
assert vars_scope["splunk"]["wildcard_license"] == wildcard_license
assert type(vars_scope["splunk"]["ignore_license"]) == bool
assert vars_scope["splunk"]["ignore_license"] == ignore_license
assert vars_scope["splunk"]["license_download_dest"] == license_download_dest
@pytest.mark.parametrize(("default_yml", "os_env", "java_version", "java_download_url", "java_update_version"),
[
({}, {}, None, None, None),
# Check environment variable parameters
({}, {"JAVA": "oracle:8"}, None, None, None),
({}, {"JAVA_VERSION": "openjdk:8"}, "openjdk:8", None, None),
({}, {"JAVA_VERSION": "openjdk:9"}, "openjdk:9", None, None),
({}, {"JAVA_VERSION": "oracle:8"}, "oracle:8", "https://download.oracle.com/otn-pub/java/jdk/8u141-b15/336fa29ff2bb4ef291e347e091f7f4a7/jdk-8u141-linux-x64.tar.gz", "141"),
({}, {"JAVA_VERSION": "ORACLE:8"}, "oracle:8", "https://download.oracle.com/otn-pub/java/jdk/8u141-b15/336fa29ff2bb4ef291e347e091f7f4a7/jdk-8u141-linux-x64.tar.gz", "141"),
({}, {"JAVA_VERSION": "openjdk:11"}, "openjdk:11", "https://download.java.net/java/GA/jdk11/9/GPL/openjdk-11.0.2_linux-x64_bin.tar.gz", "11.0.2"),
({}, {"JAVA_VERSION": "oPenJdK:11"}, "openjdk:11", "https://download.java.net/java/GA/jdk11/9/GPL/openjdk-11.0.2_linux-x64_bin.tar.gz", "11.0.2"),
({}, {"JAVA_VERSION": "oracle:8", "JAVA_DOWNLOAD_URL": "https://java/jdk-8u9000-linux-x64.tar.gz"}, "oracle:8", "https://java/jdk-8u9000-linux-x64.tar.gz", "9000"),
({}, {"JAVA_VERSION": "openjdk:11", "JAVA_DOWNLOAD_URL": "https://java/openjdk-11.11.11_linux-x64_bin.tar.gz"}, "openjdk:11", "https://java/openjdk-11.11.11_linux-x64_bin.tar.gz", "11.11.11"),
# Check default.yml
({"java_version": "openjdk:11"}, {}, "openjdk:11", None, None),
({"java_download_url": "http://web/java.tgz"}, {}, None, "http://web/java.tgz", None),
({"java_update_version": "jdk11u141"}, {}, None, None, "jdk11u141"),
# Check order of precedence
({"java_version": "openjdk:9", "java_download_url": "http://web/java.tgz", "java_update_version": "jdk11u141"}, {"JAVA_VERSION": "oPenJdK:11"}, "openjdk:11", "https://download.java.net/java/GA/jdk11/9/GPL/openjdk-11.0.2_linux-x64_bin.tar.gz", "11.0.2"),
]
)
def test_getJava(default_yml, os_env, java_version, java_download_url, java_update_version):
vars_scope = default_yml
with patch("os.environ", new=os_env):
environ.getJava(vars_scope)
assert vars_scope["java_version"] == java_version
assert vars_scope["java_download_url"] == java_download_url
assert vars_scope["java_update_version"] == java_update_version
@pytest.mark.parametrize(("os_env", "java_version", "java_download_url", "err_msg"),
[
({"JAVA_VERSION": "oracle:3"}, None, None, "Invalid Java version supplied"),
({"JAVA_VERSION": "openjdk:20"}, None, None, "Invalid Java version supplied"),
({"JAVA_VERSION": "oracle:8", "JAVA_DOWNLOAD_URL": "https://java/jdk-8u9000.tar.gz"}, "oracle:8", "https://java/jdk-8u9000.tar.gz", "Invalid Java download URL format"),
({"JAVA_VERSION": "openjdk:11", "JAVA_DOWNLOAD_URL": "https://java/openjdk-11.tar.gz"}, "openjdk:11", "https://java/openjdk-11.tar.gz", "Invalid Java download URL format"),
]
)
def test_getJava_exception(os_env, java_version, java_download_url, err_msg):
vars_scope = {"splunk": {}}
with patch("os.environ", new=os_env):
try:
environ.getJava(vars_scope)
assert False
except Exception as e:
assert True
assert err_msg in str(e)
assert vars_scope["java_version"] == java_version
assert vars_scope["java_download_url"] == java_download_url
assert vars_scope["java_update_version"] == None
@pytest.mark.parametrize(("default_yml", "os_env", "build", "build_url_bearer_token"),
[
({}, {}, None, None),
# Check default.yml parameters
({"buildlocation": "http://server/file.tgz"}, {}, None, None),
({"build_location": None}, {}, None, None),
({"build_location": ""}, {}, "", None),
({"build_location": "/path/to/file.tgz"}, {}, "/path/to/file.tgz", None),
({"build_location": "http://server/file.tgz"}, {}, "http://server/file.tgz", None),
({"build_location": "https://server/file.tgz"}, {}, "https://server/file.tgz", None),
# Check environment variable parameters
({}, {"SPLUNK_BUILD": "http://server/file.tgz"}, None, None),
({}, {"SPLUNK_BUILD_URL": None}, None, None),
({}, {"SPLUNK_BUILD_URL": ""}, "", None),
({}, {"SPLUNK_BUILD_URL": "/path/to/file.tgz", "SPLUNK_BUILD_URL_BEARER_TOKEN": "testToken"}, "/path/to/file.tgz", "testToken"),
({}, {"SPLUNK_BUILD_URL": "http://server/file.tgz", "SPLUNK_BUILD_URL_BEARER_TOKEN": "testToken"}, "http://server/file.tgz", "testToken"),
({}, {"SPLUNK_BUILD_URL": "https://server/file.tgz", "SPLUNK_BUILD_URL_BEARER_TOKEN": "testToken"}, "https://server/file.tgz", "testToken"),
# Check order of precedence
({"build_location": "http://server/file1.tgz"}, {"SPLUNK_BUILD_URL": "https://server/file2.tgz"}, "https://server/file2.tgz", None),
({"build_location": "http://server/file1.tgz"}, {"SPLUNK_BUILD_URL": "/path/to/file.tgz"}, "/path/to/file.tgz", None),
]
)
def test_getSplunkBuild(default_yml, os_env, build, build_url_bearer_token):
vars_scope = dict()
vars_scope["splunk"] = default_yml
with patch("os.environ", new=os_env):
environ.getSplunkBuild(vars_scope)
assert vars_scope["splunk"]["build_location"] == build
assert vars_scope["splunk"]["build_url_bearer_token"] == build_url_bearer_token
@pytest.mark.parametrize(("default_yml", "response_content", "trigger_splunkbase"),
[
({}, "123abc", False),
({"splunkbase_username": "ocho"}, "123abc", False),
({"splunkbase_password": "cinco"}, "123abc", False),
({"splunkbase_username": "ocho", "splunkbase_password": "cinco"}, "123abc", True),
({"splunkbase_username": "", "splunkbase_password": ""}, "123abc", False),
({}, "123abc", False),
({"splunkbase_username": "ocho"}, b"123abc", False),
({"splunkbase_password": "cinco"}, b"123abc", False),
({"splunkbase_username": "ocho", "splunkbase_password": "cinco"}, b"123abc", True),
({"splunkbase_username": "", "splunkbase_password": ""}, b"123abc", False),
]
)
def test_getSplunkbaseToken(default_yml, response_content, trigger_splunkbase):
vars_scope = default_yml
with patch("environ.requests.post") as mock_post:
mock_post.return_value = MagicMock(status_code=200, content=response_content)
with patch("os.environ", new=dict()):
environ.getSplunkbaseToken(vars_scope)
# Make sure Splunkbase token is populated when appropriate
assert "splunkbase_token" in vars_scope
assert "splunkbase_username" in vars_scope
assert "splunkbase_password" in vars_scope
if trigger_splunkbase:
mock_post.assert_called_with("https://splunkbase.splunk.com/api/account:login/", data={"username": "ocho", "password": "cinco"})
assert vars_scope.get("splunkbase_token") == "123abc"
else:
mock_post.assert_not_called()
assert not vars_scope.get("splunkbase_token")
def test_getSplunkbaseToken_exception():
with patch("environ.requests.post") as mock_post:
mock_post.return_value = MagicMock(status_code=400, content="error")
try:
environ.getSplunkbaseToken({"splunkbase_username": "ocho", "splunkbase_password": "cinco"})
assert False
except Exception as e:
assert True
assert "Invalid Splunkbase credentials" in str(e)
@pytest.mark.parametrize(("default_yml", "os_env", "apps_cnt_def", "apps_cnt_shc", "apps_cnt_idc"),
[
# Check null parameters
({}, {}, 0, 0, 0),
# Check default.yml parameters
({"app_paths_install": {"defaults": ["a"]}}, {}, 0, 0, 0),
({"app_paths_install": {"default": ["a"]}}, {}, 1, 0, 0),
({"apps_paths_install":{"default": ["a", "b", "c"]}}, {}, 0, 0, 0),
({"app_paths_install": {"default": ["a", "b", "c"], "shc": ["e", "f"]}}, {}, 3, 2, 0),
({"app_paths_install": {"default": ["a", "b", "c"], "idxc": ["e", "f"]}}, {}, 3, 0, 2),
({"app_paths_install": {"shc": ["a", "b", "c"], "idxc": ["e", "f"]}}, {}, 0, 3, 2),
({"app_paths_install": {"default": ["a"], "shc": ["b"], "idxc": ["c"]}}, {}, 1, 1, 1),
]
)
def test_getSplunkAppPathInstall(default_yml, os_env, apps_cnt_def, apps_cnt_shc, apps_cnt_idc):
vars_scope = dict()
vars_scope["splunk"] = default_yml
with patch("os.environ", new=os_env):
environ.getSplunkAppPathInstall(vars_scope)
assert type(vars_scope["splunk"]["app_paths_install"]["default"]) == list
assert len(vars_scope["splunk"]["app_paths_install"]["default"]) == apps_cnt_def
assert type(vars_scope["splunk"]["app_paths_install"]["shc"]) == list
assert len(vars_scope["splunk"]["app_paths_install"]["shc"]) == apps_cnt_shc
assert type(vars_scope["splunk"]["app_paths_install"]["idxc"]) == list
assert len(vars_scope["splunk"]["app_paths_install"]["idxc"]) == apps_cnt_idc
@pytest.mark.parametrize(("default_yml", "os_env", "apps_count"),
[
# Check null parameters
({}, {}, 0),
# Check default.yml parameters
({"app_location": []}, {}, 0),
({"app_location": ["a"]}, {}, 0),
({"app_location": ["a", "b", "c"]}, {}, 0),
({"apps_location": []}, {}, 0),
({"apps_location": ["a"]}, {}, 1),
({"apps_location": ["a", "b", "c"]}, {}, 3),
({"apps_location": "a"}, {}, 1),
({"apps_location": "a,b,c,d"}, {}, 4),
# Check environment variable parameters
({}, {"SPLUNK_APPS": None}, 0),
({}, {"SPLUNK_APPS": "hi"}, 0),
({}, {"SPLUNK_APPS_URL": "hi"}, 1),
({}, {"SPLUNK_APPS_URL": "a,b,ccccc,dd"}, 4),
# Check the union combination of default.yml + environment variables
### Invalid 'app_location' variable name in default.yml
({"app_location": []}, {"SPLUNK_APPS_URL": None}, 0),
({"app_location": ["a"]}, {"SPLUNK_APPS_URL": "a"}, 1),
({"app_location": ["a", "b", "c"]}, {"SPLUNK_APPS_URL": "a,bb"}, 2),
### Invalid 'SPLUNK_APP_URL' variable name in env vars
({"apps_location": ["x"]}, {"SPLUNK_APP_URL": "a"}, 1),
({"apps_location": ["x", "y"]}, {"SPLUNK_APP_URL": "a,bb"}, 2),
({"apps_location": "x,y,z"}, {"SPLUNK_APP_URL": "a,bb"}, 3),
### Correct variable names
({"apps_location": ["x"]}, {"SPLUNK_APPS_URL": "a"}, 2),
({"apps_location": ["x", "y"]}, {"SPLUNK_APPS_URL": "a,bb"}, 4),
({"apps_location": "x,y,z"}, {"SPLUNK_APPS_URL": "a,bb"}, 5),
### Only return unique set of apps
({"apps_location": ["x"]}, {"SPLUNK_APPS_URL": "x"}, 1),
({"apps_location": ["x", "y"]}, {"SPLUNK_APPS_URL": "a,bb,y"}, 4),
({"apps_location": "x,y,z"}, {"SPLUNK_APPS_URL": "x,yy,a,z"}, 5),
]
)
def test_getSplunkApps(default_yml, os_env, apps_count):
vars_scope = dict()
vars_scope["splunk"] = default_yml
with patch("os.environ", new=os_env):
environ.getSplunkApps(vars_scope)
assert type(vars_scope["splunk"]["apps_location"]) == list
assert len(vars_scope["splunk"]["apps_location"]) == apps_count
@pytest.mark.parametrize(("default_yml", "os_env", "apps_count"),
[
# Check null parameters
({}, {}, 0),
# Check default.yml parameters
({"app_location_local": []}, {}, 0),
({"app_location_local": ["a"]}, {}, 0),
({"app_location_local": ["a", "b", "c"]}, {}, 0),
({"apps_location_local": []}, {}, 0),
({"apps_location_local": ["a"]}, {}, 1),
({"apps_location_local": ["a", "b", "c"]}, {}, 3),
({"apps_location_local": "a"}, {}, 1),
({"apps_location_local": "a,b,c,d"}, {}, 4),
# Check the union combination of default.yml + environment variables
### Invalid 'app_location' variable name in default.yml
({"app_location_local": []}, {"SPLUNK_APPS_URL_LOCAL": None}, 0),
({"app_location_local": ["a"]}, {"SPLUNK_APPS_URL_LOCAL": "a"}, 1),
({"app_location_local": ["a", "b", "c"]}, {"SPLUNK_APPS_URL_LOCAL": "a,bb"}, 2),
### Invalid 'SPLUNK_APP_URL' variable name in env vars
({"apps_location_local": ["x"]}, {"SPLUNK_APP_URL_LOCAL": "a"}, 1),
({"apps_location_local": ["x", "y"]}, {"SPLUNK_APP_URL_LOCAL": "a,bb"}, 2),
({"apps_location_local": "x,y,z"}, {"SPLUNK_APP_URL_LOCAL": "a,bb"}, 3),
### Correct variable names
({"apps_location_local": ["x"]}, {"SPLUNK_APPS_URL_LOCAL": "a"}, 2),
({"apps_location_local": ["x", "y"]}, {"SPLUNK_APPS_URL_LOCAL": "a,bb"}, 4),
({"apps_location_local": "x,y,z"}, {"SPLUNK_APPS_URL_LOCAL": "a,bb"}, 5),
### Only return unique set of apps
({"apps_location_local": ["x"]}, {"SPLUNK_APPS_URL_LOCAL": "x"}, 1),
({"apps_location_local": ["x", "y"]}, {"SPLUNK_APPS_URL_LOCAL": "a,bb,y"}, 4),
({"apps_location_local": "x,y,z"}, {"SPLUNK_APPS_URL_LOCAL": "x,yy,a,z"}, 5),
]
)
def test_getSplunkAppsLocal(default_yml, os_env, apps_count):
vars_scope = dict()
vars_scope["splunk"] = default_yml
with patch("os.environ", new=os_env):
environ.getSplunkAppsLocal(vars_scope)
assert type(vars_scope["splunk"]["apps_location_local"]) == list
assert len(vars_scope["splunk"]["apps_location_local"]) == apps_count
@pytest.mark.parametrize(("default_yml", "os_env", "key", "value"),
[
# Check cert_prefix
({}, {}, "cert_prefix", "https"),
({"cert_prefix": "http"}, {}, "cert_prefix", "http"),
({}, {"SPLUNK_CERT_PREFIX": "fakehttps"}, "cert_prefix", "fakehttps"),
# Check splunk.user
({"splunk": {"user": "root"}}, {}, "splunk.user", "root"),
({}, {"SPLUNK_USER": "root"}, "splunk.user", "root"),
# Check splunk.group
({"splunk": {"group": "root"}}, {}, "splunk.group", "root"),
({}, {"SPLUNK_GROUP": "root"}, "splunk.group", "root"),
# Check splunk.root_endpoint
({"splunk": {"root_endpoint": "/splunk"}}, {}, "splunk.root_endpoint", "/splunk"),
({}, {"SPLUNK_ROOT_ENDPOINT": "/splk"}, "splunk.root_endpoint", "/splk"),
# Check splunk.svc_port
({"splunk": {"svc_port": "9089"}}, {}, "splunk.svc_port", "9089"),
({}, {"SPLUNK_SVC_PORT": "8189"}, "splunk.svc_port", "8189"),
# Check splunk.s2s.port
({"splunk": {"s2s": {"port": "9999"}}}, {}, "splunk.s2s.port", 9999),
({}, {"SPLUNK_S2S_PORT": "9991"}, "splunk.s2s.port", 9991),
# Check splunk.enable_service
({"splunk": {"enable_service": "yes"}}, {}, "splunk.enable_service", "yes"),
({}, {"SPLUNK_ENABLE_SERVICE": "no"}, "splunk.enable_service", "no"),
# Check splunk.service_name
({"splunk": {"service_name": "SpLuNkD"}}, {}, "splunk.service_name", "SpLuNkD"),
({}, {"SPLUNK_SERVICE_NAME": "sPlUnKd"}, "splunk.service_name", "sPlUnKd"),
# Check splunk.allow_upgrade
({"splunk": {"allow_upgrade": "yes"}}, {}, "splunk.allow_upgrade", "yes"),
({}, {"SPLUNK_ALLOW_UPGRADE": "no"}, "splunk.allow_upgrade", "no"),
# Check splunk.set_search_peers
({"splunk": {"set_search_peers": False}}, {}, "splunk.set_search_peers", False),
({}, {"SPLUNK_SET_SEARCH_PEERS": "False"}, "splunk.set_search_peers", False),
({"splunk": {"set_search_peers": True}}, {"SPLUNK_SET_SEARCH_PEERS": "False"}, "splunk.set_search_peers", False),
# Check splunk.appserver.port
({"splunk": {"appserver": {"port": "9291"}}}, {}, "splunk.appserver.port", "9291"),
({}, {"SPLUNK_APPSERVER_PORT": "9391"}, "splunk.appserver.port", "9391"),
# Check splunk.kvstore.port
({"splunk": {"kvstore" :{"port": "9165"}}}, {}, "splunk.kvstore.port", "9165"),
({}, {"SPLUNK_KVSTORE_PORT": "9265"}, "splunk.kvstore.port", "9265"),
# Check splunk.connection_timeout
({"splunk": {"connection_timeout": 60}}, {}, "splunk.connection_timeout", 60),
({}, {"SPLUNK_CONNECTION_TIMEOUT": 200}, "splunk.connection_timeout", 200),
]
)
def test_overrideEnvironmentVars(default_yml, os_env, key, value):
vars_scope = {
"ansible_pre_tasks": None,
"ansible_post_tasks": None,
"cert_prefix": "https",
"splunk": {
"user": "splunk",
"group": "splunk",
"root_endpoint": None,
"enable_tcp_mode": True,
"svc_port": 8089,
"s2s": {"port": 9997},
"appserver": {"port": 8065},
"kvstore": {"port": 8191},
"hec_token": "abcd1234",
"enable_service": False,
"service_name": "Splunkd",
"allow_upgrade": True,
"asan": None,
"set_search_peers": True,
"connection_timeout": 0,
}
}
# TODO: Possibly remove the dependency on merge_dict() in this test
environ.merge_dict(vars_scope, default_yml)
with patch("os.environ", new=os_env):
environ.overrideEnvironmentVars(vars_scope)
if "splunk" in key:
if "s2s" in key or "appserver" in key or "kvstore" in key:
section, key = key.split(".")[-2:]
assert vars_scope["splunk"][section][key] == value
else:
key = key.split(".")[-1]
assert vars_scope["splunk"][key] == value
else:
assert vars_scope[key] == value
@pytest.mark.parametrize(("default_yml", "os_env", "output"),
[
# Check null parameters
({}, {}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
# Check default.yml parameters
({"dfs": {"enable": True}}, {}, {"enable": True, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({"dfs": {"dfw_num_slots": 20}}, {}, {"enable": False, "dfw_num_slots": 20, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({"dfs": {"dfw_num_slots": "15"}}, {}, {"enable": False, "dfw_num_slots": 15, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({"dfs": {"dfc_num_slots": 20}}, {}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 20, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({"dfs": {"dfc_num_slots": "15"}}, {}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 15, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({"dfs": {"dfw_num_slots_enabled": True}}, {}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": True, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({"dfs": {"spark_master_host": "10.0.0.1"}}, {}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "10.0.0.1", "spark_master_webui_port": 8080}),
({"dfs": {"spark_master_webui_port": 8081}}, {}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8081}),
({"dfs": {"spark_master_webui_port": "8082"}}, {}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8082}),
# Check environment variable parameters
({}, {"SPLUNK_ENABLE_DFS": ""}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({}, {"SPLUNK_ENABLE_DFS": "true"}, {"enable": True, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({}, {"SPLUNK_ENABLE_DFS": "TRUE"}, {"enable": True, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({}, {"SPLUNK_DFW_NUM_SLOTS": "11"}, {"enable": False, "dfw_num_slots": 11, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({}, {"SPLUNK_DFC_NUM_SLOTS": "1"}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 1, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({}, {"SPLUNK_DFW_NUM_SLOTS_ENABLED": ""}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({}, {"SPLUNK_DFW_NUM_SLOTS_ENABLED": "true"}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": True, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({}, {"SPLUNK_DFW_NUM_SLOTS_ENABLED": "TRUE"}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": True, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({}, {"SPARK_MASTER_HOST": "8.8.8.8"}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "8.8.8.8", "spark_master_webui_port": 8080}),
({}, {"SPARK_MASTER_WEBUI_PORT": "8888"}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8888}),
# Check the union combination of default.yml + environment variables and order of precedence when overwriting
({"dfs": {"enable": False}}, {"SPLUNK_ENABLE_DFS": "true"}, {"enable": True, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({"dfs": {"dfw_num_slots": 100}}, {"SPLUNK_DFW_NUM_SLOTS": "101"}, {"enable": False, "dfw_num_slots": 101, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({"dfs": {"dfc_num_slots": 100}}, {"SPLUNK_DFC_NUM_SLOTS": "101"}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 101, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({"dfs": {"dfw_num_slots_enabled": False}}, {"SPLUNK_DFW_NUM_SLOTS_ENABLED": "True"}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": True, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8080}),
({"dfs": {"spark_master_host": "10.0.0.1"}}, {"SPARK_MASTER_HOST": "8.8.8.8"}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "8.8.8.8", "spark_master_webui_port": 8080}),
({"dfs": {"spark_master_webui_port": 8082}}, {"SPARK_MASTER_WEBUI_PORT": "8888"}, {"enable": False, "dfw_num_slots": 10, "dfc_num_slots": 4, "dfw_num_slots_enabled": False, "spark_master_host": "127.0.0.1", "spark_master_webui_port": 8888}),
]
)
def test_getDFS(default_yml, os_env, output):
vars_scope = dict()
vars_scope["splunk"] = default_yml
with patch("os.environ", new=os_env):
environ.getDFS(vars_scope)
# Check typing
assert type(vars_scope["splunk"]["dfs"]["enable"]) == bool
assert type(vars_scope["splunk"]["dfs"]["dfw_num_slots"]) == int
assert type(vars_scope["splunk"]["dfs"]["dfc_num_slots"]) == int
assert type(vars_scope["splunk"]["dfs"]["dfw_num_slots_enabled"]) == bool
assert type(vars_scope["splunk"]["dfs"]["spark_master_webui_port"]) == int
assert vars_scope["splunk"]["dfs"] == output
@pytest.mark.parametrize(("os_env", "deployment_server", "deployment_client", "add", "before_start_cmd", "cmd"),
[
({}, None, None, None, None, None),
# Check environment variable parameters
({"SPLUNK_DEPLOYMENT_SERVER": ""}, None, None, None, None, None),
({"SPLUNK_DEPLOYMENT_SERVER": "something"}, "something", None, None, None, None),
({"SPLUNK_DEPLOYMENT_CLIENT_NAME": ""}, None, None, None, None, None),
({"SPLUNK_DEPLOYMENT_CLIENT_NAME": "client_name"}, None, {"name": "client_name"}, None, None, None),
({"SPLUNK_ADD": ""}, None, None, None, None, None),
({"SPLUNK_ADD": "echo 1"}, None, None, ["echo 1"], None, None),
({"SPLUNK_ADD": "echo 1,echo 2"}, None, None, ["echo 1", "echo 2"], None, None),
({"SPLUNK_BEFORE_START_CMD": ""}, None, None, None, None, None),
({"SPLUNK_BEFORE_START_CMD": "echo 1"}, None, None, None, ["echo 1"], None),
({"SPLUNK_BEFORE_START_CMD": "echo 1,echo 2"}, None, None, None, ["echo 1", "echo 2"], None),
({"SPLUNK_CMD": ""}, None, None, None, None, None),
({"SPLUNK_CMD": "echo 1"}, None, None, None, None, ["echo 1"]),
({"SPLUNK_CMD": "echo 1,echo 2"}, None, None, None, None, ["echo 1", "echo 2"]),
]
)
def test_getUFSplunkVariables(os_env, deployment_server, deployment_client, add, before_start_cmd, cmd):
vars_scope = {"splunk": {}}
with patch("os.environ", new=os_env):
environ.getUFSplunkVariables(vars_scope)
assert vars_scope["splunk"].get("deployment_server") == deployment_server
assert vars_scope["splunk"].get("deployment_client") == deployment_client
assert vars_scope["splunk"].get("add") == add
assert vars_scope["splunk"].get("before_start_cmd") == before_start_cmd
assert vars_scope["splunk"].get("cmd") == cmd
def test_getRandomString():
word = environ.getRandomString()
assert len(word) == 6
@pytest.mark.parametrize(("url", "vars_scope", "output"),
[
("licmaster", {"splunk": {}}, "https://licmaster:8089"),
("http://licmaster", {"splunk": {}}, "http://licmaster:8089"),
("licmaster:8081", {"splunk": {}}, "https://licmaster:8081"),
("http://licmaster:80", {"splunk": {}}, "http://licmaster:80"),
("ftp://licmaster.corp.net:3333", {"splunk": {}}, "ftp://licmaster.corp.net:3333"),
("username:password@lm.internal.net", {"splunk": {}}, "https://lm.internal.net:8089"),
("http://username:password@lm.internal.net:3333", {"splunk": {}}, "http://lm.internal.net:3333"),
# Check null input
("", {"splunk": {}}, ""),
(None, {"splunk": {}}, ""),
# Check vars_scope overrides
("licmaster", {"cert_prefix": "http", "splunk": {"svc_port": 18089}}, "http://licmaster:18089"),
("https://licmaster", {"cert_prefix": "http", "splunk": {"svc_port": 18089}}, "https://licmaster:18089"),
("licmaster:28089", {"cert_prefix": "http", "splunk": {"svc_port": 18089}}, "http://licmaster:28089"),
("https://licmaster:38089", {"cert_prefix": "http", "splunk": {"svc_port": 18089}}, "https://licmaster:38089"),
]
)
def test_parseUrl(url, vars_scope, output):
result = environ.parseUrl(url, vars_scope)
assert result == output
@pytest.mark.parametrize(("dict1", "dict2", "result"),
[
# Check dicts
({}, {"a": 2}, {"a": 2}),
({"b": 2}, {"a": 2}, {"a": 2, "b": 2}),
({"a": 1, "b": 2}, {"a": 2}, {"a": 2, "b": 2}),
({"a": 0}, {"a": 1}, {"a": 1}),
({"a": 1}, {"b": 2, "c": 3}, {"a": 1, "b": 2, "c": 3}),
# Check arrays
({}, {"a": []}, {"a": []}),
({}, {"a": [1, 2]}, {"a": [1, 2]}),
({"b": [0]}, {"a": [1]}, {"a": [1], "b": [0]}),
({"a": [0]}, {"a": [1]}, {"a": [0, 1]}),
# Check nested dict output
({"nested": {}}, {"nested": {"a": 1}}, {"nested": {"a": 1}}),
({"nested": {"a": 1}}, {"nested": {"b": 2}}, {"nested": {"a": 1, "b": 2}}),
({"nested": {"a": 1, "c": 3}}, {"nested": {"b": 2}}, {"nested": {"a": 1, "b": 2, "c": 3}}),
({"nested": {"a": 1, "b": 3}}, {"nested": {"b": 2}}, {"nested": {"a": 1, "b": 2}}),
# Check nested with diff value types
({"nested": {"x": 1}}, {"nested": {"x": {"a": 1}}}, {"nested": {"x": {"a": 1}}}),
({"nested": {"x": {"a": 1}}}, {"nested": {"x": 1}}, {"nested": {"x": 1}}),
# Check nested arrays
({"nested": {"array": []}}, {"nested": {"array": [1]}}, {"nested": {"array": [1]}}),
({"nested": {"array": [1, 2, 3]}}, {"nested": {"array": []}}, {"nested": {"array": [1, 2, 3]}}),
({"nested": {"array": [1, 2]}}, {"nested": {"array": [3, 4, 5]}}, {"nested": {"array": [1, 2, 3, 4, 5]}}),
({"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"}}]}}),
]
)
def test_merge_dict(dict1, dict2, result):
output = environ.merge_dict(dict1, dict2)
assert output == result
@pytest.mark.parametrize(("source", "merge_url_called", "merge_file_called"),
[
(None, False, False),
("", False, False),
(" ", False, False),
("http://web/default.yml", True, False),
("https://web/default.yml", True, False),
("file:///path/to/default.yml", False, True),
("/path/to/default.yml", False, True),
("rel/path/to/default.yml", False, True),
]
)
def test_mergeDefaults(source, merge_url_called, merge_file_called):
with patch("environ.mergeDefaultsFromFile") as mock_merge_file:
with patch("environ.mergeDefaultsFromURL") as mock_merge_url:
result = environ.mergeDefaults({"hello": "world"}, "foobar", source)
if merge_url_called:
mock_merge_url.assert_called_once()
mock_merge_file.assert_not_called()
else:
mock_merge_url.assert_not_called()
if merge_file_called:
mock_merge_file.assert_called_once()
mock_merge_url.assert_not_called()
else:
mock_merge_file.assert_not_called()
@pytest.mark.parametrize(("key"),
[
("FOO"),
("BAR"),
("BAZ"),
]
)
def test_mergeDefaults_url_with_req_params(key):
config = {
"config": {
"FOO": {
"headers": {"HI": "MOM"},
"verify": True
},
"BAR": {
"headers": {"GOODBYE": "MOM"},
"verify": False
}
}
}
with patch("environ.mergeDefaultsFromFile") as mock_merge_file:
with patch("environ.mergeDefaultsFromURL") as mock_merge_url:
result = environ.mergeDefaults(config, key, "http://website/default.yml")
mock_merge_file.assert_not_called()
mock_merge_url.assert_called_once()
if key == "FOO":
mock_merge_url.assert_called_with(config, "http://website/default.yml", {"HI": "MOM"}, True)
elif key == "BAR":
mock_merge_url.assert_called_with(config, "http://website/default.yml", {"GOODBYE": "MOM"}, False)
else:
mock_merge_url.assert_called_with(config, "http://website/default.yml", None, False)
@pytest.mark.parametrize(("vars_scope", "content", "os_env", "headers", "verify"),
[
# Check dicts
({"config": {"max_retries": 3, "max_delay": 4, "max_timeout": 5}}, "helloworld", {}, None, False),
# Change max_timeout
({"config": {"max_retries": 3, "max_delay": 4, "max_timeout": 11}}, "helloworld", {}, None, False),
# Enable verify
({"config": {"max_retries": 3, "max_delay": 4, "max_timeout": 5}}, "helloworld", {}, None, True),
# Exercise bytes content
({"config": {"max_retries": 3, "max_delay": 4, "max_timeout": 5}}, b"helloworld", {}, None, False),
# Exercise various headers
({"config": {"max_retries": 3, "max_delay": 4, "max_timeout": 5}}, "helloworld", {}, {}, False),
({"config": {"max_retries": 3, "max_delay": 4, "max_timeout": 5}}, "helloworld", {}, {"HELLO": "WORLD"}, False),
({"config": {"max_retries": 3, "max_delay": 4, "max_timeout": 5}}, "helloworld", {}, {"A": "B", "C": "D"}, False),
# Exercise OS env vars with headers
({"config": {"max_retries": 3, "max_delay": 4, "max_timeout": 5}}, "helloworld", {"one": "two"}, {}, False),
({"config": {"max_retries": 3, "max_delay": 4, "max_timeout": 5}}, "helloworld", {"SPLUNK_DEFAULTS_HTTP_AUTH_HEADER": "Bearer xyz"}, {"HELLO": "WORLD"}, False),
]
)
def test_mergeDefaultsFromURL(vars_scope, content, os_env, headers, verify):
# Mock response
mock_response = MagicMock()
mock_response.content = "helloworld"
mock_response.status_code = 200
mock_response.raise_for_status = MagicMock()
# Invoke function
with patch("os.environ", new=os_env):
with patch("environ.merge_dict") as mock_merge:
with patch("environ.requests.get") as mock_get:
mock_get.return_value = mock_response
result = environ.mergeDefaultsFromURL(vars_scope, "http://website", headers, verify)
# Check headers and parameters send to GET call
expected_headers = {}
if headers:
expected_headers.update(headers)
if os_env and "SPLUNK_DEFAULTS_HTTP_AUTH_HEADER" is os_env:
expected_headers["Authorization"] = os_env["SPLUNK_DEFAULTS_HTTP_AUTH_HEADER"]
mock_get.assert_called_once()
mock_get.assert_called_with("http://website", headers=expected_headers, timeout=vars_scope["config"]["max_timeout"], verify=verify)
mock_merge.assert_called_once()
mock_merge.assert_called_with(vars_scope, "helloworld")
@pytest.mark.parametrize(("file", "file_exists", "merge_called"),
[
(None, False, False),
("", False, False),
(" ", False, False),
("/path/to/file", False, False),
("/path/to/file", True, True),
]
)
def test_mergeDefaultsFromFile(file, file_exists, merge_called):
mo = mock_open()
with patch("environ.open", mo, create=True):
with patch("environ.os") as mock_os:
with patch("environ.merge_dict") as mock_merge:
mock_os.path.exists = MagicMock(return_value=file_exists)
result = environ.mergeDefaultsFromFile({"hello": "world"}, file)
if merge_called:
mo.assert_called_once()
mock_merge.assert_called_once()
else:
mo.assert_not_called()
mock_merge.assert_not_called()
assert result == {"hello": "world"}
@pytest.mark.parametrize(("mock_base", "mock_baked", "mock_env", "mock_host", "merge_call_count"),
[
# Null cases
({}, [], [], [], 0),
({"config": None}, [], [], [], 0),
({"config": {}}, [], [], [], 0),
# Check baked
({"config": {"foo": "bar"}}, [{"key": "baked", "src": "file1"}], [], [], 1),
({"config": {"foo": "bar"}}, [{"key": "baked", "src": "f1"}, {"key": "baked", "src": "f2"}, {"key": "baked", "src": "f3"}], [], [], 3),
# Check env
({"config": {"foo": "bar"}}, [], [{"key": "env", "src": "file1"}], [], 1),
({"config": {"foo": "bar"}}, [], [{"key": "env", "src": "f1"}, {"key": "env", "src": "f2"}, {"key": "env", "src": "f3"}], [], 3),
# Check host
({"config": {"foo": "bar"}}, [], [], [{"key": "host", "src": "file1"}], 1),
({"config": {"foo": "bar"}}, [], [], [{"key": "host", "src": "f1"}, {"key": "host", "src": "f2"}, {"key": "host", "src": "f3"}], 3),
# Check mixed
({"config": {"foo": "bar"}}, [{"key": "baked", "src": "file1"}], [{"key": "env", "src": "f1"}, {"key": "env", "src": "f2"}], [{"key": "host", "src": "f1"}, {"key": "host", "src": "f2"}], 5),
({"config": None}, [{"key": "baked", "src": "file1"}], [{"key": "env", "src": "f1"}, {"key": "env", "src": "f2"}], [{"key": "host", "src": "f1"}, {"key": "host", "src": "f2"}], 0),
({"config": {}}, [{"key": "baked", "src": "file1"}], [{"key": "env", "src": "f1"}, {"key": "env", "src": "f2"}], [{"key": "host", "src": "f1"}, {"key": "host", "src": "f2"}], 0),
]
)
def test_loadDefaults(mock_base, mock_baked, mock_env, mock_host, merge_call_count):
mbase = MagicMock(return_value=mock_base)
mbaked = MagicMock(return_value=mock_baked)
menv = MagicMock(return_value=mock_env)
mhost = MagicMock(return_value=mock_host)
with patch("environ.loadBaseDefaults", mbase):
with patch("environ.loadBakedDefaults", mbaked):
with patch("environ.loadEnvDefaults", menv):
with patch("environ.loadHostDefaults", mhost):
with patch("environ.mergeDefaults") as mock_merge:
output = environ.loadDefaults()
assert mock_merge.call_count == merge_call_count
@pytest.mark.parametrize(("os_env", "filename"),
[
({}, "splunk_defaults"),
({"SPLUNK_ROLE": "splunk_standalone"}, "splunk_defaults"),
({"SPLUNK_ROLE": "splunk_universal_forwarder"}, "splunkforwarder_defaults"),
]
)
def test_loadBaseDefaults(os_env, filename):
sample_yml = """
this: file
is:
a: yaml
"""
mo = mock_open(read_data=sample_yml)
with patch("environ.open", mo, create=True):
with patch("os.environ", new=os_env):
output = environ.loadBaseDefaults()
mo.assert_called_once()
args, _ = mo.call_args
assert filename in args[0]
assert args[1] == "r"
assert type(output) == dict
assert output["this"] == "file"
@pytest.mark.parametrize(("config", "output"),
[
(None, []),
({}, []),
({"baked": None}, []),
({"baked": ""}, []),
({"baked": "file1"}, [{"key": "baked", "src": "file1"}]),
({"baked": "file1,file2,file3"}, [{"key": "baked", "src": "file1"}, {"key": "baked", "src": "file2"}, {"key": "baked", "src": "file3"}]),
]
)
def test_loadBakedDefaults(config, output):
result = environ.loadBakedDefaults(config)
assert result == output
@pytest.mark.parametrize(("config", "output"),
[
(None, []),
({}, []),
({"env": None}, []),
({"env": {}}, []),
({"env": {"var": None}}, []),
({"env": {"var": ""}}, []),
# Adding test for a key that does not exist
({"env": {"var": "FAKE"}}, []),
# Adding tests for keys that exist
({"env": {"var": "KEY1"}}, [{"key": "env", "src": "file1"}]),
({"env": {"var": "KEY2"}}, [{"key": "env", "src": "file1"}, {"key": "env", "src": "file2"}, {"key": "env", "src": "file3"}]),
]
)
def test_loadEnvDefaults(config, output):
with patch("os.environ", new={"KEY1": "file1", "KEY2": "file1,file2,file3"}):
result = environ.loadEnvDefaults(config)
assert result == output
@pytest.mark.parametrize(("config", "output"),
[
(None, []),
({}, []),
({"host": None}, []),
({"host": {}}, []),
({"host": {"url": None}}, []),
({"host": {"url": ""}}, []),
({"host": {"url": "file1"}}, [{"key": "host", "src": "file1"}]),
({"host": {"url": "file1,file2,file3"}}, [{"key": "host", "src": "file1"}, {"key": "host", "src": "file2"}, {"key": "host", "src": "file3"}]),
]
)
def test_loadHostDefaults(config, output):
result = environ.loadHostDefaults(config)
assert result == output
@pytest.mark.parametrize(("inputInventory", "outputInventory"),
[
# Verify null inputs
({}, {}),
({"all": {}}, {"all": {}}),
({"all": {"vars": {}}}, {"all": {"vars": {}}}),
({"all": {"vars": {"splunk": {}}}}, {"all": {"vars": {"splunk": {}}}}),
# Verify individual keys to obfuscate
({"all": {"vars": {"splunk": {"password": "helloworld"}}}}, {"all": {"vars": {"splunk": {"password": "**************"}}}}),
({"all": {"vars": {"splunk": {"shc": {"secret": "helloworld"}}}}}, {"all": {"vars": {"splunk": {"shc": {"secret": "**************"}}}}}),
({"all": {"vars": {"splunk": {"smartstore": {"index": []}}}}}, {"all": {"vars": {"splunk": {"smartstore": {"index": []}}}}}),
({"all": {"vars": {"splunk": {"smartstore": {"index": [{"s3": {"access_key": "1234", "secret_key": "abcd"}}]}}}}}, {"all": {"vars": {"splunk": {"smartstore": {"index": [{"s3": {"access_key": "**************", "secret_key": "**************"}}]}}}}}),
]
)
def test_obfuscate_vars(inputInventory, outputInventory):
result = environ.obfuscate_vars(inputInventory)
assert result == outputInventory
@pytest.mark.skip(reason="TODO")
def test_create_parser():
pass
@pytest.mark.skip(reason="TODO")
def test_prep_for_yaml_out():
pass
@pytest.mark.skip(reason="TODO")
def test_main():
pass