diff --git a/ansible.cfg b/ansible.cfg index 61b6d040..b20ad914 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -21,6 +21,10 @@ action_warnings = False allow_world_readable_tmpfiles = True stderr_callback=debug stdout_callback=debug +localhost_warning = False + +[inventory] +unparsed_is_failed = True [privilege_escalation] become = true diff --git a/docs/ADVANCED.md b/docs/ADVANCED.md index 996777be..877a7286 100644 --- a/docs/ADVANCED.md +++ b/docs/ADVANCED.md @@ -47,6 +47,7 @@ Splunk-Ansible ships with an inventory script in `inventory/environ.py`. The scr | SPLUNK_CERT_PREFIX | HTTP scheme used when making API requests to Splunk management endpoint. Default: `https` | no | no | no | | SPLUNK_ROOT_ENDPOINT | Allow SplunkWeb to be accessed behind a given route (ex. reverse proxy usage) | no | no | no | | SPLUNK_PASSWORD* | Default password of the admin user | yes | yes | yes | +| SPLUNK_DECLARATVE_ADMIN_PASSWORD | When `true`, admin password will be fixed to the value defined through Ansible | no | no | no | | SPLUNK_PASS4SYMMKEY | Used to overwrite default `pass4SymmKey` for Splunk secrets | no | no | no | | SPLUNK_HEC_TOKEN | HEC (HTTP Event Collector) token when enabled | no | no | no | | SPLUNK_SHC_SECRET | Search Head Clustering shared secret (deprecated in favor of `SPLUNK_SHC_PASS4SYMMKEY`) | no | no | no | @@ -79,6 +80,8 @@ Splunk-Ansible ships with an inventory script in `inventory/environ.py`. The scr | SPLUNK_HTTP_ENABLESSL_CERT | Path to SSL certificate used for SplunkWeb, if HTTPS is enabled | no | no | no | | SPLUNK_HTTP_ENABLESSL_PRIVKEY | Path to SSL private key used for SplunkWeb, if HTTPS is enabled | no | no | no | | SPLUNK_HTTP_ENABLESSL_PRIVKEY_PASSWORD | SSL certificate private key password used with SplunkWeb, if HTTPS is enabled | no | no | no | +| SPLUNK_KVSTORE_PORT | Port to run Splunk KVStore. Default: `8191` | no | no | no | +| SPLUNK_APPSERVER_PORT | Port to run Splunk appserver. Default: `8065` | no | no | no | | SPLUNK_SET_SEARCH_PEERS | Boolean to configure whether search heads should connect to search peers. Default: `True`. Not recommended to change | no | no | no | | SPLUNK_SITE | For multisite topologies, define the site of this particular Splunk Enterprise instance | no | no | no | | SPLUNK_ALL_SITES | For multisite topologies, define all sites of the topology | no | no | no | @@ -91,10 +94,19 @@ Splunk-Ansible ships with an inventory script in `inventory/environ.py`. The scr | NO_HEALTHCHECK | Disable the Splunk health check script | no | no | yes | | STEPDOWN_ANSIBLE_USER | Removes Ansible user from the sudo group when set to true. This means that no other users than root will have root access. | no | no | no | | SPLUNK_HOME_OWNERSHIP_ENFORCEMENT | Recursively enforces `${SPLUNK_HOME}` to be owned by the user "splunk". Default: `True` | no | no | no | +| SPLUNK_DISABLE_POPUPS | Disable pop-ups from login on home page and search app. Default: `False` | no | no | no | | HIDE_PASSWORD | Hide all Ansible task logs containing Splunk password to secure output to `stdout`. | no | no | no | | JAVA_VERSION | Supply `"oracle:8"`, `"openjdk:8"`, or `"openjdk:11"` to install a respective Java distribution. | no | no | no | | JAVA_DOWNLOAD_URL | Provide a custom URL where the Java installation will be fetched| no | no | no | | SPLUNK_TAIL_FILE | Determine which file gets written to the container's stdout (default: `splunkd_stderr.log`) | no | no | no | +| SPLUNK_ES_SSL_ENABLEMENT | When running Enterprise Security version >= 6.3.0, define ssl_enablement installation option | no | no | no | +| SPLUNK_DSP_ENABLE | Enable DSP forwarding. Default: `false` | no | no | no | +| SPLUNK_DSP_SERVER | DSP S2S forwarding endpoint | no | no | no | +| SPLUNK_DSP_CERT | DSP certificate used when forwarding | no | no | no | +| SPLUNK_DSP_VERIFY | Enable cert verification when forwarding to DSP. Default: `false` | no | no | no | +| SPLUNK_DSP_PIPELINE_NAME | Name of DSP pipeline to create/update | no | no | no | +| SPLUNK_DSP_PIPELINE_DESC | Description of DSP pipeline to create/update | no | no | no | +| SPLUNK_DSP_PIPELINE_SPEC | SPL2 specification of DSP pipeline to create/update | no | no | no | | SPLUNK_ENABLE_DFS | Enable [Data Fabric Search (DFS)](https://docs.splunk.com/Documentation/DFS/latest/DFS/Overview) | no | no | no | | SPLUNK_DFW_NUM_SLOTS | Maximum number of concurrent DFS searches that run on a search head cluster | no | no | no | | SPLUNK_DFC_NUM_SLOTS | Maximum number of concurrent DFS searches that run on each search head | no | no | no | diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 53f348b4..ae38ec27 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,6 +2,8 @@ ## Navigation +* [8.0.6](#806) +* [8.0.5.1](#8051) * [8.0.5](#805) * [8.0.4.1](#8041) * [8.0.4](#804) @@ -35,6 +37,33 @@ --- +## 8.0.6 + +#### What's New? +* Support for declarative admin password, enabling password updates and rotations. `splunk.password` will always be the password for the admin user and changes to `splunk.password` will drive password reconciliation. + * `splunk.declarative_admin_password` in `default.yml` + * `SPLUNK_DECLARATVE_ADMIN_PASSWORD` environment variable +* Added flag to disable pop-ups and new user tour + * `splunk.disable_popups` in `default.yml` + * `SPLUNK_DISABLE_POPUPS` environment variable + +#### Changes +* Fixed default variable propagation order +* ASan v5 is dynamically linked to builds +* Bugfixes and security updates + +--- + +## 8.0.5.1 + +#### What's New? +Syncing with latest codebase - currently up to sync with 8.0.6. + +#### Changes +* See [8.0.6](#806) changes above. + +--- + ## 8.0.5 #### What's New? diff --git a/docs/SETUP.md b/docs/SETUP.md index 01daa379..acace9de 100644 --- a/docs/SETUP.md +++ b/docs/SETUP.md @@ -51,7 +51,13 @@ $ docker run -it splunk/splunk:latest create-defaults > default.yml ``` Alternatively, you can download the example `default.yml` supplied [here](advanced/default.yml.spec.md#sample). -3. Inspect your newly-created `default.yml` and tweak options as you see fit. For a full list of parameters, please see the [`default.yml.spec`](advanced/default.yml.spec.md#spec). +3. Define a few key variables in your `default.yml`: +* `splunk.role`: the role this instance will play in the Splunk Enterprise deployment +* `splunk.build_location`: URL to dynamically fetch the Splunk Enterprise build and install it at run time +* `splunk.build_remote_src`: this wll be `true` when `splunk.build_location` above is a URL +* `splunk.password`: default `admin` user password that Splunk will be provisioned with on first-time run + +4. Inspect your newly-created `default.yml` and tweak options as you see fit. For a full list of parameters, please see the [`default.yml.spec`](advanced/default.yml.spec.md#spec). ## Execute playbooks In order to get your container to run Ansible, it needs a copy of all the playbooks. @@ -63,7 +69,7 @@ $ docker cp . splcontainer:/tmp/splunk-ansible/ 2. Run the following command ``` -$ docker exec -it splcontainer bash -c 'cd /tmp/splunk-ansible; ansible-playbook --connection local site.yml --extra-vars "@default.yml"' +$ docker exec -it splcontainer bash -c 'cd /tmp/splunk-ansible; ansible-playbook --inventory localhost, --connection local site.yml --extra-vars "@default.yml"' ``` You should see streaming Ansible output in your terminal. Here is what is happening when you run the above command: * `ansible-playbook` command is invoked using the playbook `site.yml` diff --git a/docs/advanced/default.yml.spec.md b/docs/advanced/default.yml.spec.md index 26f7a9fc..b7b25d68 100644 --- a/docs/advanced/default.yml.spec.md +++ b/docs/advanced/default.yml.spec.md @@ -182,6 +182,10 @@ splunk: * NOTE: This is being deprecated in favor of `splunk.search_head_captain_url`. * Default: null + disable_popups: + * When set to true, pop-ups/modals will be disabled from login on the homescreen and search app. + * Default: false + preferred_captaincy: * Boolean to determine whether splunk should set a preferred captain. This can have an effect on day 2 operations if the search heads need to be restarted * Default: true @@ -214,6 +218,10 @@ splunk: * Default Splunk admin user password. This is REQUIRED when starting Splunk, and can only be set during the first-time run of the playbooks. If changes are required to the admin password, they should be done through SplunkWeb/CLI and the new value should be re-entered here. * Default: null + declarative_admin_password: + * When set to true, the playbooks will always enforce that the admin password is set to the value of `password` above. Any changes to the admin password outside of splunk-ansible will be reverted. + * Default: false + user: * Host user under which Splunk will run * Default: splunk diff --git a/execute_adhoc_plays.yml b/execute_adhoc_plays.yml index 8d2dd44f..a06bde2c 100644 --- a/execute_adhoc_plays.yml +++ b/execute_adhoc_plays.yml @@ -4,6 +4,7 @@ url: "{{ playbook }}" dest: "{{ '/opt/container_artifact/' + playbook|basename }}" force: yes + mode: 0666 ignore_errors: yes register: downloaded_plays when: diff --git a/inventory/environ.py b/inventory/environ.py index 48891749..f4229659 100755 --- a/inventory/environ.py +++ b/inventory/environ.py @@ -111,6 +111,7 @@ def getDefaultVars(): overrideEnvironmentVars(defaultVars) getAnsibleContext(defaultVars) getASan(defaultVars) + getDisablePopups(defaultVars) getHEC(defaultVars) getSecrets(defaultVars) getSplunkPaths(defaultVars) @@ -365,6 +366,11 @@ def getSecrets(vars_scope): vars_scope["splunk"]["password"] = f.read().strip() if not vars_scope["splunk"]["password"]: raise Exception("Splunk password supplied is empty/null") + dpw = os.environ.get("SPLUNK_DECLARATIVE_ADMIN_PASSWORD", "") + if dpw.lower() == "true": + vars_scope["splunk"]["declarative_admin_password"] = True + else: + vars_scope["splunk"]["declarative_admin_password"] = bool(vars_scope["splunk"].get("declarative_admin_password")) vars_scope["splunk"]["pass4SymmKey"] = os.environ.get('SPLUNK_PASS4SYMMKEY', vars_scope["splunk"].get("pass4SymmKey")) vars_scope["splunk"]["secret"] = os.environ.get('SPLUNK_SECRET', vars_scope["splunk"].get("secret")) @@ -403,6 +409,17 @@ def getASan(vars_scope): if vars_scope["splunk"]["asan"]: vars_scope["ansible_environment"].update({"ASAN_OPTIONS": "detect_leaks=0"}) +def getDisablePopups(vars_scope): + """ + Configure pop-up settings + """ + vars_scope["splunk"]["disable_popups"] = bool(vars_scope["splunk"].get("disable_popups")) + popups_disabled = os.environ.get("SPLUNK_DISABLE_POPUPS", "") + if popups_disabled.lower() == "true": + vars_scope["splunk"]["disable_popups"] = True + elif popups_disabled.lower() == "false": + vars_scope["splunk"]["disable_popups"] = False + def getHEC(vars_scope): """ Configure HEC settings @@ -613,19 +630,16 @@ def loadDefaults(): """ # Load base defaults from splunk-ansible repository base = loadBaseDefaults() - # Build an array of new defaults to override the base - ymls = [] - config = base.get("config") - if not config: + if not base.get("config"): return base # Add "baked" files to array - ymls.extend(loadBakedDefaults(config)) - # Add "env" URLs to array - ymls.extend(loadEnvDefaults(config)) - # Add "host" URLs to array - ymls.extend(loadHostDefaults(config)) - # For each new YAML discovered, merge them with base in order so values get superseded - for yml in ymls: + for yml in loadBakedDefaults(base.get("config")): + base = mergeDefaults(base, yml["key"], yml["src"]) + # Add "env" files to array + for yml in loadEnvDefaults(base.get("config")): + base = mergeDefaults(base, yml["key"], yml["src"]) + # Add "host" files to array + for yml in loadHostDefaults(base.get("config")): base = mergeDefaults(base, yml["key"], yml["src"]) return base diff --git a/inventory/splunk_defaults_linux.yml b/inventory/splunk_defaults_linux.yml index b9bbedbb..09c88bea 100644 --- a/inventory/splunk_defaults_linux.yml +++ b/inventory/splunk_defaults_linux.yml @@ -35,6 +35,7 @@ splunk: admin_user: "admin" root_endpoint: password: + declarative_admin_password: False secret: pass4SymmKey: svc_port: 8089 @@ -110,6 +111,7 @@ splunk: deployer_url: connection_timeout: 0 enable_service: False + disable_popups: False service_name: smartstore: app_paths: diff --git a/inventory/splunk_defaults_windows.yml b/inventory/splunk_defaults_windows.yml index 64d4ddf7..c12e913e 100644 --- a/inventory/splunk_defaults_windows.yml +++ b/inventory/splunk_defaults_windows.yml @@ -35,6 +35,7 @@ splunk: admin_user: "admin" root_endpoint: password: + declarative_admin_password: False secret: pass4SymmKey: svc_port: 8089 @@ -102,6 +103,7 @@ splunk: deployer_url: connection_timeout: 180 enable_service: False + disable_popups: False service_name: smartstore: app_paths: diff --git a/inventory/splunkforwarder_defaults_linux.yml b/inventory/splunkforwarder_defaults_linux.yml index 0e155222..7a7d149e 100644 --- a/inventory/splunkforwarder_defaults_linux.yml +++ b/inventory/splunkforwarder_defaults_linux.yml @@ -35,6 +35,7 @@ splunk: admin_user: "admin" root_endpoint: password: + declarative_admin_password: False secret: pass4SymmKey: svc_port: 8089 @@ -102,6 +103,7 @@ splunk: deployer_url: connection_timeout: 0 enable_service: False + disable_popups: False service_name: smartstore: app_paths: diff --git a/inventory/splunkforwarder_defaults_windows.yml b/inventory/splunkforwarder_defaults_windows.yml index 1be5d8aa..74198340 100644 --- a/inventory/splunkforwarder_defaults_windows.yml +++ b/inventory/splunkforwarder_defaults_windows.yml @@ -35,6 +35,7 @@ splunk: admin_user: "admin" root_endpoint: password: + declarative_admin_password: False secret: pass4SymmKey: svc_port: 8089 @@ -102,6 +103,7 @@ splunk: deployer_url: connection_timeout: 180 enable_service: False + disable_popups: False service_name: smartstore: app_paths: diff --git a/roles/splunk_common/tasks/add_forward_server.yml b/roles/splunk_common/tasks/add_forward_server.yml index 28d06d8f..fac2cc7c 100644 --- a/roles/splunk_common/tasks/add_forward_server.yml +++ b/roles/splunk_common/tasks/add_forward_server.yml @@ -1,6 +1,6 @@ --- - name: "Enable forwarding to {{ forward_servers }}" - command: "{{ splunk.exec }} add forward-server {{ item }}:{{ splunk.s2s.port if splunk.s2s.port is defined else splunk.s2s_port }} -auth {{ splunk.admin_user }}:{{ splunk.password }}" + command: "{{ splunk.exec }} add forward-server {{ item }}:{{ splunk.s2s.port if splunk.s2s.port is defined else splunk.s2s_port }} -auth {{ splunk.admin_user }}:{{ splunk.password }} --accept-license --answer-yes --no-prompt" become: yes become_user: "{{ splunk.user }}" with_items: "{{ forward_servers }}" @@ -39,18 +39,6 @@ no_log: "{{ hide_password }}" register: enable_ssl_forwarding -- name: "Get Splunk status" - command: "{{ splunk.exec }} status --accept-license --answer-yes --no-prompt" - become: yes - become_user: "{{ splunk.user }}" - register: splunk_status - changed_when: False - failed_when: False - ignore_errors: yes - -# We want to restart only when Splunk is currently running and when any of the above have changed -- name: Trigger restart - command: ls - changed_when: splunk_status.rc == 0 and (forward_status is changed or enable_ssl_forwarding is changed) - notify: - - Restart the splunkd service +# Restart only when Splunk is running and when any of the above have changed +- include_tasks: trigger_restart.yml + when: forward_status is changed or enable_ssl_forwarding is changed diff --git a/roles/splunk_common/tasks/disable_popups.yml b/roles/splunk_common/tasks/disable_popups.yml new file mode 100644 index 00000000..39edce72 --- /dev/null +++ b/roles/splunk_common/tasks/disable_popups.yml @@ -0,0 +1,27 @@ +--- +- name: GET OptInVersion + uri: + url: "{{ cert_prefix }}://127.0.0.1:{{ splunk.svc_port }}/servicesNS/nobody/splunk_instrumentation/admin/telemetry/general?output_mode=json" + method: GET + user: "{{ splunk.admin_user }}" + password: "{{ splunk.password }}" + validate_certs: false + status_code: 200 + timeout: 10 + return_content: yes + register: telemetry + no_log: "{{ hide_password }}" + +- name: Disable Popups + uri: + url: "{{ cert_prefix }}://127.0.0.1:{{ splunk.svc_port }}/{{ item.key }}" + method: POST + user: "{{ splunk.admin_user }}" + password: "{{ splunk.password }}" + body: "{{ item.value }}" + validate_certs: false + status_code: 200,201,409 + with_items: + - { key: "servicesNS/admin/user-prefs/data/user-prefs/general", value: "hideInstrumentationOptInModal=1¬ification_python_3_impact=false&showWhatsNew=0" } + - { key: "servicesNS/nobody/splunk_instrumentation/admin/telemetry/general", value: "showOptInModal=0&optInVersionAcknowledged={{ telemetry['json']['entry'][0]['content']['optInVersion'] }}" } + - { key: "servicesNS/admin/search/data/ui/ui-tour/search-tour", value: "tourPage=search&viewed=1" } \ No newline at end of file diff --git a/roles/splunk_common/tasks/enable_admin_auth.yml b/roles/splunk_common/tasks/enable_admin_auth.yml new file mode 100644 index 00000000..e5db1271 --- /dev/null +++ b/roles/splunk_common/tasks/enable_admin_auth.yml @@ -0,0 +1,56 @@ +--- +- name: Set admin access via seed + when: first_run | bool + block: + - name: "Hash the password" + command: "{{ splunk.exec }} hash-passwd {{ splunk.password }}" + register: hashed_pwd + changed_when: hashed_pwd.rc == 0 + become: yes + become_user: "{{ splunk.user }}" + no_log: "{{ hide_password }}" + + - name: "Generate user-seed.conf (Linux)" + ini_file: + owner: "{{ splunk.user }}" + group: "{{ splunk.group }}" + dest: "{{ splunk.home }}/etc/system/local/user-seed.conf" + section: user_info + option: "{{ item.opt }}" + value: "{{ item.val }}" + with_items: + - { opt: 'USERNAME', val: '{{ splunk.admin_user }}' } + - { opt: 'HASHED_PASSWORD', val: '{{ hashed_pwd.stdout }}' } + loop_control: + label: "{{ item.opt }}" + when: ansible_system is match("Linux") + no_log: "{{ hide_password }}" + + - name: "Generate user-seed.conf (Windows)" + ini_file: + dest: "{{ splunk.home }}/etc/system/local/user-seed.conf" + section: user_info + option: "{{ item.opt }}" + value: "{{ item.val }}" + with_items: + - { opt: 'USERNAME', val: '{{ splunk.admin_user }}' } + - { opt: 'HASHED_PASSWORD', val: '{{ hashed_pwd.stdout }}' } + loop_control: + label: "{{ item.opt }}" + when: ansible_system is match("CYGWIN*|Win32NT") + no_log: "{{ hide_password }}" + +- name: Establish declarative admin access + when: + - "'declarative_admin_password' in splunk and splunk.declarative_admin_password | bool" + - not first_run | bool + block: + - name: Apply admin password + command: "{{ splunk.exec }} cmd splunkd rest --noauth POST /services/admin/users/{{ splunk.admin_user }} 'password={{ splunk.password }}'" + register: declarative_pw + changed_when: False + become: yes + become_user: "{{ splunk.user }}" + no_log: "{{ hide_password }}" + + - include_tasks: trigger_restart.yml diff --git a/roles/splunk_common/tasks/enable_asan.yml b/roles/splunk_common/tasks/enable_asan.yml index fb65009f..db1ff932 100644 --- a/roles/splunk_common/tasks/enable_asan.yml +++ b/roles/splunk_common/tasks/enable_asan.yml @@ -1,13 +1,33 @@ --- -- name: Copy ASan libraries +- name: Check version of ASan + stat: + path: "{{ splunk.home }}/lib/libasan.so.5.0.0" + register: result + +- name: Copy new ASan libraries copy: src: "{{ splunk.home }}/lib/{{ item }}" - dest: "/lib64/{{ item }}" + dest: "{{'/lib' if ansible_facts['os_family'] == 'Debian' else '/lib64'}}/{{ item }}" remote_src: yes mode: 0755 + when: result.stat.exists + with_items: + - libasan.so + - libasan.so.5 + - libasan.so.5.0.0 + become: yes + become_user: "{{ privileged_user }}" + +- name: Copy old ASan libraries + copy: + src: "{{ splunk.home }}/lib/{{ item }}" + dest: "{{'/lib' if ansible_facts['os_family'] == 'Debian' else '/lib64'}}/{{ item }}" + remote_src: yes + mode: 0755 + when: not result.stat.exists with_items: - - libssp.so.0 - libasan.so + - libssp.so.0 - libasan.so.2 - libasan.so.2.0.0 become: yes diff --git a/roles/splunk_common/tasks/enable_dsp.yml b/roles/splunk_common/tasks/enable_dsp.yml index b229c6b7..e9409de7 100644 --- a/roles/splunk_common/tasks/enable_dsp.yml +++ b/roles/splunk_common/tasks/enable_dsp.yml @@ -6,6 +6,7 @@ dest: "{{ splunk.home }}/etc/auth/DigiCertGlobalRootCA.pem" owner: "{{ splunk.user }}" group: "{{ splunk.group }}" + mode: 0666 - name: Set root CA ini_file: @@ -85,18 +86,6 @@ - splunk.dsp.pipeline_name is defined and splunk.dsp.pipeline_name - splunk.dsp.pipeline_spec is defined and splunk.dsp.pipeline_spec -- name: Get Splunk status - command: "{{ splunk.exec }} status --accept-license --answer-yes --no-prompt" - become: yes - become_user: "{{ splunk.user }}" - register: splunk_status - changed_when: False - failed_when: False - ignore_errors: yes - -# We want to restart only when Splunk is currently running and when any of the above have changed -- name: Trigger restart - command: ls - changed_when: splunk_status.rc == 0 and (dsp_ca is changed or dsp_group is changed or dsp_default is changed) - notify: - - Restart the splunkd service +# Restart only when Splunk is running and when any of the above have changed +- include_tasks: trigger_restart.yml + when: dsp_ca is changed or dsp_group is changed or dsp_default is changed diff --git a/roles/splunk_common/tasks/enable_forwarding.yml b/roles/splunk_common/tasks/enable_forwarding.yml index 9369c459..070d8f32 100644 --- a/roles/splunk_common/tasks/enable_forwarding.yml +++ b/roles/splunk_common/tasks/enable_forwarding.yml @@ -77,18 +77,6 @@ - not splunk_indexer_cluster | bool - splunk_forward_servers is defined -- name: "Get Splunk status" - command: "{{ splunk.exec }} status --accept-license --answer-yes --no-prompt" - become: yes - become_user: "{{ splunk.user }}" - register: splunk_status - changed_when: False - failed_when: False - ignore_errors: yes - -# We want to restart only when Splunk is currently running and when any of the above have changed -- name: Trigger restart - command: ls - changed_when: splunk_status.rc == 0 and (indexer_discovery is changed or tcpout_group is changed or default_tcpout_group is changed or index_disabling is changed) - notify: - - Restart the splunkd service +# Restart only when Splunk is running and when any of the above have changed +- include_tasks: trigger_restart.yml + when: indexer_discovery is changed or tcpout_group is changed or default_tcpout_group is changed or index_disabling is changed diff --git a/roles/splunk_common/tasks/get_splunk_status.yml b/roles/splunk_common/tasks/get_splunk_status.yml new file mode 100644 index 00000000..debf7f61 --- /dev/null +++ b/roles/splunk_common/tasks/get_splunk_status.yml @@ -0,0 +1,9 @@ +--- +- name: Get Splunk status + command: "{{ splunk.exec }} status --accept-license --answer-yes --no-prompt" + become: yes + become_user: "{{ splunk.user }}" + register: splunk_status + changed_when: False + failed_when: False + ignore_errors: yes diff --git a/roles/splunk_common/tasks/install_apps.yml b/roles/splunk_common/tasks/install_apps.yml index 1f8b50c3..e7ecd2d7 100644 --- a/roles/splunk_common/tasks/install_apps.yml +++ b/roles/splunk_common/tasks/install_apps.yml @@ -11,6 +11,7 @@ update: "true" filename: "true" auth: "{{ splunkbase_token }}" + mode: 0666 body_format: "form-urlencoded" status_code: [ 200, 201 ] timeout: 300 diff --git a/roles/splunk_common/tasks/install_splunk_tgz.yml b/roles/splunk_common/tasks/install_splunk_tgz.yml index 018cc249..23732886 100644 --- a/roles/splunk_common/tasks/install_splunk_tgz.yml +++ b/roles/splunk_common/tasks/install_splunk_tgz.yml @@ -6,6 +6,7 @@ group: "{{ splunk.group }}" headers: '{% if splunk.build_url_bearer_token %}{"Authorization": "Bearer {{ splunk.build_url_bearer_token }}"}{% else %}{}{% endif %}' validate_certs: no + mode: 0666 when: splunk.build_location is match("^(https?)://.*") register: download_result become: yes diff --git a/roles/splunk_common/tasks/java_tasks/install_openjdk9_jdk_windows.yml b/roles/splunk_common/tasks/java_tasks/install_openjdk9_jdk_windows.yml index e3fa3743..0d6ec82f 100644 --- a/roles/splunk_common/tasks/java_tasks/install_openjdk9_jdk_windows.yml +++ b/roles/splunk_common/tasks/java_tasks/install_openjdk9_jdk_windows.yml @@ -4,6 +4,7 @@ url: "https://download.java.net/openjdk/jdk9/ri/jdk-9+181_windows-x64_ri.zip" dest: /home/splunk/ timeout: 30 + mode: 0666 register: download_result until: download_result.status_code == 200 retries: "{{ retry_num }}" diff --git a/roles/splunk_common/tasks/java_tasks/install_oracle8_jdk.yml b/roles/splunk_common/tasks/java_tasks/install_oracle8_jdk.yml index 9a79571c..5951203c 100644 --- a/roles/splunk_common/tasks/java_tasks/install_oracle8_jdk.yml +++ b/roles/splunk_common/tasks/java_tasks/install_oracle8_jdk.yml @@ -6,6 +6,7 @@ Cookie: oraclelicense=accept-securebackup-cookie dest: /opt/container_artifact timeout: 90 + mode: 0666 register: download_result until: download_result.status_code == 200 retries: "{{ retry_num }}" diff --git a/roles/splunk_common/tasks/licenses/add_license.yml b/roles/splunk_common/tasks/licenses/add_license.yml index 4e03df28..b500f79d 100644 --- a/roles/splunk_common/tasks/licenses/add_license.yml +++ b/roles/splunk_common/tasks/licenses/add_license.yml @@ -4,6 +4,7 @@ url: "{{ lic }}" dest: "{{ splunk.license_download_dest }}" timeout: 20 + mode: 0666 when: lic is match("^(https?|file)://.*") register: downloaded_license_path ignore_errors: yes diff --git a/roles/splunk_common/tasks/main.yml b/roles/splunk_common/tasks/main.yml index f77e226c..8fdabd3c 100644 --- a/roles/splunk_common/tasks/main.yml +++ b/roles/splunk_common/tasks/main.yml @@ -37,26 +37,18 @@ - "'asan' in splunk and splunk.asan | bool" - include_tasks: remove_first_login.yml - when: - - first_run | bool - include_tasks: install_java.yml when: - java_version is defined and java_version - include_tasks: set_general_symmkey_password.yml - when: - - "'pass4SymmKey' in splunk and splunk.pass4SymmKey" - - first_run | bool + when: "'pass4SymmKey' in splunk and splunk.pass4SymmKey" # This needs to be done before any encrypted passkeys are generated - include_tasks: set_splunk_secret.yml - when: - - first_run | bool -- include_tasks: set_user_seed.yml - when: - - first_run | bool +- include_tasks: enable_admin_auth.yml - include_tasks: set_launch_conf.yml when: @@ -64,8 +56,6 @@ - include_tasks: pre_splunk_start_commands.yml ignore_errors: true - when: - - first_run | bool - include_tasks: enable_s2s.yml when: @@ -139,3 +129,6 @@ - include_tasks: clean_user_seed.yml - include_tasks: add_splunk_license.yml + +- include_tasks: disable_popups.yml + when: "'disable_popups' in splunk and splunk.disable_popups | bool" \ No newline at end of file diff --git a/roles/splunk_common/tasks/premium_apps/configure_ess.yml b/roles/splunk_common/tasks/premium_apps/configure_ess.yml index fe3be939..dd3d09e0 100644 --- a/roles/splunk_common/tasks/premium_apps/configure_ess.yml +++ b/roles/splunk_common/tasks/premium_apps/configure_ess.yml @@ -12,7 +12,7 @@ no_log: "{{ hide_password }}" - name: Run ESS post-install setup - command: "{{ splunk.exec }} search '| essinstall {% if ess_info.json.entry[0].content.version is version('6.3', '>=') %}{{ es_ssl_enablement }}{% endif %}' -auth {{ splunk.admin_user }}:{{ splunk.password }}" + command: "{{ splunk.exec }} search '| essinstall {% if ess_info.json.entry[0].content.version is version('6.3', '>=') %}{{ es_ssl_enablement }}{% endif %} {% if splunk.role == 'splunk_deployer' %}--deployment_type shc_deployer{% endif %}' -auth {{ splunk.admin_user }}:{{ splunk.password }}" no_log: "{{ hide_password }}" become: yes become_user: "{{ splunk.user }}" diff --git a/roles/splunk_common/tasks/remove_first_login.yml b/roles/splunk_common/tasks/remove_first_login.yml index 6aca810b..15ed4641 100644 --- a/roles/splunk_common/tasks/remove_first_login.yml +++ b/roles/splunk_common/tasks/remove_first_login.yml @@ -3,6 +3,8 @@ file: path: "{{ splunk.home }}/etc/.ui_login" state: touch + modification_time: preserve + access_time: preserve owner: "{{ splunk.user }}" group: "{{ splunk.group }}" mode: 0660 diff --git a/roles/splunk_common/tasks/s2s/configure_splunktcp.yml b/roles/splunk_common/tasks/s2s/configure_splunktcp.yml index b4c7b183..5c68ccaa 100644 --- a/roles/splunk_common/tasks/s2s/configure_splunktcp.yml +++ b/roles/splunk_common/tasks/s2s/configure_splunktcp.yml @@ -37,18 +37,6 @@ group: "{{ splunk.group }}" register: splunktcp_ssl_ca_reset -- name: "Get Splunk status" - command: "{{ splunk.exec }} status --accept-license --answer-yes --no-prompt" - become: yes - become_user: "{{ splunk.user }}" - register: splunk_status - changed_when: False - failed_when: False - ignore_errors: yes - -# We want to restart only when Splunk is currently running and when any of the above have changed -- name: Trigger restart - command: ls - changed_when: splunk_status.rc == 0 and (splunktcp_enabled is changed or splunktcp_ssl_disabled is changed or splunktcp_ssl_reset is changed or splunktcp_ssl_ca_reset is changed) - notify: - - Restart the splunkd service +# Restart only when Splunk is running and when any of the above have changed +- include_tasks: trigger_restart.yml + when: splunktcp_enabled is changed or splunktcp_ssl_disabled is changed or splunktcp_ssl_reset is changed or splunktcp_ssl_ca_reset is changed diff --git a/roles/splunk_common/tasks/s2s/configure_splunktcp_ssl.yml b/roles/splunk_common/tasks/s2s/configure_splunktcp_ssl.yml index 1824e3ad..50a81761 100644 --- a/roles/splunk_common/tasks/s2s/configure_splunktcp_ssl.yml +++ b/roles/splunk_common/tasks/s2s/configure_splunktcp_ssl.yml @@ -50,18 +50,6 @@ when: ansible_system is not match("CYGWIN*|Win32NT") register: splunktcp_ssl_ca_configured -- name: "Get Splunk status" - command: "{{ splunk.exec }} status --accept-license --answer-yes --no-prompt" - become: yes - become_user: "{{ splunk.user }}" - register: splunk_status - changed_when: False - failed_when: False - ignore_errors: yes - -# We want to restart only when Splunk is currently running and when any of the above have changed -- name: Trigger restart - command: ls - changed_when: splunk_status.rc == 0 and (splunktcp_disabled is changed or splunktcp_ssl_cert_configured is changed or splunktcp_ssl_pass_configured is changed or splunktcp_ssl_ca_configured is changed) - notify: - - Restart the splunkd service +# Restart only when Splunk is running and when any of the above have changed +- include_tasks: trigger_restart.yml + when: splunktcp_disabled is changed or splunktcp_ssl_cert_configured is changed or splunktcp_ssl_pass_configured is changed or splunktcp_ssl_ca_configured is changed diff --git a/roles/splunk_common/tasks/set_certificate_prefix.yml b/roles/splunk_common/tasks/set_certificate_prefix.yml index 8e021283..300ad341 100644 --- a/roles/splunk_common/tasks/set_certificate_prefix.yml +++ b/roles/splunk_common/tasks/set_certificate_prefix.yml @@ -1,10 +1,8 @@ --- - name: "Test basic https endpoint" uri: - url: "https://127.0.0.1:{{ splunk.svc_port }}/services/properties" + url: "https://127.0.0.1:{{ splunk.svc_port }}" method: GET - user: "{{ splunk.admin_user }}" - password: "{{ splunk.password }}" validate_certs: false status_code: 200,404 timeout: 10 diff --git a/roles/splunk_common/tasks/set_general_symmkey_password.yml b/roles/splunk_common/tasks/set_general_symmkey_password.yml index 65a38a6b..e36dcb80 100644 --- a/roles/splunk_common/tasks/set_general_symmkey_password.yml +++ b/roles/splunk_common/tasks/set_general_symmkey_password.yml @@ -6,5 +6,7 @@ value: "{{ splunk.pass4SymmKey }}" owner: "{{ splunk.user }}" group: "{{ splunk.group }}" - notify: - - Restart the splunkd service + register: set_symmkey + +- include_tasks: trigger_restart.yml + when: set_symmkey is changed diff --git a/roles/splunk_common/tasks/set_root_endpoint.yml b/roles/splunk_common/tasks/set_root_endpoint.yml index 1d064062..7c4e4701 100644 --- a/roles/splunk_common/tasks/set_root_endpoint.yml +++ b/roles/splunk_common/tasks/set_root_endpoint.yml @@ -9,18 +9,6 @@ group: "{{ splunk.group }}" register: set_root_endpoint -- name: "Get Splunk status" - command: "{{ splunk.exec }} status --accept-license --answer-yes --no-prompt" - become: yes - become_user: "{{ splunk.user }}" - register: splunk_status - changed_when: False - failed_when: False - ignore_errors: yes - -# Restart only when Splunk is currently running and when any of the above have changed -- name: Trigger restart - command: ls - changed_when: splunk_status.rc == 0 and set_root_endpoint is changed - notify: - - Restart the splunkd service +# Restart only when Splunk is running and when any of the above have changed +- include_tasks: trigger_restart.yml + when: set_root_endpoint is changed diff --git a/roles/splunk_common/tasks/set_user_seed.yml b/roles/splunk_common/tasks/set_user_seed.yml deleted file mode 100644 index a706cedb..00000000 --- a/roles/splunk_common/tasks/set_user_seed.yml +++ /dev/null @@ -1,38 +0,0 @@ ---- -- name: "Hash the password" - command: "{{ splunk.exec }} hash-passwd {{ splunk.password }}" - register: hashed_pwd - changed_when: hashed_pwd.rc == 0 - become: yes - become_user: "{{ splunk.user }}" - no_log: "{{ hide_password }}" - -- name: "Generate user-seed.conf (Linux)" - ini_file: - owner: "{{ splunk.user }}" - group: "{{ splunk.group }}" - dest: "{{ splunk.home }}/etc/system/local/user-seed.conf" - section: user_info - option: "{{ item.opt }}" - value: "{{ item.val }}" - with_items: - - { opt: 'USERNAME', val: '{{ splunk.admin_user }}' } - - { opt: 'HASHED_PASSWORD', val: '{{ hashed_pwd.stdout }}' } - loop_control: - label: "{{ item.opt }}" - when: ansible_system is match("Linux") - no_log: "{{ hide_password }}" - -- name: "Generate user-seed.conf (Windows)" - ini_file: - dest: "{{ splunk.home }}/etc/system/local/user-seed.conf" - section: user_info - option: "{{ item.opt }}" - value: "{{ item.val }}" - with_items: - - { opt: 'USERNAME', val: '{{ splunk.admin_user }}' } - - { opt: 'HASHED_PASSWORD', val: '{{ hashed_pwd.stdout }}' } - loop_control: - label: "{{ item.opt }}" - when: ansible_system is match("CYGWIN*|Win32NT") - no_log: "{{ hide_password }}" diff --git a/roles/splunk_common/tasks/start_splunk.yml b/roles/splunk_common/tasks/start_splunk.yml index dd1a2014..30a6d5db 100644 --- a/roles/splunk_common/tasks/start_splunk.yml +++ b/roles/splunk_common/tasks/start_splunk.yml @@ -1,64 +1,55 @@ --- -- name: "Get Splunk status" - command: "{{ splunk.exec }} status --accept-license --answer-yes --no-prompt" - become: yes - become_user: "{{ splunk.user }}" - register: splunk_status - changed_when: False - failed_when: False - ignore_errors: yes - -- name: "Cleanup Splunk runtime files" - file: - state: absent - path: "{{ item }}" - with_items: - - "{{ splunk.home }}/var/run/splunk/splunkd.pid" - - "{{ splunk.home }}/var/lib/splunk/kvstore/mongo/mongod.lock" - when: - - splunk_status.rc != 0 - become: yes - become_user: "{{ splunk.user }}" - -- name: "Restrict permissions on splunk.key" - include_tasks: restrict_permissions.yml - vars: - file_path: "{{ item }}" - with_items: - - "{{ splunk.home }}/var/lib/splunk/kvstore/mongo/splunk.key" - when: - - splunk_status.rc != 0 +- include_tasks: get_splunk_status.yml - name: "Start Splunk" + when: splunk_status.rc != 0 block: - - name: "Start Splunk via CLI" - command: "{{ splunk.exec }} start --accept-license --answer-yes --no-prompt" - register: start_splunk - changed_when: start_splunk.rc == 0 and 'already running' not in start_splunk.stdout - become: yes - become_user: "{{ splunk.user }}" - when: - - not splunk.enable_service + - name: Cleanup Splunk runtime files + file: + state: absent + path: "{{ item }}" + with_items: + - "{{ splunk.home }}/var/run/splunk/splunkd.pid" + - "{{ splunk.home }}/var/lib/splunk/kvstore/mongo/mongod.lock" + become: yes + become_user: "{{ splunk.user }}" - - name: "Start Splunk via service" - service: - name: "{{ splunk_service_name }}" - state: started - become: yes - become_user: "{{ privileged_user }}" - when: - - splunk.enable_service - - ansible_system is match("Linux") + - name: "Restrict permissions on splunk.key" + include_tasks: restrict_permissions.yml + vars: + file_path: "{{ item }}" + with_items: + - "{{ splunk.home }}/var/lib/splunk/kvstore/mongo/splunk.key" - - name: "Start Splunk via Windows service" - win_service: - name: splunkd - state: started - when: - - splunk.enable_service - - ansible_os_family == "Windows" - when: splunk_status.rc != 0 + - name: "Start Splunk via CLI" + command: "{{ splunk.exec }} start --accept-license --answer-yes --no-prompt" + register: start_splunk + changed_when: start_splunk.rc == 0 and 'already running' not in start_splunk.stdout + when: not splunk.enable_service + become: yes + become_user: "{{ splunk.user }}" + + - name: "Start Splunk via service" + service: + name: "{{ splunk_service_name }}" + state: started + become: yes + become_user: "{{ privileged_user }}" + when: + - splunk.enable_service + - ansible_system is match("Linux") + + - name: "Start Splunk via Windows service" + win_service: + name: splunkd + state: started + when: + - splunk.enable_service + - ansible_os_family == "Windows" - name: "Wait for splunkd management port" wait_for: port: "{{ splunk.svc_port }}" + +- name: Flush restart handlers + meta: flush_handlers diff --git a/roles/splunk_common/tasks/trigger_restart.yml b/roles/splunk_common/tasks/trigger_restart.yml new file mode 100644 index 00000000..a53af9b0 --- /dev/null +++ b/roles/splunk_common/tasks/trigger_restart.yml @@ -0,0 +1,9 @@ +--- +# Trigger restart only when Splunk is currently running; add add'l when clauses during include_tasks invocation as needed +- include_tasks: get_splunk_status.yml + +- name: Trigger restart + command: ls + changed_when: splunk_status.rc == 0 + notify: + - Restart the splunkd service diff --git a/roles/splunk_common/vars/main.yml b/roles/splunk_common/vars/main.yml index 6d49ef6c..94786882 100644 --- a/roles/splunk_common/vars/main.yml +++ b/roles/splunk_common/vars/main.yml @@ -4,7 +4,7 @@ default_apps: [ "legacy", "splunk_gdi", "SplunkForwarder", "SplunkLightForwarder "appsbrowser", "framework", "learned", "launcher", "alert_logevent", "sample_app", "splunk_instrumentation", "search", "splunk_archiver", "splunk_monitoring_console", "_splunk_config", "splunk_enterprise_on_docker", "splunk_forwarder_on_docker", - "splunk_metrics_workspace", "splunk_internal_metrics", "splunk_telemetry" ] + "splunk_metrics_workspace", "splunk_internal_metrics", "splunk_telemetry", "splunk_secure_gateway" ] itsi_apps: [ "DA-ITSI-APPSERVER", "DA-ITSI-DATABASE", "DA-ITSI-EUEM", "DA-ITSI-LB", "DA-ITSI-OS", "DA-ITSI-STORAGE", "DA-ITSI-VIRTUALIZATION", "DA-ITSI-WEBSERVER", "SA-ITOA", "SA-ITSI-ATAD", "SA-UserAccess", "SA-ITSI-CustomModuleViz", "SA-ITSI-MetricAD", "SA-ITSI-Licensechecker", "itsi", "splunk_app_infrastructure" ] diff --git a/roles/splunk_deployer/tasks/push_apps_to_search_heads.yml b/roles/splunk_deployer/tasks/push_apps_to_search_heads.yml index aeab05e2..227f992c 100644 --- a/roles/splunk_deployer/tasks/push_apps_to_search_heads.yml +++ b/roles/splunk_deployer/tasks/push_apps_to_search_heads.yml @@ -7,7 +7,7 @@ dest: "{{ splunk.app_paths.shc }}" - name: Apply shcluster bundle - command: "{{ splunk.exec }} apply shcluster-bundle -target {{ cert_prefix }}://{{ splunk.search_head_captain_url }}:{{ splunk.svc_port }} -auth {{ splunk.admin_user }}:{{ splunk.password }} --answer-yes" + command: "{{ splunk.exec }} apply shcluster-bundle -target {{ cert_prefix }}://{{ splunk.search_head_captain_url }}:{{ splunk.svc_port }} -auth {{ splunk.admin_user }}:{{ splunk.password }} --answer-yes -push-default-apps true" become: yes become_user: "{{ splunk.user }}" no_log: "{{ hide_password }}" diff --git a/roles/splunk_monitor/tasks/adding_peers.yml b/roles/splunk_monitor/tasks/adding_peers.yml index f154feca..cc429c0c 100644 --- a/roles/splunk_monitor/tasks/adding_peers.yml +++ b/roles/splunk_monitor/tasks/adding_peers.yml @@ -13,7 +13,7 @@ become: yes become_user: "{{ splunk.user }}" register: set_as_peer - until: set_as_peer.rc == 0 + until: set_as_peer.rc == 0 or 'already exists' in set_as_peer.stderr retries: "{{ retry_num }}" delay: "{{ retry_delay }}" changed_when: set_as_peer.rc == 0 diff --git a/roles/splunk_monitor/tasks/main.yml b/roles/splunk_monitor/tasks/main.yml index 08c3bff1..c4aa21db 100644 --- a/roles/splunk_monitor/tasks/main.yml +++ b/roles/splunk_monitor/tasks/main.yml @@ -42,6 +42,24 @@ license_master_string: "{{ distributed_info['json']['entry'] | selectattr('content.server_roles','defined') | selectattr('content.server_roles', 'search', 'license_master') | map(attribute='name') | list | join('&member=') }}" configured_peers: "{% if splunk.role == 'splunk_search_head' and splunk.role == 'splunk_cluster_master' %}distributed_info['json']['entry'] | map(attribute='name') | list | join(','){% else %}{% endif %}" +- name: Define Cluster Label + set_fact: + cluster_label_dict: "{{ cluster_label_dict|default({}) | combine( {item.name: item.content.cluster_label} ) }}" + with_items: + - "{{ distributed_info['json']['entry'] }}" + +- name: Create cluster_label key value pairing + set_fact: + cluster_label_list_of_dicts: | + {% set res = [] -%} + {% for key in cluster_label_dict.keys() -%} + {% for value in cluster_label_dict[key] -%} + {% set ignored = res.extend([{'name': key, 'cluster_label':value}]) -%} + {%- endfor %} + {%- endfor %} + {{ res }} + when: cluster_label_dict is defined + - name: Add DMC server roles to search strings set_fact: index_string: "{% if 'indexer' in server_info['json']['entry'][0]['content']['server_roles'] and index_string | length > 0 %}localhost:localhost&member={{ index_string }}{% elif 'indexer' in server_info['json']['entry'][0]['content']['server_roles'] and index_string | length == 0 %}localhost:localhost{% else %}{{ index_string }}{% endif %}" diff --git a/roles/splunk_monitor/tasks/post_calls.yml b/roles/splunk_monitor/tasks/post_calls.yml index 92c40fd3..aba7c60c 100644 --- a/roles/splunk_monitor/tasks/post_calls.yml +++ b/roles/splunk_monitor/tasks/post_calls.yml @@ -25,4 +25,16 @@ - "{{ dmc_group_kv_store }}" - "{{ dmc_group_license_master }}" - "{{ dmc_group_search_head }}" - - "{{ dmc_group_shc_deployer }}" \ No newline at end of file + - "{{ dmc_group_shc_deployer }}" + +- name: Cluster Label POST Requests + uri: + url: "{{ cert_prefix }}://127.0.0.1:{{ splunk.svc_port }}/services/search/distributed/groups" + method: POST + user: "{{ splunk.admin_user }}" + password: "{{ splunk.password }}" + body: "member={{ item.name }}&default=false&name=dmc_indexerclustergroup_{{ item.cluster_label }}" + validate_certs: false + status_code: 201,409 + loop: "{{ cluster_label_list_of_dicts }}" + when: cluster_label_list_of_dicts is defined and item.cluster_label | length > 0 \ No newline at end of file diff --git a/roles/splunk_search_head/tasks/setup_multisite.yml b/roles/splunk_search_head/tasks/setup_multisite.yml index 6a588ad3..bcf2e52f 100644 --- a/roles/splunk_search_head/tasks/setup_multisite.yml +++ b/roles/splunk_search_head/tasks/setup_multisite.yml @@ -12,7 +12,8 @@ become: yes become_user: "{{ splunk.user }}" register: set_new_master - until: set_new_master.rc == 0 + until: set_new_master.rc == 0 or (set_new_master.rc != 0 and "Cannot edit this searchhead. Use 'splunk edit cluster-master' to edit information for this searchhead." in set_new_master.stderr) + failed_when: set_new_master.rc != 0 and "Cannot edit this searchhead. Use 'splunk edit cluster-master' to edit information for this searchhead." not in set_new_master.stderr changed_when: set_new_master.rc == 0 retries: "{{ retry_num }}" delay: "{{ retry_delay }}" diff --git a/roles/splunk_standalone/molecule/apps/group_vars/all.yml b/roles/splunk_standalone/molecule/apps/group_vars/all.yml index 058fbbf6..6a7e84b8 100644 --- a/roles/splunk_standalone/molecule/apps/group_vars/all.yml +++ b/roles/splunk_standalone/molecule/apps/group_vars/all.yml @@ -8,3 +8,4 @@ splunk: hec: token: abcd1234 password: helloworld + disable_popups: true diff --git a/roles/splunk_standalone/molecule/apps/tests/test_apps.py b/roles/splunk_standalone/molecule/apps/tests/test_apps.py index 15bbe1e3..75332d09 100644 --- a/roles/splunk_standalone/molecule/apps/tests/test_apps.py +++ b/roles/splunk_standalone/molecule/apps/tests/test_apps.py @@ -127,3 +127,16 @@ def test_splunk_app_httpexample(host): output = json.loads(output.stdout) assert output["entry"][0]["content"]["eai:appName"] == "splunk_app_httpexample" assert output["entry"][0]["content"]["version"] == "0.0.1" + +def test_disabled_popups_homescreen(host): + output = host.run("curl -k https://localhost:8089/servicesNS/admin/user-prefs/data/user-prefs/general \ + -u admin:helloworld -d output_mode=json") + output = json.loads(output.stdout) + assert int(output["entry"][0]["content"]["hideInstrumentationOptInModal"]) == 1 + assert output["entry"][0]["content"]["notification_python_3_impact"] == 'false' + +def test_disabled_popups_search(host): + output = host.run("curl -k https://localhost:8089/servicesNS/admin/search/data/ui/ui-tour/search-tour \ + -u admin:helloworld -d output_mode=json") + output = json.loads(output.stdout) + assert int(output["entry"][0]["content"]["viewed"]) == 1 \ No newline at end of file diff --git a/tests/fixtures/molecule-splunk-hosts.yml b/tests/fixtures/molecule-splunk-hosts.yml index c44fc931..c0e6cc60 100644 --- a/tests/fixtures/molecule-splunk-hosts.yml +++ b/tests/fixtures/molecule-splunk-hosts.yml @@ -41,6 +41,7 @@ all: port: 9000 spark_master_host: 127.0.0.1 spark_master_webui_port: 8080 + disable_popups: false enable_service: false exec: /opt/splunk/bin/splunk group: splunk diff --git a/tests/fixtures/molecule-uf-hosts.yml b/tests/fixtures/molecule-uf-hosts.yml index 440cc129..fa53a8ac 100644 --- a/tests/fixtures/molecule-uf-hosts.yml +++ b/tests/fixtures/molecule-uf-hosts.yml @@ -41,6 +41,7 @@ all: port: 9000 spark_master_host: 127.0.0.1 spark_master_webui_port: 8080 + disable_popups: false enable_service: false exec: /opt/splunkforwarder/bin/splunk group: splunk diff --git a/tests/small/test_environ.py b/tests/small/test_environ.py index 1b79a20c..34e0e0ed 100644 --- a/tests/small/test_environ.py +++ b/tests/small/test_environ.py @@ -174,15 +174,22 @@ def test_getSplunkWebSSL(): @pytest.mark.parametrize(("default_yml", "os_env", "output"), [ # Check null parameters - Splunk password is required - ({"password": "helloworld"}, {}, {"password": "helloworld", "pass4SymmKey": None, "secret": None}), + ({"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", "pass4SymmKey": "you-will-never-guess", "secret": None}), - ({"password": "helloworld", "pass4SymmKey": "you-will-never-guess", "secret": "1234"}, {}, {"password": "helloworld", "pass4SymmKey": "you-will-never-guess", "secret": "1234"}), - ({"password": "helloworld", "secret": "1234"}, {}, {"password": "helloworld", "pass4SymmKey": None, "secret": "1234"}), + ({"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", "pass4SymmKey": "you-will-never-guess", "secret": None}), - ({"password": None}, {"SPLUNK_PASSWORD": "helloworld", "SPLUNK_PASS4SYMMKEY": "you-will-never-guess", "SPLUNK_SECRET": "1234"}, {"password": "helloworld", "pass4SymmKey": "you-will-never-guess", "secret": "1234"}), - ({"password": None}, {"SPLUNK_PASSWORD": "helloworld", "SPLUNK_SECRET": "1234"}, {"password": "helloworld", "pass4SymmKey": None, "secret": "1234"}) + ({"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): @@ -363,6 +370,35 @@ def test_getHEC(default_yml, os_env, result): 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 diff --git a/win-ansible.cfg b/win-ansible.cfg index bc5ef14f..3debb095 100644 --- a/win-ansible.cfg +++ b/win-ansible.cfg @@ -20,6 +20,10 @@ timeout = 30 action_warnings = False allow_world_readable_tmpfiles = True remote_tmp = /tmp/.ansible/tmp +localhost_warning = False + +[inventory] +unparsed_is_failed = True [privilege_escalation] become = true