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 Resource: aws_athena_data_catalog #22968

Merged
merged 21 commits into from
Apr 22, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
09d5d40
Athena-DataCatalog: Create entry in `internal/provider/provider.go`
bschaatsbergen Feb 6, 2022
41f2ef6
Athena-DataCatalog: create changelog entry
bschaatsbergen Feb 6, 2022
f6a70bf
Athena-DataCatalog: create `data_catalog.go`
bschaatsbergen Feb 6, 2022
785e8a6
Athena-DataCatalog: Set ARN to retrieve tags
bschaatsbergen Feb 6, 2022
c46b1ad
Athena-DataCatalog: Implement workaround for the `parameters` as API …
bschaatsbergen Feb 6, 2022
f69053d
Athena-DataCatalog: Added regex validation to match API spec
bschaatsbergen Feb 6, 2022
7ce5996
Athena-DataCatalog: Add `data_catalog_test.go`
bschaatsbergen Feb 6, 2022
f9b5427
Athena-DataCatalog: Added per attribute acceptance tests
bschaatsbergen Feb 6, 2022
c7b8dc1
Athena-DataCatalog: Add new resource docs
bschaatsbergen Feb 6, 2022
b116b50
r/aws_athena_data_catalog: Alphabetize attributes.
ewbankkit Apr 22, 2022
6426e63
r/aws_athena_data_catalog: Reorder CRUD handler functions.
ewbankkit Apr 22, 2022
32a5c2a
r/aws_athena_data_catalog: Tidy up acceptance test configurations.
ewbankkit Apr 22, 2022
08d5c98
r/aws_athena_data_catalog: Rename acceptance test functions.
ewbankkit Apr 22, 2022
82663e4
r/aws_athena_data_catalog: Tidup up 'parameters' handling.
ewbankkit Apr 22, 2022
88f7fb1
r/aws_athena_data_catalog: Test 'parameters' update.
ewbankkit Apr 22, 2022
0f07b9a
r/aws_athena_data_catalog: Add 'TestAccAthenaDataCatalog_tags'.
ewbankkit Apr 22, 2022
7c33710
Fix 'MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actu…
ewbankkit Apr 22, 2022
2fd96f9
Fix terrafmt error.
ewbankkit Apr 22, 2022
d194679
Really fix terrafmt error.
ewbankkit Apr 22, 2022
0385003
Fix 'AT012: file contains multiple acceptance test name prefixes: [Te…
ewbankkit Apr 22, 2022
64d83f0
Add '//lintignore:AWSAT003,AWSAT005' in multiple places.
ewbankkit Apr 22, 2022
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/22968.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:new-resource
aws_athena_data_catalog
```
7 changes: 4 additions & 3 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -971,9 +971,10 @@ func Provider() *schema.Provider {
"aws_appsync_graphql_api": appsync.ResourceGraphQLAPI(),
"aws_appsync_resolver": appsync.ResourceResolver(),

"aws_athena_database": athena.ResourceDatabase(),
"aws_athena_named_query": athena.ResourceNamedQuery(),
"aws_athena_workgroup": athena.ResourceWorkGroup(),
"aws_athena_database": athena.ResourceDatabase(),
"aws_athena_data_catalog": athena.ResourceDataCatalog(),
"aws_athena_named_query": athena.ResourceNamedQuery(),
"aws_athena_workgroup": athena.ResourceWorkGroup(),

"aws_autoscaling_attachment": autoscaling.ResourceAttachment(),
"aws_autoscaling_group": autoscaling.ResourceGroup(),
Expand Down
240 changes: 240 additions & 0 deletions internal/service/athena/data_catalog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
package athena

import (
"context"
"fmt"
"log"
"regexp"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/athena"
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
"github.com/hashicorp/terraform-provider-aws/internal/flex"
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
"github.com/hashicorp/terraform-provider-aws/internal/verify"
)

func ResourceDataCatalog() *schema.Resource {
return &schema.Resource{
CreateContext: resourceDataCatalogCreate,
ReadContext: resourceDataCatalogRead,
UpdateContext: resourceDataCatalogUpdate,
DeleteContext: resourceDataCatalogDelete,

Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},

CustomizeDiff: verify.SetTagsDiff,

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"description": {
Type: schema.TypeString,
Required: true,
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.All(
validation.StringLenBetween(1, 129),
validation.StringMatch(regexp.MustCompile(`[\w@-]*`), ""),
),
},
"parameters": {
Type: schema.TypeMap,
Required: true,
Elem: &schema.Schema{Type: schema.TypeString},
ValidateDiagFunc: allDiagFunc(
validation.MapKeyLenBetween(1, 255),
validation.MapValueLenBetween(0, 51200),
),
},
"tags": tftags.TagsSchema(),
"tags_all": tftags.TagsSchemaComputed(),
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice(athena.DataCatalogType_Values(), false),
},
},
}
}

func resourceDataCatalogCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).AthenaConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
tags := defaultTagsConfig.MergeTags(tftags.New(d.Get("tags").(map[string]interface{})))

name := d.Get("name").(string)
input := &athena.CreateDataCatalogInput{
Name: aws.String(name),
Description: aws.String(d.Get("description").(string)),
Type: aws.String(d.Get("type").(string)),
}

if v, ok := d.GetOk("parameters"); ok && len(v.(map[string]interface{})) > 0 {
input.Parameters = flex.ExpandStringMap(v.(map[string]interface{}))
}

if len(tags) > 0 {
input.Tags = Tags(tags.IgnoreAWS())
}

log.Printf("[DEBUG] Creating Athena Data Catalog: %s", input)
_, err := conn.CreateDataCatalogWithContext(ctx, input)

if err != nil {
return diag.Errorf("creating Athena Data Catalog (%s): %s", name, err)
}

d.SetId(name)

return resourceDataCatalogRead(ctx, d, meta)
}

func resourceDataCatalogRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).AthenaConn
defaultTagsConfig := meta.(*conns.AWSClient).DefaultTagsConfig
ignoreTagsConfig := meta.(*conns.AWSClient).IgnoreTagsConfig

input := &athena.GetDataCatalogInput{
Name: aws.String(d.Id()),
}

dataCatalog, err := conn.GetDataCatalogWithContext(ctx, input)

// If the resource doesn't exist, the API returns a `ErrCodeInvalidRequestException` error.
if !d.IsNewResource() && tfawserr.ErrMessageContains(err, athena.ErrCodeInvalidRequestException, "was not found") {
log.Printf("[WARN] Athena Data Catalog (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return diag.Errorf("reading Athena Data Catalog (%s): %s", d.Id(), err)
}

arn := arn.ARN{
Partition: meta.(*conns.AWSClient).Partition,
Region: meta.(*conns.AWSClient).Region,
Service: "athena",
AccountID: meta.(*conns.AWSClient).AccountID,
Resource: fmt.Sprintf("datacatalog/%s", d.Id()),
}.String()
d.Set("arn", arn)
d.Set("description", dataCatalog.DataCatalog.Description)
d.Set("name", dataCatalog.DataCatalog.Name)
d.Set("type", dataCatalog.DataCatalog.Type)

// NOTE: This is a workaround for the fact that the API sets default values for parameters that are not set.
// Because the API sets default values, what's returned by the API is different than what's set by the user.
if v, ok := d.GetOk("parameters"); ok && len(v.(map[string]interface{})) > 0 {
parameters := make(map[string]string, 0)

for key, val := range v.(map[string]interface{}) {
if v, ok := dataCatalog.DataCatalog.Parameters[key]; ok {
parameters[key] = aws.StringValue(v)
} else {
parameters[key] = val.(string)
}
}

d.Set("parameters", parameters)
} else {
d.Set("parameters", nil)
}

tags, err := ListTags(conn, arn)

if err != nil {
return diag.Errorf("listing tags for Athena Data Catalog (%s): %s", d.Id(), err)
}

tags = tags.IgnoreAWS().IgnoreConfig(ignoreTagsConfig)

//lintignore:AWSR002
if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil {
return diag.Errorf("setting tags: %s", err)
}

if err := d.Set("tags_all", tags.Map()); err != nil {
return diag.Errorf("error setting tags_all: %s", err)
}

return nil
}

func resourceDataCatalogUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).AthenaConn

if d.HasChangesExcept("tags", "tags_all") {
input := &athena.UpdateDataCatalogInput{
Name: aws.String(d.Id()),
Type: aws.String(d.Get("type").(string)),
Description: aws.String(d.Get("description").(string)),
}

if d.HasChange("parameters") {
if v, ok := d.GetOk("parameters"); ok && len(v.(map[string]interface{})) > 0 {
input.Parameters = flex.ExpandStringMap(v.(map[string]interface{}))
}
}

log.Printf("[DEBUG] Updating Athena Data Catalog: %s", input)
_, err := conn.UpdateDataCatalogWithContext(ctx, input)

if err != nil {
return diag.Errorf("updating Athena Data Catalog (%s): %s", d.Id(), err)
}
}

if d.HasChange("tags_all") {
o, n := d.GetChange("tags_all")

if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
return diag.Errorf("updating Athena Data Catalog (%s) tags: %s", d.Id(), err)
}
}

return resourceDataCatalogRead(ctx, d, meta)
}

func resourceDataCatalogDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
conn := meta.(*conns.AWSClient).AthenaConn

log.Printf("[DEBUG] Deleting Athena Data Catalog: (%s)", d.Id())
_, err := conn.DeleteDataCatalogWithContext(ctx, &athena.DeleteDataCatalogInput{
Name: aws.String(d.Id()),
})

if tfawserr.ErrCodeEquals(err, athena.ErrCodeResourceNotFoundException) {
return nil
}

if err != nil {
return diag.Errorf("deleting Athena Data Catalog (%s): %s", d.Id(), err)
}

return nil
}

func allDiagFunc(validators ...schema.SchemaValidateDiagFunc) schema.SchemaValidateDiagFunc {
return func(i interface{}, k cty.Path) diag.Diagnostics {
var diags diag.Diagnostics
for _, validator := range validators {
diags = append(diags, validator(i, k)...)
}
return diags
}
}
Loading