Skip to content

feat(audit): [119841102] support query audit events #2857

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/2857.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-data-source
tencentcloud_audit_events
```
2 changes: 1 addition & 1 deletion .github/workflows/fmt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.18
go-version: 1.20

# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3
Expand Down
1 change: 1 addition & 0 deletions tencentcloud/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,7 @@ func Provider() *schema.Provider {
"tencentcloud_audit_cos_regions": audit.DataSourceTencentCloudAuditCosRegions(),
"tencentcloud_audit_key_alias": audit.DataSourceTencentCloudAuditKeyAlias(),
"tencentcloud_audits": audit.DataSourceTencentCloudAudits(),
"tencentcloud_audit_events": audit.DataSourceTencentCloudAuditEvents(),
"tencentcloud_cynosdb_clusters": cynosdb.DataSourceTencentCloudCynosdbClusters(),
"tencentcloud_cynosdb_instances": cynosdb.DataSourceTencentCloudCynosdbInstances(),
"tencentcloud_cynosdb_zone_config": cynosdb.DataSourceTencentCloudCynosdbZoneConfig(),
Expand Down
1 change: 1 addition & 0 deletions tencentcloud/provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ Cloud Audit(Audit)
tencentcloud_audit_cos_regions
tencentcloud_audit_key_alias
tencentcloud_audits
tencentcloud_audit_events

Resource
tencentcloud_audit
Expand Down
338 changes: 338 additions & 0 deletions tencentcloud/services/audit/data_source_tc_audit_events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,338 @@
package audit

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
cloudaudit "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cloudaudit/v20190319"
tccommon "github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/common"
"github.com/tencentcloudstack/terraform-provider-tencentcloud/tencentcloud/internal/helper"
)

func DataSourceTencentCloudAuditEvents() *schema.Resource {
return &schema.Resource{
Read: dataSourceTencentCloudAuditEventsRead,
Schema: map[string]*schema.Schema{
"start_time": {
Type: schema.TypeInt,
Required: true,
Description: "Start timestamp in seconds (cannot be 90 days after the current time).",
},

"end_time": {
Type: schema.TypeInt,
Required: true,
Description: "End timestamp in seconds (the time range for query is less than 30 days).",
},

"max_results": {
Type: schema.TypeInt,
Optional: true,
Description: "Max number of returned logs (up to 50).",
},

"lookup_attributes": {
Type: schema.TypeList,
Optional: true,
Description: "Search condition. Valid values: `RequestId`, `EventName`, `ActionType` (write/read), `PrincipalId` (sub-account), `ResourceType`, `ResourceName`, `AccessKeyId`, `SensitiveAction`, `ApiErrorCode`, `CamErrorCode`, and `Tags` (Format of AttributeValue: [{\"key\":\"*\",\"value\":\"*\"}]).",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"attribute_key": {
Type: schema.TypeString,
Required: true,
Description: "Valid values: RequestId, EventName, ReadOnly, Username, ResourceType, ResourceName, AccessKeyId, and EventId\nNote: `null` may be returned for this field, indicating that no valid values can be obtained.",
},
"attribute_value": {
Type: schema.TypeString,
Optional: true,
Description: "Value of `AttributeValue`\nNote: `null` may be returned for this field, indicating that no valid values can be obtained.",
},
},
},
},

"is_return_location": {
Type: schema.TypeInt,
Optional: true,
Description: "Whether to return the IP location. `1`: yes, `0`: no.",
},

"events": {
Type: schema.TypeList,
Computed: true,
Description: "Logset. Note: `null` may be returned for this field, indicating that no valid values can be obtained.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"event_id": {
Type: schema.TypeString,
Optional: true,
Description: "Log ID.",
},
"username": {
Type: schema.TypeString,
Optional: true,
Description: "Username.",
},
"event_time": {
Type: schema.TypeString,
Optional: true,
Description: "Event Time.",
},
"cloud_audit_event": {
Type: schema.TypeString,
Optional: true,
Description: "Log details.",
},
"resource_type_cn": {
Type: schema.TypeString,
Optional: true,
Description: "Description of resource type in Chinese (please use this field as required; if you are using other languages, ignore this field).",
},
"error_code": {
Type: schema.TypeInt,
Optional: true,
Description: "Authentication error code.",
},
"event_name": {
Type: schema.TypeString,
Optional: true,
Description: "Event name.",
},
"secret_id": {
Type: schema.TypeString,
Optional: true,
Description: "Certificate ID\nNote: `null` may be returned for this field, indicating that no valid values can be obtained.",
},
"event_source": {
Type: schema.TypeString,
Optional: true,
Description: "Request source.",
},
"request_id": {
Type: schema.TypeString,
Optional: true,
Description: "Request ID.",
},
"resource_region": {
Type: schema.TypeString,
Optional: true,
Description: "Resource region.",
},
"account_id": {
Type: schema.TypeInt,
Optional: true,
Description: "Root account ID.",
},
"source_ip_address": {
Type: schema.TypeString,
Optional: true,
Description: "Source IP\nNote: `null` may be returned for this field, indicating that no valid values can be obtained.",
},
"event_name_cn": {
Type: schema.TypeString,
Optional: true,
Description: "Description of event name in Chinese (please use this field as required; if you are using other languages, ignore this field).",
},
"resources": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Resource pair.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"resource_type": {
Type: schema.TypeString,
Optional: true,
Description: "Resource type.",
},
"resource_name": {
Type: schema.TypeString,
Optional: true,
Description: "Resource name\nNote: `null` may be returned for this field, indicating that no valid values can be obtained.",
},
},
},
},
"event_region": {
Type: schema.TypeString,
Optional: true,
Description: "Event region.",
},
"location": {
Type: schema.TypeString,
Optional: true,
Description: "IP location.",
},
},
},
},

"result_output_file": {
Type: schema.TypeString,
Optional: true,
Description: "Used to save results.",
},
},
}
}

func dataSourceTencentCloudAuditEventsRead(d *schema.ResourceData, meta interface{}) error {
defer tccommon.LogElapsed("data_source.tencentcloud_audit_event.read")()
defer tccommon.InconsistentCheck(d, meta)()

logId := tccommon.GetLogId(nil)

Check failure on line 184 in tencentcloud/services/audit/data_source_tc_audit_events.go

View workflow job for this annotation

GitHub Actions / golangci-lint

SA1012: do not pass a nil Context, even if a function permits it; pass context.TODO if you are unsure about which Context to use (staticcheck)
ctx := tccommon.NewResourceLifeCycleHandleFuncContext(context.Background(), logId, d, meta)

service := AuditService{client: meta.(tccommon.ProviderMeta).GetAPIV3Conn()}

paramMap := make(map[string]interface{})

if v, ok := d.GetOkExists("max_results"); ok {
paramMap["MaxResults"] = helper.IntUint64(v.(int))
}

if v, ok := d.GetOkExists("start_time"); ok {
paramMap["StartTime"] = helper.IntUint64(v.(int))
}

if v, ok := d.GetOkExists("end_time"); ok {
paramMap["EndTime"] = helper.IntUint64(v.(int))
}

if v, ok := d.GetOk("lookup_attributes"); ok {
lookupAttributesSet := v.([]interface{})
tmpSet := make([]*cloudaudit.LookupAttribute, 0, len(lookupAttributesSet))
for _, item := range lookupAttributesSet {
lookupAttributesMap := item.(map[string]interface{})
lookupAttribute := cloudaudit.LookupAttribute{}
if v, ok := lookupAttributesMap["attribute_key"]; ok {
lookupAttribute.AttributeKey = helper.String(v.(string))
}
if v, ok := lookupAttributesMap["attribute_value"]; ok {
lookupAttribute.AttributeValue = helper.String(v.(string))
}
tmpSet = append(tmpSet, &lookupAttribute)
}
paramMap["LookupAttributes"] = tmpSet
}

if v, ok := d.GetOkExists("is_return_location"); ok {
paramMap["IsReturnLocation"] = helper.IntUint64(v.(int))
}

var respData []*cloudaudit.Event
err := resource.Retry(tccommon.ReadRetryTimeout, func() *resource.RetryError {
result, e := service.DescribeAuditEventByFilter(ctx, paramMap)
if e != nil {
return tccommon.RetryError(e)
}
respData = result
return nil
})
if err != nil {
return err
}

ids := make([]string, 0, len(respData))
eventsList := make([]map[string]interface{}, 0, len(respData))
if respData != nil {
for _, events := range respData {
eventsMap := map[string]interface{}{}
println(*events.EventId)
if events.EventId != nil {
eventsMap["event_id"] = events.EventId
}

if events.Username != nil {
eventsMap["username"] = events.Username
}

if events.EventTime != nil {
eventsMap["event_time"] = events.EventTime
}

if events.CloudAuditEvent != nil {
eventsMap["cloud_audit_event"] = events.CloudAuditEvent
}

if events.ResourceTypeCn != nil {
eventsMap["resource_type_cn"] = events.ResourceTypeCn
}

if events.ErrorCode != nil {
eventsMap["error_code"] = events.ErrorCode
}

if events.EventName != nil {
eventsMap["event_name"] = events.EventName
}

if events.SecretId != nil {
eventsMap["secret_id"] = events.SecretId
}

if events.EventSource != nil {
eventsMap["event_source"] = events.EventSource
}

if events.RequestID != nil {
eventsMap["request_id"] = events.RequestID
}

if events.ResourceRegion != nil {
eventsMap["resource_region"] = events.ResourceRegion
}

if events.AccountID != nil {
eventsMap["account_id"] = events.AccountID
}

if events.SourceIPAddress != nil {
eventsMap["source_ip_address"] = events.SourceIPAddress
}

if events.EventNameCn != nil {
eventsMap["event_name_cn"] = events.EventNameCn
}

resourcesMap := map[string]interface{}{}

if events.Resources != nil {
if events.Resources.ResourceType != nil {
resourcesMap["resource_type"] = events.Resources.ResourceType
}

if events.Resources.ResourceName != nil {
resourcesMap["resource_name"] = events.Resources.ResourceName
}

eventsMap["resources"] = []interface{}{resourcesMap}
}

if events.EventRegion != nil {
eventsMap["event_region"] = events.EventRegion
}

if events.Location != nil {
eventsMap["location"] = events.Location
}

eventsList = append(eventsList, eventsMap)
ids = append(ids, *events.EventId)
}

_ = d.Set("events", eventsList)
}

d.SetId(helper.DataResourceIdsHash(ids))

output, ok := d.GetOk("result_output_file")
if ok && output.(string) != "" {
if e := tccommon.WriteToFile(output.(string), eventsList); e != nil {
return e
}
}

return nil
}
27 changes: 27 additions & 0 deletions tencentcloud/services/audit/data_source_tc_audit_events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Use this data source to query the events list supported by the audit.

Example Usage
```hcl
data "tencentcloud_audit_events" "events" {
start_time = "1727433841"
end_time = "1727437441"
max_results = 50

lookup_attributes {
attribute_key = "ResourceType"
attribute_value = "cvm"
}

lookup_attributes {
attribute_key = "OnlyRecordNotSeen"
attribute_value = "0"
}

lookup_attributes {
attribute_key = "EventPlatform"
attribute_value = "0"
}

is_return_location = 1
}
```
Loading
Loading