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

New Data Source: aws_rds_certificate #15789

Merged
merged 1 commit into from
Oct 22, 2020
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
149 changes: 149 additions & 0 deletions aws/data_source_aws_rds_certificate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package aws

import (
"fmt"
"sort"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/rds"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceAwsRdsCertificate() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsRdsCertificateRead,
Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"certificate_type": {
Type: schema.TypeString,
Computed: true,
},
"customer_override": {
Type: schema.TypeBool,
Computed: true,
},
"customer_override_valid_till": {
Type: schema.TypeString,
Computed: true,
},
"id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"latest_valid_till": {
Type: schema.TypeBool,
Optional: true,
},
"thumbprint": {
Type: schema.TypeString,
Computed: true,
},
"valid_from": {
Type: schema.TypeString,
Computed: true,
},
"valid_till": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceAwsRdsCertificateRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).rdsconn

input := &rds.DescribeCertificatesInput{}

if v, ok := d.GetOk("id"); ok {
input.CertificateIdentifier = aws.String(v.(string))
}

var certificates []*rds.Certificate

err := conn.DescribeCertificatesPages(input, func(page *rds.DescribeCertificatesOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}

for _, certificate := range page.Certificates {
if certificate == nil {
continue
}

certificates = append(certificates, certificate)
}
return !lastPage
})

if err != nil {
return fmt.Errorf("error reading RDS Certificates: %w", err)
}

if len(certificates) == 0 {
return fmt.Errorf("no RDS Certificates found")
}

// client side filtering
var certificate *rds.Certificate

if d.Get("latest_valid_till").(bool) {
sort.Sort(rdsCertificateValidTillSort(certificates))
certificate = certificates[len(certificates)-1]
}

if len(certificates) > 1 {
return fmt.Errorf("multiple RDS Certificates match the criteria; try changing search query")
}

if certificate == nil && len(certificates) == 1 {
certificate = certificates[0]
}

if certificate == nil {
return fmt.Errorf("no RDS Certificates match the criteria")
}

d.SetId(aws.StringValue(certificate.CertificateIdentifier))

d.Set("arn", certificate.CertificateArn)
d.Set("certificate_type", certificate.CertificateType)
d.Set("customer_override", certificate.CustomerOverride)

if certificate.CustomerOverrideValidTill != nil {
d.Set("customer_override_valid_till", aws.TimeValue(certificate.CustomerOverrideValidTill).Format(time.RFC3339))
}

d.Set("thumbprint", certificate.Thumbprint)

if certificate.ValidFrom != nil {
d.Set("valid_from", aws.TimeValue(certificate.ValidFrom).Format(time.RFC3339))
}

if certificate.ValidTill != nil {
d.Set("valid_till", aws.TimeValue(certificate.ValidTill).Format(time.RFC3339))
}

return nil
}

type rdsCertificateValidTillSort []*rds.Certificate

func (s rdsCertificateValidTillSort) Len() int { return len(s) }
func (s rdsCertificateValidTillSort) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s rdsCertificateValidTillSort) Less(i, j int) bool {
if s[i] == nil || s[i].ValidTill == nil {
return true
}

if s[j] == nil || s[j].ValidTill == nil {
return false
}

return (*s[i].ValidTill).Before(*s[j].ValidTill)
}
88 changes: 88 additions & 0 deletions aws/data_source_aws_rds_certificate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package aws

import (
"regexp"
"testing"

"github.com/aws/aws-sdk-go/service/rds"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccAWSRDSCertificateDataSource_Id(t *testing.T) {
dataSourceName := "data.aws_rds_certificate.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccAWSRDSCertificatePreCheck(t) },
Providers: testAccProviders,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccAWSRDSCertificateDataSourceConfigId(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "id", "data.aws_rds_certificate.latest", "id"),
),
},
},
})
}

func TestAccAWSRDSCertificateDataSource_LatestValidTill(t *testing.T) {
dataSourceName := "data.aws_rds_certificate.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccAWSRDSCertificatePreCheck(t) },
Providers: testAccProviders,
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: testAccAWSRDSCertificateDataSourceConfigLatestValidTill(),
Check: resource.ComposeTestCheckFunc(
testAccMatchResourceAttrRegionalARNNoAccount(dataSourceName, "arn", "rds", regexp.MustCompile(`cert:rds-ca-[0-9]{4}`)),
resource.TestCheckResourceAttr(dataSourceName, "certificate_type", "CA"),
resource.TestCheckResourceAttr(dataSourceName, "customer_override", "false"),
resource.TestCheckNoResourceAttr(dataSourceName, "customer_override_valid_till"),
resource.TestMatchResourceAttr(dataSourceName, "id", regexp.MustCompile(`rds-ca-[0-9]{4}`)),
resource.TestMatchResourceAttr(dataSourceName, "thumbprint", regexp.MustCompile(`[0-9a-f]+`)),
resource.TestMatchResourceAttr(dataSourceName, "valid_from", regexp.MustCompile(rfc3339RegexPattern)),
resource.TestMatchResourceAttr(dataSourceName, "valid_till", regexp.MustCompile(rfc3339RegexPattern)),
),
},
},
})
}

func testAccAWSRDSCertificatePreCheck(t *testing.T) {
conn := testAccProvider.Meta().(*AWSClient).rdsconn

input := &rds.DescribeCertificatesInput{}

_, err := conn.DescribeCertificates(input)

if testAccPreCheckSkipError(err) {
t.Skipf("skipping acceptance testing: %s", err)
}

if err != nil {
t.Fatalf("unexpected PreCheck error: %s", err)
}
}

func testAccAWSRDSCertificateDataSourceConfigId() string {
return `
data "aws_rds_certificate" "latest" {
latest_valid_till = true
}

data "aws_rds_certificate" "test" {
id = data.aws_rds_certificate.latest.id
}
`
}

func testAccAWSRDSCertificateDataSourceConfigLatestValidTill() string {
return `
data "aws_rds_certificate" "test" {
latest_valid_till = true
}
`
}
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ func Provider() *schema.Provider {
"aws_pricing_product": dataSourceAwsPricingProduct(),
"aws_qldb_ledger": dataSourceAwsQLDBLedger(),
"aws_ram_resource_share": dataSourceAwsRamResourceShare(),
"aws_rds_certificate": dataSourceAwsRdsCertificate(),
"aws_rds_cluster": dataSourceAwsRdsCluster(),
"aws_rds_engine_version": dataSourceAwsRdsEngineVersion(),
"aws_rds_orderable_db_instance": dataSourceAwsRdsOrderableDbInstance(),
Expand Down
38 changes: 38 additions & 0 deletions website/docs/d/rds_certificate.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
subcategory: "RDS"
layout: "aws"
page_title: "AWS: aws_rds_certificate"
description: |-
Information about an RDS Certificate.
---

# Data Source: aws_rds_certificate

Information about an RDS Certificate.

## Example Usage

```hcl
data "aws_rds_certificate" "example" {
latest_valid_till = true
}
```

## Argument Reference

The following arguments are supported:

* `id` - (Optional) Certificate identifier. For example, `rds-ca-2019`.
* `latest_valid_till` - (Optional) When enabled, returns the certificate with the latest `ValidTill`.

## Attribute Reference

In addition to all arguments above, the following attributes are exported:

* `arn` - Amazon Resource Name (ARN) of the certificate.
* `certificate_type` - Type of certificate. For example, `CA`.
* `customer_override` - Boolean whether there is an override for the default certificate identifier.
* `customer_override_valid_till` - If there is an override for the default certificate identifier, when the override expires.
* `thumbprint` - Thumbprint of the certificate.
* `valid_from` - [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8) of certificate starting validity date.
* `valid_till` - [RFC3339 format](https://tools.ietf.org/html/rfc3339#section-5.8) of certificate ending validity date.