Skip to content

Commit

Permalink
feat(lts): the log stream supports modifying ttl_in_days field
Browse files Browse the repository at this point in the history
  • Loading branch information
wuzhuanhong committed Dec 17, 2024
1 parent 818ad5d commit 782eb81
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 29 deletions.
2 changes: 2 additions & 0 deletions docs/data-sources/lts_streams.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ The `streams` block supports:

* `name` - The name of the log stream.

* `ttl_in_days` - The log expiration time (days).

* `tags` - The key/value pairs to associate with the log stream.

* `created_at` - The creation time of the log stream, in RFC3339 format.
20 changes: 2 additions & 18 deletions docs/resources/lts_stream.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ The following arguments are supported:
* `stream_name` - (Required, String, ForceNew) Specifies the log stream name. Changing this parameter will create a new
resource.

* `ttl_in_days` - (Optional, Int, ForceNew) Specifies the log expiration time(days), value range: 1-365.
If not specified, it will inherit the log group setting. Changing this parameter will create a new resource.
* `ttl_in_days` - (Optional, Int) Specifies the log expiration time (days).
The valid value is a non-zero integer from `-1` to `365`, defaults to `-1` which means inherit the log group settings.

* `enterprise_project_id` - (Optional, String, ForceNew) Specifies the enterprise project ID.
Changing this parameter will create a new resource.
Expand All @@ -59,19 +59,3 @@ The log stream can be imported using the group ID and stream ID separated by a s
```bash
$ terraform import huaweicloud_lts_stream.test <group_id>/<id>
```

Note that the imported state may not be identical to your resource definition, due to `ttl_in_days` attribute missing
from the API response. It is generally recommended running `terraform plan` after importing a resource.
You can then decide if changes should be applied to the resource, or the resource definition should be updated to
align with the resource. Also you can ignore changes as below.

```hcl
resource "huaweicloud_lts_stream" "test" {
...
lifecycle {
ignore_changes = [
ttl_in_days,
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func TestAccDataSourceStreams_basic(t *testing.T) {
dcByName.CheckResourceExists(),
resource.TestCheckResourceAttrPair(byName, "streams.0.id", "huaweicloud_lts_stream.test", "id"),
resource.TestCheckResourceAttr(byName, "streams.0.name", rName),
resource.TestCheckResourceAttr(byName, "streams.0.ttl_in_days", "60"),
resource.TestCheckResourceAttr(byName, "streams.0.tags._sys_enterprise_project_id", "0"),
resource.TestCheckResourceAttr(byName, "streams.0.tags.terraform", "test"),
resource.TestCheckOutput("is_name_filter_useful", "true"),
Expand Down Expand Up @@ -70,6 +71,7 @@ resource "huaweicloud_lts_group" "test" {
resource "huaweicloud_lts_stream" "test" {
group_id = huaweicloud_lts_group.test.id
stream_name = huaweicloud_lts_group.test.group_name
ttl_in_days = 60
enterprise_project_id = "0"
tags = {
Expand All @@ -88,6 +90,7 @@ locals {
stream_name = huaweicloud_lts_stream.test.stream_name
}
# The name is an exact match.
data "huaweicloud_lts_streams" "filter_by_name" {
depends_on = [
huaweicloud_lts_stream.test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func TestAccLtsStream_basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
rc.CheckResourceExists(),
resource.TestCheckResourceAttr(resourceName, "stream_name", rName),
resource.TestCheckResourceAttr(resourceName, "ttl_in_days", "-1"),
resource.TestCheckResourceAttr(resourceName, "filter_count", "0"),
resource.TestCheckResourceAttr(resourceName, "enterprise_project_id", "0"),
resource.TestCheckResourceAttrSet(resourceName, "created_at"),
Expand All @@ -81,16 +82,16 @@ func TestAccLtsStream_basic(t *testing.T) {
Config: testAccLtsStream_update(rName),
Check: resource.ComposeTestCheckFunc(
rc.CheckResourceExists(),
resource.TestCheckResourceAttr(resourceName, "ttl_in_days", "60"),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(resourceName, "tags.owner", "terraform"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"ttl_in_days"},
ImportStateIdFunc: testLtsStreamImportState(resourceName),
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateIdFunc: testLtsStreamImportState(resourceName),
},
},
})
Expand Down Expand Up @@ -124,7 +125,6 @@ resource "huaweicloud_lts_group" "test" {
resource "huaweicloud_lts_stream" "test" {
group_id = huaweicloud_lts_group.test.id
stream_name = "%[1]s"
ttl_in_days = 60
tags = {
foo = "bar"
Expand Down
14 changes: 10 additions & 4 deletions huaweicloud/services/lts/data_source_huaweicloud_lts_streams.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ func DataSourceLtsStreams() *schema.Resource {
Computed: true,
Description: `The name of the log stream.`,
},
"ttl_in_days": {
Type: schema.TypeInt,
Computed: true,
Description: `the log expiration time (days).`,
},
"tags": {
Type: schema.TypeMap,
Computed: true,
Expand Down Expand Up @@ -132,10 +137,11 @@ func (w *StreamsDSWrapper) listLogStreamsToSchema(body *gjson.Result) error {
d.Set("streams", schemas.SliceToList(body.Get("log_streams"),
func(streams gjson.Result) any {
return map[string]any{
"id": streams.Get("log_stream_id").Value(),
"name": streams.Get("log_stream_name").Value(),
"tags": schemas.MapToStrMap(streams.Get("tag")),
"created_at": w.setLogStrCreTime(streams),
"id": streams.Get("log_stream_id").Value(),
"name": streams.Get("log_stream_name").Value(),
"ttl_in_days": streams.Get("ttl_in_days").Value(),
"tags": schemas.MapToStrMap(streams.Get("tag")),
"created_at": w.setLogStrCreTime(streams),
}
},
)),
Expand Down
31 changes: 30 additions & 1 deletion huaweicloud/services/lts/resource_huaweicloud_lts_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const EPSTagKey string = "_sys_enterprise_project_id"

// @API LTS POST /v2/{project_id}/groups/{log_group_id}/streams
// @API LTS GET /v2/{project_id}/groups/{log_group_id}/streams
// @API LTS PUT /v2/{project_id}/groups/{log_group_id}/streams-ttl/{log_stream_id}
// @API LTS DELETE /v2/{project_id}/groups/{log_group_id}/streams/{log_stream_id}
// @API LTS POST /v1/{project_id}/{resource_type}/{resource_id}/tags/action
func ResourceLTSStream() *schema.Resource {
Expand Down Expand Up @@ -52,8 +53,8 @@ func ResourceLTSStream() *schema.Resource {
},
"ttl_in_days": {
Type: schema.TypeInt,
Computed: true,
Optional: true,
ForceNew: true,
},
"enterprise_project_id": {
Type: schema.TypeString,
Expand Down Expand Up @@ -212,6 +213,7 @@ func resourceStreamRead(_ context.Context, d *schema.ResourceData, meta interfac
mErr := multierror.Append(nil,
d.Set("region", region),
d.Set("stream_name", utils.PathSearch("log_stream_name", streamResult, nil)),
d.Set("ttl_in_days", utils.PathSearch("ttl_in_days", streamResult, nil)),
d.Set("enterprise_project_id", utils.PathSearch("tag._sys_enterprise_project_id", streamResult, nil)),
d.Set("tags", ignoreSysEpsTag(utils.PathSearch("tag", streamResult, make(map[string]interface{})).(map[string]interface{}))),
d.Set("filter_count", utils.PathSearch("filter_count", streamResult, nil)),
Expand All @@ -238,9 +240,36 @@ func resourceStreamUpdate(ctx context.Context, d *schema.ResourceData, meta inte
}
}

if d.HasChange("ttl_in_days") {
if err = updateStreamTTL(client, d.Get("group_id").(string), streamId, d.Get("ttl_in_days")); err != nil {
return diag.FromErr(err)
}
}

return resourceStreamRead(ctx, d, meta)
}

func updateStreamTTL(client *golangsdk.ServiceClient, logGroupId, logStreamId string, ttlInDays interface{}) error {
httpUrl := "v2/{project_id}/groups/{log_group_id}/streams-ttl/{log_stream_id}"
updatePath := client.Endpoint + httpUrl
updatePath = strings.ReplaceAll(updatePath, "{project_id}", client.ProjectID)
updatePath = strings.ReplaceAll(updatePath, "{log_group_id}", logGroupId)
updatePath = strings.ReplaceAll(updatePath, "{log_stream_id}", logStreamId)

updateOpt := golangsdk.RequestOpts{
KeepResponseBody: true,
MoreHeaders: map[string]string{"Content-Type": "application/json"},
JSONBody: map[string]interface{}{
"ttl_in_days": ttlInDays,
},
}
_, err := client.Request("PUT", updatePath, &updateOpt)
if err != nil {
return fmt.Errorf("error updating ttl_in_days of the log stream (%s): %s", logStreamId, err)
}
return nil
}

func resourceStreamDelete(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var (
cfg = meta.(*config.Config)
Expand Down

0 comments on commit 782eb81

Please sign in to comment.