Skip to content

Commit

Permalink
Merge pull request hashicorp#36362 from hashicorp/td-lakeformation_mi…
Browse files Browse the repository at this point in the history
…grate_sdkv2

Migrate LakeFormation Service to AWS Go SDKv2
  • Loading branch information
johnsonaj committed Mar 14, 2024
2 parents 6facb32 + c7b79fb commit fae116d
Show file tree
Hide file tree
Showing 26 changed files with 882 additions and 762 deletions.
5 changes: 0 additions & 5 deletions internal/conns/awsclient_gen.go

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

134 changes: 82 additions & 52 deletions internal/service/lakeformation/data_lake_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ import (
"context"
"fmt"
"log"
"reflect"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/lakeformation"
"github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/lakeformation"
awstypes "github.com/aws/aws-sdk-go-v2/service/lakeformation/types"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"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/create"
"github.com/hashicorp/terraform-provider-aws/internal/enum"
"github.com/hashicorp/terraform-provider-aws/internal/errs"
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
"github.com/hashicorp/terraform-provider-aws/internal/flex"
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
Expand Down Expand Up @@ -81,8 +83,8 @@ func ResourceDataLakeSettings() *schema.Resource {
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice(lakeformation.Permission_Values(), false),
Type: schema.TypeString,
ValidateDiagFunc: enum.Validate[awstypes.Permission](),
},
},
"principal": {
Expand All @@ -106,8 +108,8 @@ func ResourceDataLakeSettings() *schema.Resource {
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice(lakeformation.Permission_Values(), false),
Type: schema.TypeString,
ValidateDiagFunc: enum.Validate[awstypes.Permission](),
},
},
"principal": {
Expand Down Expand Up @@ -143,15 +145,15 @@ func ResourceDataLakeSettings() *schema.Resource {

func resourceDataLakeSettingsCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).LakeFormationConn(ctx)
conn := meta.(*conns.AWSClient).LakeFormationClient(ctx)

input := &lakeformation.PutDataLakeSettingsInput{}

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

settings := &lakeformation.DataLakeSettings{}
settings := &awstypes.DataLakeSettings{}

if v, ok := d.GetOk("admins"); ok {
settings.DataLakeAdmins = expandDataLakeSettingsAdmins(v.(*schema.Set))
Expand All @@ -166,7 +168,7 @@ func resourceDataLakeSettingsCreate(ctx context.Context, d *schema.ResourceData,
}

if v, ok := d.GetOk("authorized_session_tag_value_list"); ok {
settings.AuthorizedSessionTagValueList = flex.ExpandStringList(v.([]interface{}))
settings.AuthorizedSessionTagValueList = flex.ExpandStringValueList(v.([]interface{}))
}

if v, ok := d.GetOk("create_database_default_permissions"); ok {
Expand All @@ -182,20 +184,21 @@ func resourceDataLakeSettingsCreate(ctx context.Context, d *schema.ResourceData,
}

if v, ok := d.GetOk("trusted_resource_owners"); ok {
settings.TrustedResourceOwners = flex.ExpandStringList(v.([]interface{}))
settings.TrustedResourceOwners = flex.ExpandStringValueList(v.([]interface{}))
}

input.DataLakeSettings = settings

var output *lakeformation.PutDataLakeSettingsOutput
err := retry.RetryContext(ctx, IAMPropagationTimeout, func() *retry.RetryError {
var err error
output, err = conn.PutDataLakeSettingsWithContext(ctx, input)
output, err = conn.PutDataLakeSettings(ctx, input)
if err != nil {
if tfawserr.ErrMessageContains(err, lakeformation.ErrCodeInvalidInputException, "Invalid principal") {
if errs.IsAErrorMessageContains[*awstypes.InvalidInputException](err, "Invalid principal") {
return retry.RetryableError(err)
}
if tfawserr.ErrCodeEquals(err, lakeformation.ErrCodeConcurrentModificationException) {

if errs.IsA[*awstypes.ConcurrentModificationException](err) {
return retry.RetryableError(err)
}

Expand All @@ -205,7 +208,7 @@ func resourceDataLakeSettingsCreate(ctx context.Context, d *schema.ResourceData,
})

if tfresource.TimedOut(err) {
output, err = conn.PutDataLakeSettingsWithContext(ctx, input)
output, err = conn.PutDataLakeSettings(ctx, input)
}

if err != nil {
Expand All @@ -216,24 +219,24 @@ func resourceDataLakeSettingsCreate(ctx context.Context, d *schema.ResourceData,
return sdkdiag.AppendErrorf(diags, "creating Lake Formation data lake settings: empty response")
}

d.SetId(fmt.Sprintf("%d", create.StringHashcode(input.String())))
d.SetId(fmt.Sprintf("%d", create.StringHashcode(prettify(input))))

return append(diags, resourceDataLakeSettingsRead(ctx, d, meta)...)
}

func resourceDataLakeSettingsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).LakeFormationConn(ctx)
conn := meta.(*conns.AWSClient).LakeFormationClient(ctx)

input := &lakeformation.GetDataLakeSettingsInput{}

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

output, err := conn.GetDataLakeSettingsWithContext(ctx, input)
output, err := conn.GetDataLakeSettings(ctx, input)

if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, lakeformation.ErrCodeEntityNotFoundException) {
if !d.IsNewResource() && errs.IsA[*awstypes.EntityNotFoundException](err) {
log.Printf("[WARN] Lake Formation data lake settings (%s) not found, removing from state", d.Id())
d.SetId("")
return diags
Expand All @@ -252,36 +255,36 @@ func resourceDataLakeSettingsRead(ctx context.Context, d *schema.ResourceData, m
d.Set("admins", flattenDataLakeSettingsAdmins(settings.DataLakeAdmins))
d.Set("read_only_admins", flattenDataLakeSettingsAdmins(settings.ReadOnlyAdmins))
d.Set("allow_external_data_filtering", settings.AllowExternalDataFiltering)
d.Set("authorized_session_tag_value_list", flex.FlattenStringList(settings.AuthorizedSessionTagValueList))
d.Set("authorized_session_tag_value_list", flex.FlattenStringValueList(settings.AuthorizedSessionTagValueList))
d.Set("create_database_default_permissions", flattenDataLakeSettingsCreateDefaultPermissions(settings.CreateDatabaseDefaultPermissions))
d.Set("create_table_default_permissions", flattenDataLakeSettingsCreateDefaultPermissions(settings.CreateTableDefaultPermissions))
d.Set("external_data_filtering_allow_list", flattenDataLakeSettingsDataFilteringAllowList(settings.ExternalDataFilteringAllowList))
d.Set("trusted_resource_owners", flex.FlattenStringList(settings.TrustedResourceOwners))
d.Set("trusted_resource_owners", flex.FlattenStringValueList(settings.TrustedResourceOwners))

return diags
}

func resourceDataLakeSettingsDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).LakeFormationConn(ctx)
conn := meta.(*conns.AWSClient).LakeFormationClient(ctx)

input := &lakeformation.PutDataLakeSettingsInput{
DataLakeSettings: &lakeformation.DataLakeSettings{
CreateDatabaseDefaultPermissions: make([]*lakeformation.PrincipalPermissions, 0),
CreateTableDefaultPermissions: make([]*lakeformation.PrincipalPermissions, 0),
DataLakeAdmins: make([]*lakeformation.DataLakePrincipal, 0),
ReadOnlyAdmins: make([]*lakeformation.DataLakePrincipal, 0),
TrustedResourceOwners: make([]*string, 0),
DataLakeSettings: &awstypes.DataLakeSettings{
CreateDatabaseDefaultPermissions: make([]awstypes.PrincipalPermissions, 0),
CreateTableDefaultPermissions: make([]awstypes.PrincipalPermissions, 0),
DataLakeAdmins: make([]awstypes.DataLakePrincipal, 0),
ReadOnlyAdmins: make([]awstypes.DataLakePrincipal, 0),
TrustedResourceOwners: make([]string, 0),
},
}

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

_, err := conn.PutDataLakeSettingsWithContext(ctx, input)
_, err := conn.PutDataLakeSettings(ctx, input)

if tfawserr.ErrCodeEquals(err, lakeformation.ErrCodeEntityNotFoundException) {
if errs.IsA[*awstypes.EntityNotFoundException](err) {
log.Printf("[WARN] Lake Formation data lake settings (%s) not found, removing from state", d.Id())
return diags
}
Expand All @@ -293,8 +296,8 @@ func resourceDataLakeSettingsDelete(ctx context.Context, d *schema.ResourceData,
return diags
}

func expandDataLakeSettingsCreateDefaultPermissions(tfMaps []interface{}) []*lakeformation.PrincipalPermissions {
apiObjects := make([]*lakeformation.PrincipalPermissions, 0, len(tfMaps))
func expandDataLakeSettingsCreateDefaultPermissions(tfMaps []interface{}) []awstypes.PrincipalPermissions {
apiObjects := make([]awstypes.PrincipalPermissions, 0, len(tfMaps))

for _, tfMap := range tfMaps {
apiObjects = append(apiObjects, expandDataLakeSettingsCreateDefaultPermission(tfMap.(map[string]interface{})))
Expand All @@ -303,18 +306,18 @@ func expandDataLakeSettingsCreateDefaultPermissions(tfMaps []interface{}) []*lak
return apiObjects
}

func expandDataLakeSettingsCreateDefaultPermission(tfMap map[string]interface{}) *lakeformation.PrincipalPermissions {
apiObject := &lakeformation.PrincipalPermissions{
Permissions: flex.ExpandStringSet(tfMap["permissions"].(*schema.Set)),
Principal: &lakeformation.DataLakePrincipal{
func expandDataLakeSettingsCreateDefaultPermission(tfMap map[string]interface{}) awstypes.PrincipalPermissions {
apiObject := awstypes.PrincipalPermissions{
Permissions: expandPermissions(tfMap["permissions"].(*schema.Set).List()),
Principal: &awstypes.DataLakePrincipal{
DataLakePrincipalIdentifier: aws.String(tfMap["principal"].(string)),
},
}

return apiObject
}

func flattenDataLakeSettingsCreateDefaultPermissions(apiObjects []*lakeformation.PrincipalPermissions) []map[string]interface{} {
func flattenDataLakeSettingsCreateDefaultPermissions(apiObjects []awstypes.PrincipalPermissions) []map[string]interface{} {
if apiObjects == nil {
return nil
}
Expand All @@ -327,32 +330,59 @@ func flattenDataLakeSettingsCreateDefaultPermissions(apiObjects []*lakeformation
return tfMaps
}

func flattenDataLakeSettingsCreateDefaultPermission(apiObject *lakeformation.PrincipalPermissions) map[string]interface{} {
func flattenDataLakeSettingsCreateDefaultPermission(apiObject awstypes.PrincipalPermissions) map[string]interface{} {
tfMap := make(map[string]interface{})

if apiObject == nil {
if reflect.ValueOf(apiObject).IsZero() {
return tfMap
}

if apiObject.Permissions != nil {
tfMap["permissions"] = flex.FlattenStringSet(apiObject.Permissions)
tfMap["permissions"] = flex.FlattenStringValueSet(flattenPermissions(apiObject.Permissions))
}

if v := aws.StringValue(apiObject.Principal.DataLakePrincipalIdentifier); v != "" {
if v := aws.ToString(apiObject.Principal.DataLakePrincipalIdentifier); v != "" {
tfMap["principal"] = v
}

return tfMap
}

func expandDataLakeSettingsAdmins(tfSet *schema.Set) []*lakeformation.DataLakePrincipal {
func expandPermissions(in []interface{}) []awstypes.Permission {
if len(in) == 0 {
return nil
}

var out []awstypes.Permission

for _, v := range in {
out = append(out, awstypes.Permission(v.(string)))
}

return out
}

func flattenPermissions(apiObjects []awstypes.Permission) []string {
if len(apiObjects) == 0 {
return nil
}

var out []string
for _, apiObject := range apiObjects {
out = append(out, string(apiObject))
}

return out
}

func expandDataLakeSettingsAdmins(tfSet *schema.Set) []awstypes.DataLakePrincipal {
tfSlice := tfSet.List()
apiObjects := make([]*lakeformation.DataLakePrincipal, 0, len(tfSlice))
apiObjects := make([]awstypes.DataLakePrincipal, 0, len(tfSlice))

for _, tfItem := range tfSlice {
val, ok := tfItem.(string)
if ok && val != "" {
apiObjects = append(apiObjects, &lakeformation.DataLakePrincipal{
apiObjects = append(apiObjects, awstypes.DataLakePrincipal{
DataLakePrincipalIdentifier: aws.String(tfItem.(string)),
})
}
Expand All @@ -361,28 +391,28 @@ func expandDataLakeSettingsAdmins(tfSet *schema.Set) []*lakeformation.DataLakePr
return apiObjects
}

func flattenDataLakeSettingsAdmins(apiObjects []*lakeformation.DataLakePrincipal) []interface{} {
func flattenDataLakeSettingsAdmins(apiObjects []awstypes.DataLakePrincipal) []interface{} {
if apiObjects == nil {
return nil
}

tfSlice := make([]interface{}, 0, len(apiObjects))

for _, apiObject := range apiObjects {
tfSlice = append(tfSlice, aws.StringValue(apiObject.DataLakePrincipalIdentifier))
tfSlice = append(tfSlice, aws.ToString(apiObject.DataLakePrincipalIdentifier))
}

return tfSlice
}

func expandDataLakeSettingsDataFilteringAllowList(tfSet *schema.Set) []*lakeformation.DataLakePrincipal {
func expandDataLakeSettingsDataFilteringAllowList(tfSet *schema.Set) []awstypes.DataLakePrincipal {
tfSlice := tfSet.List()
apiObjects := make([]*lakeformation.DataLakePrincipal, 0, len(tfSlice))
apiObjects := make([]awstypes.DataLakePrincipal, 0, len(tfSlice))

for _, tfItem := range tfSlice {
val, ok := tfItem.(string)
if ok && val != "" {
apiObjects = append(apiObjects, &lakeformation.DataLakePrincipal{
apiObjects = append(apiObjects, awstypes.DataLakePrincipal{
DataLakePrincipalIdentifier: aws.String(tfItem.(string)),
})
}
Expand All @@ -391,15 +421,15 @@ func expandDataLakeSettingsDataFilteringAllowList(tfSet *schema.Set) []*lakeform
return apiObjects
}

func flattenDataLakeSettingsDataFilteringAllowList(apiObjects []*lakeformation.DataLakePrincipal) []interface{} {
func flattenDataLakeSettingsDataFilteringAllowList(apiObjects []awstypes.DataLakePrincipal) []interface{} {
if apiObjects == nil {
return nil
}

tfSlice := make([]interface{}, 0, len(apiObjects))

for _, apiObject := range apiObjects {
tfSlice = append(tfSlice, aws.StringValue(apiObject.DataLakePrincipalIdentifier))
tfSlice = append(tfSlice, aws.ToString(apiObject.DataLakePrincipalIdentifier))
}

return tfSlice
Expand Down
Loading

0 comments on commit fae116d

Please sign in to comment.