summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Saraceni <andrew.saraceni@gmail.com>2017-08-15 07:13:14 +0200
committerBrian Coca <bcoca@users.noreply.github.com>2017-08-15 07:13:14 +0200
commitbb7813f16f19023903f721d5921c31c109ba3e68 (patch)
tree8e143d44904e4c6747ea3be67ba613cbe53a3edd
parentACI Subnet: New Module (#28202) (diff)
downloadansible-bb7813f16f19023903f721d5921c31c109ba3e68.tar.xz
ansible-bb7813f16f19023903f721d5921c31c109ba3e68.zip
New Module: Write Windows event log entries (win_eventlog_entry) (#27828)
* initial commit for win_eventlog_entry module * added test module for integration tests and minor documentation fixes
-rw-r--r--lib/ansible/modules/windows/win_eventlog_entry.ps1106
-rw-r--r--lib/ansible/modules/windows/win_eventlog_entry.py78
-rw-r--r--test/integration/targets/win_eventlog_entry/aliases1
-rw-r--r--test/integration/targets/win_eventlog_entry/defaults/main.yml6
-rw-r--r--test/integration/targets/win_eventlog_entry/library/test_win_eventlog_entry.ps133
-rw-r--r--test/integration/targets/win_eventlog_entry/tasks/main.yml33
-rw-r--r--test/integration/targets/win_eventlog_entry/tasks/tests.yml159
7 files changed, 416 insertions, 0 deletions
diff --git a/lib/ansible/modules/windows/win_eventlog_entry.ps1 b/lib/ansible/modules/windows/win_eventlog_entry.ps1
new file mode 100644
index 0000000000..e40bdea0a4
--- /dev/null
+++ b/lib/ansible/modules/windows/win_eventlog_entry.ps1
@@ -0,0 +1,106 @@
+#!powershell
+
+# (c) 2017, Andrew Saraceni <andrew.saraceni@gmail.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#Requires -Module Ansible.ModuleUtils.Legacy.psm1
+
+$ErrorActionPreference = "Stop"
+
+function Test-LogExistence {
+ <#
+ .SYNOPSIS
+ Get information on a log's existence.
+ #>
+ param(
+ [String]$LogName
+ )
+
+ $log_exists = $false
+ $log = Get-EventLog -List | Where-Object {$_.Log -eq $LogName}
+ if ($log) {
+ $log_exists = $true
+ }
+ return $log_exists
+}
+
+function Test-SourceExistence {
+ <#
+ .SYNOPSIS
+ Get information on a source's existence.
+ #>
+ param(
+ [String]$LogName,
+ [String]$SourceName
+ )
+
+ $source_exists = [System.Diagnostics.EventLog]::SourceExists($SourceName)
+
+ if ($source_exists) {
+ $source_log = [System.Diagnostics.EventLog]::LogNameFromSourceName($SourceName, ".")
+ if ($source_log -ne $LogName) {
+ Fail-Json -obj $result -message "Source $SourceName does not belong to log $LogName and cannot be written to"
+ }
+ }
+
+ return $source_exists
+}
+
+$params = Parse-Args $args -supports_check_mode $true
+$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
+
+$log = Get-AnsibleParam -obj $params -name "log" -type "str" -failifempty $true
+$source = Get-AnsibleParam -obj $params -name "source" -type "str" -failifempty $true
+$event_id = Get-AnsibleParam -obj $params -name "event_id" -type "int" -failifempty $true
+$message = Get-AnsibleParam -obj $params -name "message" -type "str" -failifempty $true
+$entry_type = Get-AnsibleParam -obj $params -name "entry_type" -type "str" -validateset "Error","FailureAudit","Information","SuccessAudit","Warning"
+$category = Get-AnsibleParam -obj $params -name "category" -type "int"
+$raw_data = Get-AnsibleParam -obj $params -name "raw_data" -type "str"
+
+$result = @{
+ changed = $false
+}
+
+$log_exists = Test-LogExistence -LogName $log
+if (!$log_exists) {
+ Fail-Json -obj $result -message "Log $log does not exist and cannot be written to"
+}
+
+$source_exists = Test-SourceExistence -LogName $log -SourceName $source
+if (!$source_exists) {
+ Fail-Json -obj $result -message "Source $source does not exist"
+}
+
+if ($event_id -lt 0 -or $event_id -gt 65535) {
+ Fail-Json -obj $result -message "Event ID must be between 0 and 65535"
+}
+
+$write_params = @{
+ LogName = $log
+ Source = $source
+ EventId = $event_id
+ Message = $message
+}
+
+try {
+ if ($entry_type) {
+ $write_params.EntryType = $entry_type
+ }
+ if ($category) {
+ $write_params.Category = $category
+ }
+ if ($raw_data) {
+ $write_params.RawData = [Byte[]]($raw_data -split ",")
+ }
+
+ if (!$check_mode) {
+ Write-EventLog @write_params
+ }
+ $result.changed = $true
+ $result.msg = "Entry added to log $log from source $source"
+}
+catch {
+ Fail-Json -obj $result -message $_.Exception.Message
+}
+
+Exit-Json -obj $result
diff --git a/lib/ansible/modules/windows/win_eventlog_entry.py b/lib/ansible/modules/windows/win_eventlog_entry.py
new file mode 100644
index 0000000000..ffed384d4a
--- /dev/null
+++ b/lib/ansible/modules/windows/win_eventlog_entry.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+
+# (c) 2017, Andrew Saraceni <andrew.saraceni@gmail.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+ANSIBLE_METADATA = {'metadata_version': '1.0',
+ 'status': ['preview'],
+ 'supported_by': 'community'}
+
+DOCUMENTATION = r'''
+---
+module: win_eventlog_entry
+version_added: "2.4"
+short_description: Write entries to Windows event logs
+description:
+ - Write log entries to a given event log from a specified source.
+options:
+ log:
+ description:
+ - Name of the event log to write an entry to.
+ required: true
+ source:
+ description:
+ - Name of the log source to indicate where the entry is from.
+ required: true
+ event_id:
+ description:
+ - The numeric event identifier for the entry.
+ - Value must be between 0 and 65535.
+ required: true
+ message:
+ description:
+ - The message for the given log entry.
+ required: true
+ entry_type:
+ description:
+ - Indicates the entry being written to the log is of a specific type.
+ choices:
+ - Error
+ - FailureAudit
+ - Information
+ - SuccessAudit
+ - Warning
+ category:
+ description:
+ - A numeric task category associated with the category message file for the log source.
+ raw_data:
+ description:
+ - Binary data associated with the log entry.
+ - Value must be a comma-separated array of 8-bit unsigned integers (0 to 255).
+notes:
+ - This module will always report a change when writing an event entry.
+author:
+ - Andrew Saraceni (@andrewsaraceni)
+'''
+
+EXAMPLES = r'''
+- name: Write an entry to a Windows event log
+ win_eventlog_entry:
+ log: MyNewLog
+ source: NewLogSource1
+ event_id: 1234
+ message: This is a test log entry.
+
+- name: Write another entry to a different Windows event log
+ win_eventlog_entry:
+ log: AnotherLog
+ source: MyAppSource
+ event_id: 5000
+ message: An error has occurred.
+ entry_type: Error
+ category: 5
+ raw_data: 10,20
+'''
+
+RETURN = r'''
+# Default return values
+'''
diff --git a/test/integration/targets/win_eventlog_entry/aliases b/test/integration/targets/win_eventlog_entry/aliases
new file mode 100644
index 0000000000..c6d6198167
--- /dev/null
+++ b/test/integration/targets/win_eventlog_entry/aliases
@@ -0,0 +1 @@
+windows/ci/group3
diff --git a/test/integration/targets/win_eventlog_entry/defaults/main.yml b/test/integration/targets/win_eventlog_entry/defaults/main.yml
new file mode 100644
index 0000000000..611d16ec0e
--- /dev/null
+++ b/test/integration/targets/win_eventlog_entry/defaults/main.yml
@@ -0,0 +1,6 @@
+win_test_log_source:
+ log: WinEventLogEntryTest
+ source: WinEventLogEntrySource
+win_test_log_source_extra:
+ log: ExtraWinEventLogEntryTest
+ source: ExtraWinEventLogEntrySource
diff --git a/test/integration/targets/win_eventlog_entry/library/test_win_eventlog_entry.ps1 b/test/integration/targets/win_eventlog_entry/library/test_win_eventlog_entry.ps1
new file mode 100644
index 0000000000..6c26cd3f59
--- /dev/null
+++ b/test/integration/targets/win_eventlog_entry/library/test_win_eventlog_entry.ps1
@@ -0,0 +1,33 @@
+#!powershell
+
+# (c) 2017, Andrew Saraceni <andrew.saraceni@gmail.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#Requires -Module Ansible.ModuleUtils.Legacy.psm1
+
+# Test module used to grab the latest entry from an event log and output its properties
+
+$ErrorActionPreference = "Stop"
+
+$params = Parse-Args $args -supports_check_mode $true
+$log = Get-AnsibleParam -obj $params -name "log" -type "str" -failifempty $true
+
+$result = @{
+ changed = $false
+}
+
+try {
+ $log_entry = Get-EventLog -LogName $log | Select-Object -First 1 -Property *
+}
+catch {
+ Fail-Json -obj $result -message "Could not find any entries for log $log"
+}
+
+$result.source = $log_entry.Source
+$result.event_id = $log_entry.EventID
+$result.message = $log_entry.Message
+$result.entry_type = $log_entry.EntryType.ToString()
+$result.category = $log_entry.CategoryNumber
+$result.raw_data = $log_entry.Data -join ","
+
+Exit-Json -obj $result
diff --git a/test/integration/targets/win_eventlog_entry/tasks/main.yml b/test/integration/targets/win_eventlog_entry/tasks/main.yml
new file mode 100644
index 0000000000..9a1790a592
--- /dev/null
+++ b/test/integration/targets/win_eventlog_entry/tasks/main.yml
@@ -0,0 +1,33 @@
+# win_shell invocations can eventually be replaced with win_eventlog
+- name: Remove potentially leftover test logs and sources
+ win_shell: Remove-EventLog -LogName "{{ item.log }}" -ErrorAction SilentlyContinue
+ with_items:
+ - "{{ win_test_log_source }}"
+ - "{{ win_test_log_source_extra }}"
+ failed_when: no
+
+- name: Add new test logs and sources
+ win_shell: New-EventLog -LogName "{{ item.log }}" -Source "{{ item.source }}"
+ with_items:
+ - "{{ win_test_log_source }}"
+ - "{{ win_test_log_source_extra }}"
+
+- name: Run tests for win_eventlog_entry
+ block:
+
+ - name: Test in normal mode
+ include_tasks: tests.yml
+ vars:
+ in_check_mode: no
+
+ - name: Test in check-mode
+ include_tasks: tests.yml
+ vars:
+ in_check_mode: yes
+ check_mode: yes
+
+- name: Remove test logs and sources
+ win_shell: Remove-EventLog -LogName "{{ item.log }}"
+ with_items:
+ - "{{ win_test_log_source }}"
+ - "{{ win_test_log_source_extra }}"
diff --git a/test/integration/targets/win_eventlog_entry/tasks/tests.yml b/test/integration/targets/win_eventlog_entry/tasks/tests.yml
new file mode 100644
index 0000000000..17b78eb0ef
--- /dev/null
+++ b/test/integration/targets/win_eventlog_entry/tasks/tests.yml
@@ -0,0 +1,159 @@
+# Test code for win_eventlog_entry
+
+# (c) 2017, Andrew Saraceni <andrew.saraceni@gmail.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+- name: Add entry to fake log
+ win_eventlog_entry:
+ log: FakeLogName
+ source: "{{ win_test_log_source.source }}"
+ event_id: 12345
+ message: This is a test log entry message
+ register: add_entry_to_fake_log
+ failed_when: add_entry_to_fake_log.changed != false or add_entry_to_fake_log.msg != "Log FakeLogName does not exist and cannot be written to"
+
+
+- name: Add entry from fake source
+ win_eventlog_entry:
+ log: "{{ win_test_log_source.log }}"
+ source: FakeSourceName
+ event_id: 12345
+ message: This is a test log entry message
+ register: add_entry_from_fake_source
+ failed_when: add_entry_from_fake_source.changed != false or add_entry_from_fake_source.msg != "Source FakeSourceName does not exist"
+
+
+- name: Add entry with invalid event_id
+ win_eventlog_entry:
+ log: "{{ win_test_log_source.log }}"
+ source: "{{ win_test_log_source.source }}"
+ event_id: 67000
+ message: This is a test log entry message
+ register: add_entry_with_invalid_event_id
+ failed_when: add_entry_with_invalid_event_id.changed != false or add_entry_with_invalid_event_id.msg != "Event ID must be between 0 and 65535"
+
+
+- name: Add entry from other log source
+ win_eventlog_entry:
+ log: "{{ win_test_log_source.log }}"
+ source: "{{ win_test_log_source_extra.source }}"
+ event_id: 12345
+ message: This is a test log entry message
+ register: add_entry_from_other_log_source
+ failed_when: add_entry_from_other_log_source.changed != false or add_entry_from_other_log_source.msg != "Source {{ win_test_log_source_extra.source }} does not belong to log {{ win_test_log_source.log }} and cannot be written to"
+
+
+- name: Add entry
+ win_eventlog_entry: &wele
+ log: "{{ win_test_log_source.log }}"
+ source: "{{ win_test_log_source.source }}"
+ event_id: 12345
+ message: This is a test log entry message
+ register: add_entry
+
+- name: Test add_entry
+ assert:
+ that:
+ - add_entry.changed == true
+ - add_entry.msg == "Entry added to log {{ win_test_log_source.log }} from source {{ win_test_log_source.source }}"
+
+- name: Test add_entry count (normal mode)
+ win_shell: (Get-EventLog -LogName "{{ win_test_log_source.log }}").Count
+ register: add_entry_count
+ failed_when: add_entry_count.stdout_lines[0] != "1"
+ when: not in_check_mode
+
+- name: Test add_entry result (normal mode)
+ test_win_eventlog_entry:
+ log: "{{ win_test_log_source.log }}"
+ register: add_entry_result
+ when: not in_check_mode
+
+- name: Test add_entry_result (normal mode)
+ assert:
+ that:
+ - add_entry_result.source == win_test_log_source.source
+ - add_entry_result.event_id == 12345
+ - add_entry_result.message == "This is a test log entry message"
+ when: not in_check_mode
+
+
+- name: Add entry (again)
+ win_eventlog_entry: *wele
+ register: add_entry_again
+
+- name: Test add_entry_again (normal mode)
+ assert:
+ that:
+ - add_entry_again.changed == true
+ - add_entry_again.msg == "Entry added to log {{ win_test_log_source.log }} from source {{ win_test_log_source.source }}"
+ when: not in_check_mode
+
+- name: Test add_entry_again count (normal mode)
+ win_shell: (Get-EventLog -LogName "{{ win_test_log_source.log }}").Count
+ register: add_entry_again_count
+ failed_when: add_entry_again_count.stdout_lines[0] != "2"
+ when: not in_check_mode
+
+
+- name: Add entry all options
+ win_eventlog_entry: &wele_ao
+ <<: *wele
+ event_id: 500
+ message: This is a test error message
+ entry_type: Error
+ category: 5
+ raw_data: 10,20
+ register: add_entry_all_options
+
+- name: Test add_entry_all_options
+ assert:
+ that:
+ - add_entry_all_options.changed == true
+ - add_entry_all_options.msg == "Entry added to log {{ win_test_log_source.log }} from source {{ win_test_log_source.source }}"
+
+- name: Test add_entry_all_options count (normal mode)
+ win_shell: (Get-EventLog -LogName "{{ win_test_log_source.log }}").Count
+ register: add_entry_all_options_count
+ failed_when: add_entry_all_options_count.stdout_lines[0] != "3"
+ when: not in_check_mode
+
+- name: Test add_entry_all_options result (normal mode)
+ test_win_eventlog_entry:
+ log: "{{ win_test_log_source.log }}"
+ register: add_entry_all_options_result
+ when: not in_check_mode
+
+- name: Test add_entry_all_options_result (normal mode)
+ assert:
+ that:
+ - add_entry_all_options_result.source == win_test_log_source.source
+ - add_entry_all_options_result.event_id == 500
+ - add_entry_all_options_result.message == "This is a test error message"
+ - add_entry_all_options_result.entry_type == "Error"
+ - add_entry_all_options_result.category == 5
+ - add_entry_all_options_result.raw_data == "10,20"
+ when: not in_check_mode
+
+
+- name: Add entry all options (again)
+ win_eventlog_entry: *wele_ao
+ register: add_entry_all_options_again
+
+- name: Test add_entry_all_options_again (normal mode)
+ assert:
+ that:
+ - add_entry_all_options_again.changed == true
+ - add_entry_all_options_again.msg == "Entry added to log {{ win_test_log_source.log }} from source {{ win_test_log_source.source }}"
+ when: not in_check_mode
+
+- name: Test add_entry_all_options_again count (normal mode)
+ win_shell: (Get-EventLog -LogName "{{ win_test_log_source.log }}").Count
+ register: add_entry_all_options_again_count
+ failed_when: add_entry_all_options_again_count.stdout_lines[0] != "4"
+ when: not in_check_mode
+
+
+- name: Clear event log entries
+ win_shell: Clear-EventLog -LogName "{{ win_test_log_source.log }}"
+ when: not in_check_mode