Skip to content
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

d/aws_ssm_patch_baselines: new data source #39779

Merged
merged 1 commit into from
Oct 21, 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/39779.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-data-source
aws_ssm_patch_baselines
```
140 changes: 140 additions & 0 deletions internal/service/ssm/patch_baselines_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package ssm

import (
"context"

"github.com/aws/aws-sdk-go-v2/service/ssm"
awstypes "github.com/aws/aws-sdk-go-v2/service/ssm/types"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-provider-aws/internal/create"
"github.com/hashicorp/terraform-provider-aws/internal/framework"
"github.com/hashicorp/terraform-provider-aws/internal/framework/flex"
fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types"
tfslices "github.com/hashicorp/terraform-provider-aws/internal/slices"
"github.com/hashicorp/terraform-provider-aws/names"
)

// @FrameworkDataSource("aws_ssm_patch_baselines", name="Patch Baselines")
func newDataSourcePatchBaselines(context.Context) (datasource.DataSourceWithConfigure, error) {
return &dataSourcePatchBaselines{}, nil
}

const (
DSNamePatchBaselines = "Patch Baselines Data Source"
)

type dataSourcePatchBaselines struct {
framework.DataSourceWithConfigure
}

func (d *dataSourcePatchBaselines) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { // nosemgrep:ci.meta-in-func-name
resp.TypeName = "aws_ssm_patch_baselines"
}

func (d *dataSourcePatchBaselines) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"baseline_identities": schema.ListAttribute{
CustomType: fwtypes.NewListNestedObjectTypeOf[baselineIdentityModel](ctx),
Computed: true,
ElementType: fwtypes.NewObjectTypeOf[baselineIdentityModel](ctx),
},
"default_baselines": schema.BoolAttribute{
Optional: true,
},
},
Blocks: map[string]schema.Block{
names.AttrFilter: schema.ListNestedBlock{
CustomType: fwtypes.NewListNestedObjectTypeOf[filterModel](ctx),
NestedObject: schema.NestedBlockObject{
Attributes: map[string]schema.Attribute{
names.AttrKey: schema.StringAttribute{
Required: true,
},
names.AttrValues: schema.SetAttribute{
CustomType: fwtypes.SetOfStringType,
Required: true,
},
},
},
},
},
}
}
func (d *dataSourcePatchBaselines) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
conn := d.Meta().SSMClient(ctx)

var data dataSourcePatchBaselinesModel
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
if resp.Diagnostics.HasError() {
return
}

input := ssm.DescribePatchBaselinesInput{}
resp.Diagnostics.Append(flex.Expand(ctx, data, &input)...)
if resp.Diagnostics.HasError() {
return
}

out, err := findPatchBaselines(ctx, conn, &input)
if err != nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.SSM, create.ErrActionReading, DSNamePatchBaselines, "", err),
err.Error(),
)
return
}

if data.DefaultBaselines.ValueBool() {
out = tfslices.Filter(out, func(v awstypes.PatchBaselineIdentity) bool {
return v.DefaultBaseline
})
}

resp.Diagnostics.Append(flex.Flatten(ctx, out, &data.BaselineIdentities)...)
if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

func findPatchBaselines(ctx context.Context, conn *ssm.Client, input *ssm.DescribePatchBaselinesInput) ([]awstypes.PatchBaselineIdentity, error) {
var baselines []awstypes.PatchBaselineIdentity
pages := ssm.NewDescribePatchBaselinesPaginator(conn, input)
for pages.HasMorePages() {
page, err := pages.NextPage(ctx)

if err != nil {
return nil, err
}

baselines = append(baselines, page.BaselineIdentities...)
}

return baselines, nil
}

type dataSourcePatchBaselinesModel struct {
BaselineIdentities fwtypes.ListNestedObjectValueOf[baselineIdentityModel] `tfsdk:"baseline_identities"`
Filter fwtypes.ListNestedObjectValueOf[filterModel] `tfsdk:"filter"`
DefaultBaselines types.Bool `tfsdk:"default_baselines"`
}

type baselineIdentityModel struct {
BaselineDescription types.String `tfsdk:"baseline_description"`
BaselineID types.String `tfsdk:"baseline_id"`
BaselineName types.String `tfsdk:"baseline_name"`
DefaultBaseline types.Bool `tfsdk:"default_baseline"`
OperatingSystem types.String `tfsdk:"operating_system"`
}

type filterModel struct {
Key types.String `tfsdk:"key"`
Values fwtypes.SetOfString `tfsdk:"values"`
}
132 changes: 132 additions & 0 deletions internal/service/ssm/patch_baselines_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package ssm_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
"github.com/hashicorp/terraform-provider-aws/names"
)

func TestAccSSMPatchBaselinesDataSource_basic(t *testing.T) {
ctx := acctest.Context(t)
dataSourceName := "data.aws_ssm_patch_baselines.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, names.SSMEndpointID)
},
ErrorCheck: acctest.ErrorCheck(t, names.SSMServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccPatchBaselinesDataSourceConfig_basic(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckTypeSetElemNestedAttrs(dataSourceName, "baseline_identities.*", map[string]string{
"baseline_name": "AWS-UbuntuDefaultPatchBaseline",
"default_baseline": acctest.CtTrue,
"operating_system": "UBUNTU",
}),
resource.TestCheckTypeSetElemNestedAttrs(dataSourceName, "baseline_identities.*", map[string]string{
"baseline_name": "AWS-WindowsPredefinedPatchBaseline-OS",
"default_baseline": acctest.CtFalse,
"operating_system": "WINDOWS",
}),
),
},
},
})
}

func TestAccSSMPatchBaselinesDataSource_defaultBaselines(t *testing.T) {
ctx := acctest.Context(t)
dataSourceName := "data.aws_ssm_patch_baselines.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, names.SSMEndpointID)
},
ErrorCheck: acctest.ErrorCheck(t, names.SSMServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccPatchBaselinesDataSourceConfig_defaultBaselines(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckTypeSetElemNestedAttrs(dataSourceName, "baseline_identities.*", map[string]string{
"baseline_name": "AWS-UbuntuDefaultPatchBaseline",
"default_baseline": acctest.CtTrue,
"operating_system": "UBUNTU",
}),
),
},
},
})
}

func TestAccSSMPatchBaselinesDataSource_filter(t *testing.T) {
ctx := acctest.Context(t)
dataSourceName := "data.aws_ssm_patch_baselines.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, names.SSMEndpointID)
},
ErrorCheck: acctest.ErrorCheck(t, names.SSMServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccPatchBaselinesDataSourceConfig_filter(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckTypeSetElemNestedAttrs(dataSourceName, "baseline_identities.*", map[string]string{
"baseline_name": "AWS-DefaultPatchBaseline",
"default_baseline": acctest.CtTrue,
"operating_system": "WINDOWS",
}),
resource.TestCheckTypeSetElemNestedAttrs(dataSourceName, "baseline_identities.*", map[string]string{
"baseline_name": "AWS-WindowsPredefinedPatchBaseline-OS",
"default_baseline": acctest.CtFalse,
"operating_system": "WINDOWS",
}),
),
},
},
})
}

func testAccPatchBaselinesDataSourceConfig_basic() string {
return `
data "aws_ssm_patch_baselines" "test" {}
`
}

func testAccPatchBaselinesDataSourceConfig_defaultBaselines() string {
return `
data "aws_ssm_patch_baselines" "test" {
default_baselines = true
}
`
}

func testAccPatchBaselinesDataSourceConfig_filter() string {
return `
data "aws_ssm_patch_baselines" "test" {
filter {
key = "OWNER"
values = ["AWS"]
}
filter {
key = "OPERATING_SYSTEM"
values = ["WINDOWS"]
}
}
`
}
7 changes: 6 additions & 1 deletion internal/service/ssm/service_package_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 60 additions & 0 deletions website/docs/d/ssm_patch_baselines.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
subcategory: "SSM (Systems Manager)"
layout: "aws"
page_title: "AWS: aws_ssm_patch_baselines"
description: |-
Terraform data source for retrieving AWS SSM (Systems Manager) Patch Baselines.
---

# Data Source: aws_ssm_patch_baselines

Terraform data source for retrieving AWS SSM (Systems Manager) Patch Baselines.

## Example Usage

### Basic Usage

```terraform
data "aws_ssm_patch_baselines" "example" {}
```

### With Filters

```terraform
data "aws_ssm_patch_baselines" "example" {
filter {
key = "OWNER"
values = ["AWS"]
}
filter {
key = "OPERATING_SYSTEM"
values = ["WINDOWS"]
}
}
```

## Argument Reference

The following arguments are optional:

* `filter` - (Optional) Key-value pairs used to filter the results. See [`filter`](#filter-argument-reference) below.
* `default_baselines` - (Optional) Only return baseline identities where `default_baseline` is `true`.

### `filter` Argument Reference

* `key` - (Required) Filter key. See the [AWS SSM documentation](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_DescribePatchBaselines.html) for valid values.
* `values` - (Required) Filter values. See the [AWS SSM documentation](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_DescribePatchBaselines.html) for example values.

## Attribute Reference

This data source exports the following attributes in addition to the arguments above:

* `baseline_identities` - List of baseline identities. See [`baseline_identities`](#baseline_identities-attribute-reference) below.

### `baseline_identities` Attribute Reference

* `baseline_description` - Description of the patch baseline.
* `baseline_id` - ID of the patch baseline.
* `baseline_name` - Name of the patch baseline.
* `default_baseline` - Indicates whether this is the default baseline. AWS Systems Manager supports creating multiple default patch baselines. For example, you can create a default patch baseline for each operating system.
* `operating_system` - Operating system the patch baseline applies to.
Loading