Skip to content

Commit fe98861

Browse files
rjury-sumoCopilot
andauthored
add local windows event log source (#785)
* add local windows event log source * Update website/docs/r/local_windows_event_source.html.markdown Co-authored-by: Copilot <[email protected]> * Update website/docs/r/local_windows_event_source.html.markdown Co-authored-by: Copilot <[email protected]> * Update website/docs/r/local_windows_event_source.html.markdown Co-authored-by: Copilot <[email protected]> * Update sumologic/resource_sumologic_local_windows_event_log_source.go Co-authored-by: Copilot <[email protected]> * Refine documentation for local Windows event log source, clarifying collector installation and updating argument references. --------- Co-authored-by: Copilot <[email protected]>
1 parent f150b63 commit fe98861

File tree

5 files changed

+326
-0
lines changed

5 files changed

+326
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
## X.Y.Z (Unreleased)
22
* Add new change notes here
3+
34
BUG FIXES:
45
* Corrected selection_type configuration in RolesV2 resources.
56

67
FEATURES:
78
* The **sumologic_role_v2** resource has been promoted from Beta to General Availability (GA).
9+
* **New Resource:** sumologic_local_windows_event_log_source (GH-785)
810

911
MAINTENANCE:
1012
* Removed obsolete comments about auto-generated code. All code in this repo is eligible for by-hand modification.

sumologic/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ func Provider() *schema.Provider {
123123
"sumologic_source_template": resourceSumologicSourceTemplate(),
124124
"sumologic_azure_metrics_source": resourceSumologicGenericPollingSource(),
125125
"sumologic_scan_budget": resourceSumologicScanBudget(),
126+
"sumologic_local_windows_event_log_source": resourceSumologicLocalWindowsEventLogSource(),
126127
},
127128
DataSourcesMap: map[string]*schema.Resource{
128129
"sumologic_cse_log_mapping_vendor_product": dataSourceCSELogMappingVendorAndProduct(),
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
package sumologic
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"strconv"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
10+
)
11+
12+
func resourceSumologicLocalWindowsEventLogSource() *schema.Resource {
13+
LocalWindowsEventLogSource := resourceSumologicSource()
14+
LocalWindowsEventLogSource.Create = resourceSumologicLocalWindowsEventLogSourceCreate
15+
LocalWindowsEventLogSource.Read = resourceSumologicLocalWindowsEventLogSourceRead
16+
LocalWindowsEventLogSource.Update = resourceSumologicLocalWindowsEventLogSourceUpdate
17+
LocalWindowsEventLogSource.Importer = &schema.ResourceImporter{
18+
State: resourceSumologicSourceImport,
19+
}
20+
21+
// Windows Event Log specific fields
22+
LocalWindowsEventLogSource.Schema["log_names"] = &schema.Schema{
23+
Type: schema.TypeList,
24+
Required: true,
25+
Elem: &schema.Schema{Type: schema.TypeString},
26+
Description: "List of Windows log types to collect (e.g., Security, Application, System)",
27+
}
28+
29+
LocalWindowsEventLogSource.Schema["render_messages"] = &schema.Schema{
30+
Type: schema.TypeBool,
31+
Optional: true,
32+
Default: true,
33+
Description: "When using legacy format, indicates if full event messages are collected",
34+
}
35+
36+
LocalWindowsEventLogSource.Schema["event_format"] = &schema.Schema{
37+
Type: schema.TypeInt,
38+
Optional: true,
39+
Default: 0,
40+
ValidateFunc: validation.IntInSlice([]int{0, 1}),
41+
Description: "0 for legacy format (XML), 1 for JSON format",
42+
}
43+
44+
LocalWindowsEventLogSource.Schema["event_message"] = &schema.Schema{
45+
Type: schema.TypeInt,
46+
Optional: true,
47+
ValidateFunc: validation.IntInSlice([]int{0, 1, 2}),
48+
Description: "0 for complete message, 1 for message title, 2 for metadata only. Required if event_format is 0",
49+
}
50+
51+
LocalWindowsEventLogSource.Schema["deny_list"] = &schema.Schema{
52+
Type: schema.TypeString,
53+
Optional: true,
54+
Description: "Comma-separated list of event IDs to deny",
55+
}
56+
57+
LocalWindowsEventLogSource.Schema["allow_list"] = &schema.Schema{
58+
Type: schema.TypeString,
59+
Optional: true,
60+
Description: "Comma-separated list of event IDs to allow",
61+
}
62+
63+
return LocalWindowsEventLogSource
64+
}
65+
66+
func resourceSumologicLocalWindowsEventLogSourceCreate(d *schema.ResourceData, meta interface{}) error {
67+
c := meta.(*Client)
68+
69+
if d.Id() == "" {
70+
source := resourceToLocalWindowsEventLogSource(d)
71+
collectorID := d.Get("collector_id").(int)
72+
73+
id, err := c.CreateLocalWindowsEventLogSource(source, collectorID)
74+
if err != nil {
75+
return err
76+
}
77+
78+
d.SetId(strconv.Itoa(id))
79+
}
80+
81+
return resourceSumologicLocalWindowsEventLogSourceRead(d, meta)
82+
}
83+
84+
func resourceSumologicLocalWindowsEventLogSourceUpdate(d *schema.ResourceData, meta interface{}) error {
85+
c := meta.(*Client)
86+
87+
source := resourceToLocalWindowsEventLogSource(d)
88+
89+
err := c.UpdateLocalWindowsEventLogSource(source, d.Get("collector_id").(int))
90+
91+
if err != nil {
92+
return err
93+
}
94+
95+
return resourceSumologicLocalWindowsEventLogSourceRead(d, meta)
96+
}
97+
98+
func resourceToLocalWindowsEventLogSource(d *schema.ResourceData) LocalWindowsEventLogSource {
99+
100+
source := resourceToSource(d)
101+
source.Type = "LocalWindowsEventLog"
102+
103+
LocalWindowsEventLogSource := LocalWindowsEventLogSource{
104+
Source: source,
105+
LogNames: d.Get("log_names").([]interface{}),
106+
RenderMessages: d.Get("render_messages").(bool),
107+
EventFormat: d.Get("event_format").(int),
108+
}
109+
110+
// Handle optional deny_list
111+
if DenyList, ok := d.GetOk("deny_list"); ok {
112+
LocalWindowsEventLogSource.DenyList = DenyList.(string)
113+
}
114+
115+
// Handle optional allow_list
116+
if AllowList, ok := d.GetOk("allow_list"); ok {
117+
LocalWindowsEventLogSource.AllowList = AllowList.(string)
118+
}
119+
120+
// Handle optional event_message field
121+
if eventMessage, ok := d.GetOk("event_message"); ok {
122+
eventMessageInt := eventMessage.(int)
123+
LocalWindowsEventLogSource.EventMessage = &eventMessageInt
124+
}
125+
126+
return LocalWindowsEventLogSource
127+
128+
}
129+
130+
func resourceSumologicLocalWindowsEventLogSourceRead(d *schema.ResourceData, meta interface{}) error {
131+
c := meta.(*Client)
132+
133+
id, _ := strconv.Atoi(d.Id())
134+
source, err := c.GetLocalWindowsEventLogSource(d.Get("collector_id").(int), id)
135+
136+
if err != nil {
137+
return err
138+
}
139+
140+
if source == nil {
141+
log.Printf("[WARN] Local Windows Event Log source not found, removing from state: %v - %v", id, err)
142+
d.SetId("")
143+
return nil
144+
}
145+
146+
if err := resourceSumologicSourceRead(d, source.Source); err != nil {
147+
return fmt.Errorf("%s", err)
148+
}
149+
d.Set("log_names", source.LogNames)
150+
d.Set("render_messages", source.RenderMessages)
151+
d.Set("event_format", source.EventFormat)
152+
d.Set("deny_list", source.DenyList)
153+
d.Set("allow_list", source.AllowList)
154+
d.Set("event_message", source.EventMessage)
155+
156+
return nil
157+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package sumologic
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
)
7+
8+
type LocalWindowsEventLogSource struct {
9+
Source
10+
LogNames []interface{} `json:"logNames"`
11+
RenderMessages bool `json:"renderMessages"`
12+
EventFormat int `json:"eventFormat"`
13+
EventMessage *int `json:"eventMessage,omitempty"`
14+
DenyList string `json:"denylist,omitempty"`
15+
AllowList string `json:"allowlist,omitempty"`
16+
}
17+
18+
func (s *Client) CreateLocalWindowsEventLogSource(source LocalWindowsEventLogSource, collectorID int) (int, error) {
19+
20+
type LocalWindowsEventLogSourceMessage struct {
21+
Source LocalWindowsEventLogSource `json:"source"`
22+
}
23+
24+
request := LocalWindowsEventLogSourceMessage{
25+
Source: source,
26+
}
27+
28+
urlPath := fmt.Sprintf("v1/collectors/%d/sources", collectorID)
29+
body, err := s.Post(urlPath, request)
30+
31+
if err != nil {
32+
return -1, err
33+
}
34+
35+
var response LocalWindowsEventLogSourceMessage
36+
37+
err = json.Unmarshal(body, &response)
38+
if err != nil {
39+
return -1, err
40+
}
41+
42+
return response.Source.ID, nil
43+
}
44+
45+
func (s *Client) GetLocalWindowsEventLogSource(collectorID, sourceID int) (*LocalWindowsEventLogSource, error) {
46+
body, err := s.Get(fmt.Sprintf("v1/collectors/%d/sources/%d", collectorID, sourceID))
47+
if err != nil {
48+
return nil, err
49+
}
50+
51+
if body == nil {
52+
return nil, nil
53+
}
54+
55+
type LocalWindowsEventLogSourceResponse struct {
56+
Source LocalWindowsEventLogSource `json:"source"`
57+
}
58+
59+
var response LocalWindowsEventLogSourceResponse
60+
err = json.Unmarshal(body, &response)
61+
if err != nil {
62+
return nil, err
63+
}
64+
65+
return &response.Source, nil
66+
67+
}
68+
69+
func (s *Client) UpdateLocalWindowsEventLogSource(source LocalWindowsEventLogSource, collectorID int) error {
70+
71+
type LocalWindowsEventLogMessage struct {
72+
Source LocalWindowsEventLogSource `json:"source"`
73+
}
74+
75+
request := LocalWindowsEventLogMessage{
76+
Source: source,
77+
}
78+
79+
urlPath := fmt.Sprintf("v1/collectors/%d/sources/%d", collectorID, source.ID)
80+
_, err := s.Put(urlPath, request)
81+
82+
return err
83+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
layout: "sumologic"
3+
page_title: "SumoLogic: sumologic_local_windows_event_log_source"
4+
description: |-
5+
Provides a Sumologic Local Windows Event Log Source.
6+
---
7+
8+
# sumologic_local_windows_event_source
9+
Provides a [Sumologic Local Windows Event Log Source][1].
10+
11+
Note: installed collector sources are a special case for terraform based management. It is not possible to install a local collector via the API, only to add sources to it. The installed collector must be done installed locally on the instance and be set to cloud managed mode to allow for API based configuration.
12+
13+
## Example Usage
14+
15+
Example: 1 This will configure JSON format with "concise" setting and pick up System and Application logs with /os/windows/events as the source category.
16+
17+
```hcl
18+
data "sumologic_collector" "installed_collector" {
19+
name = "terraform_source_testing"
20+
}
21+
22+
resource "sumologic_local_windows_event_log_source" "local" {
23+
name = "windows_logs"
24+
description = "windows system and application logs in json format"
25+
category = "/os/windows/events"
26+
collector_id = "${data.sumologic_collector.installed_collector.id}"
27+
log_names = ["System","Application"]
28+
event_format = 1
29+
}
30+
```
31+
32+
Example 2: Using custom logs and a deny list
33+
34+
```hcl
35+
resource "sumologic_local_windows_event_log_source" "local" {
36+
name = "windows_logs"
37+
description = "windows logs in json format"
38+
category = "/os/windows/events"
39+
collector_id = "${data.sumologic_collector.installed_collector.id}"
40+
log_names = ["System","Application","Microsoft-Windows-PowerShell/Operational", "Microsoft-Windows-TaskScheduler/Operational"]
41+
deny_list = "9999,7890"
42+
event_format = 1
43+
}
44+
```
45+
46+
## Argument Reference
47+
48+
The following arguments are supported:
49+
50+
* `name` - (Required) The name of the local file source. This is required, and has to be unique. Changing this will force recreation the source.
51+
* `description` - (Optional) The description of the source.
52+
* `log_names` - List of Windows log types to collect (e.g., Security, Application, System)
53+
* `render_messages` - When using legacy format, indicates if full event messages are collected
54+
* `event_format` - 0 for legacy format (XML), 1 for JSON format. Default 0.
55+
* `event_message` - 0 for complete message, 1 for message title, 2 for metadata only. Required if event_format is 0
56+
* `deny_list` - Comma-separated list of event IDs to deny
57+
* `category` - (Optional) The default source category for the source.
58+
* `fields` - (Optional) Map containing [key/value pairs][2].
59+
* `allow_list` - (Optional) Comma-separated list of event IDs to allow.
60+
61+
### See also
62+
63+
* [Common Source Properties](https://github.com/terraform-providers/terraform-provider-sumologic/tree/master/website#common-source-properties)
64+
* [Windows Event Source properties](https://help.sumologic.com/docs/send-data/use-json-configure-sources/json-parameters-installed-sources/#local-windows-event-logsource)
65+
66+
## Attributes Reference
67+
The following attributes are exported:
68+
69+
* `id` - The internal ID of the local file source.
70+
71+
## Import
72+
Local Windows Event Log Sources can be imported using the collector and source IDs, e.g.:
73+
74+
```hcl
75+
terraform import sumologic_local_windows_event_source.test 123/456
76+
```
77+
78+
```hcl
79+
terraform import sumologic_local_windows_event_source.test my-test-collector/my-test-source
80+
```
81+
82+
[1]: https://help.sumologic.com/docs/send-data/installed-collectors/sources/local-windows-event-log-source/
83+
[2]: https://help.sumologic.com/Manage/Fields

0 commit comments

Comments
 (0)