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

r/glue_catalog_database - add create_table_default_permission argument #22964

Merged
merged 6 commits into from
Feb 11, 2022
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/22964.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_glue_catalog_database: Add support `create_table_default_permission` argument
```
157 changes: 153 additions & 4 deletions internal/service/glue/catalog_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,37 @@ func ResourceCatalogDatabase() *schema.Resource {
validation.StringDoesNotMatch(regexp.MustCompile(`[A-Z]`), "uppercase characters cannot be used"),
),
},
"create_table_default_permission": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"permissions": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice(glue.Permission_Values(), false),
},
},
"principal": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"data_lake_principal_identifier": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringLenBetween(1, 255),
},
},
},
},
},
},
},
"description": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -108,6 +139,10 @@ func resourceCatalogDatabaseCreate(d *schema.ResourceData, meta interface{}) err
dbInput.TargetDatabase = expandGlueDatabaseTargetDatabase(v.([]interface{})[0].(map[string]interface{}))
}

if v, ok := d.GetOk("create_table_default_permission"); ok && len(v.([]interface{})) > 0 {
dbInput.CreateTableDefaultPermissions = expandGlueDatabasePrincipalPermissions(v.([]interface{}))
}

input := &glue.CreateDatabaseInput{
CatalogId: aws.String(catalogID),
DatabaseInput: dbInput,
Expand Down Expand Up @@ -152,12 +187,14 @@ func resourceCatalogDatabaseUpdate(d *schema.ResourceData, meta interface{}) err
dbInput.Parameters = flex.ExpandStringMap(v.(map[string]interface{}))
}

if v, ok := d.GetOk("create_table_default_permission"); ok && len(v.([]interface{})) > 0 {
dbInput.CreateTableDefaultPermissions = expandGlueDatabasePrincipalPermissions(v.([]interface{}))
}

dbUpdateInput.DatabaseInput = dbInput

if d.HasChanges("description", "location_uri", "parameters") {
if _, err := conn.UpdateDatabase(dbUpdateInput); err != nil {
return err
}
if _, err := conn.UpdateDatabase(dbUpdateInput); err != nil {
return err
}

return resourceCatalogDatabaseRead(d, meta)
Expand Down Expand Up @@ -211,6 +248,10 @@ func resourceCatalogDatabaseRead(d *schema.ResourceData, meta interface{}) error
d.Set("target_database", nil)
}

if err := d.Set("create_table_default_permission", flattenGlueDatabasePrincipalPermissions(database.CreateTableDefaultPermissions)); err != nil {
return fmt.Errorf("error setting create_table_default_permission: %w", err)
}

return nil
}

Expand Down Expand Up @@ -280,3 +321,111 @@ func flattenGlueDatabaseTargetDatabase(apiObject *glue.DatabaseIdentifier) map[s

return tfMap
}

func expandGlueDatabasePrincipalPermissions(tfList []interface{}) []*glue.PrincipalPermissions {
if len(tfList) == 0 {
return nil
}

var apiObjects []*glue.PrincipalPermissions

for _, tfMapRaw := range tfList {
tfMap, ok := tfMapRaw.(map[string]interface{})

if !ok {
continue
}

apiObject := expandGlueDatabasePrincipalPermission(tfMap)

if apiObject == nil {
continue
}

apiObjects = append(apiObjects, apiObject)
}

return apiObjects
}

func expandGlueDatabasePrincipalPermission(tfMap map[string]interface{}) *glue.PrincipalPermissions {
if tfMap == nil {
return nil
}

apiObject := &glue.PrincipalPermissions{}

if v, ok := tfMap["permissions"].(*schema.Set); ok && v.Len() > 0 {
apiObject.Permissions = flex.ExpandStringSet(v)
}

if v, ok := tfMap["principal"].([]interface{}); ok && len(v) > 0 {
apiObject.Principal = expandGlueDatabasePrincipal(v[0].(map[string]interface{}))
}

return apiObject
}

func expandGlueDatabasePrincipal(tfMap map[string]interface{}) *glue.DataLakePrincipal {
if tfMap == nil {
return nil
}

apiObject := &glue.DataLakePrincipal{}

if v, ok := tfMap["data_lake_principal_identifier"].(string); ok && v != "" {
apiObject.DataLakePrincipalIdentifier = aws.String(v)
}

return apiObject
}

func flattenGlueDatabasePrincipalPermissions(apiObjects []*glue.PrincipalPermissions) []interface{} {
if len(apiObjects) == 0 {
return nil
}

var tfList []interface{}

for _, apiObject := range apiObjects {
if apiObject == nil {
continue
}

tfList = append(tfList, flattenGlueDatabasePrincipalPermission(apiObject))
}

return tfList
}

func flattenGlueDatabasePrincipalPermission(apiObject *glue.PrincipalPermissions) map[string]interface{} {
if apiObject == nil {
return nil
}

tfMap := map[string]interface{}{}

if v := apiObject.Permissions; v != nil {
tfMap["permissions"] = flex.FlattenStringSet(v)
}

if v := apiObject.Principal; v != nil {
tfMap["principal"] = []interface{}{flattenGlueDatabasePrincipal(v)}
}

return tfMap
}

func flattenGlueDatabasePrincipal(apiObject *glue.DataLakePrincipal) map[string]interface{} {
if apiObject == nil {
return nil
}

tfMap := map[string]interface{}{}

if v := apiObject.DataLakePrincipalIdentifier; v != nil {
tfMap["data_lake_principal_identifier"] = aws.StringValue(v)
}

return tfMap
}
65 changes: 62 additions & 3 deletions internal/service/glue/catalog_database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestAccGlueCatalogDatabase_full(t *testing.T) {
{
Config: testAccGlueCatalogDatabase_basic(rName),
Destroy: false,
Check: resource.ComposeTestCheckFunc(
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckGlueCatalogDatabaseExists(resourceName),
acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "glue", fmt.Sprintf("database/%s", rName)),
resource.TestCheckResourceAttr(resourceName, "name", rName),
Expand All @@ -46,7 +46,7 @@ func TestAccGlueCatalogDatabase_full(t *testing.T) {
{
Config: testAccGlueCatalogDatabase_full(rName, "A test catalog from terraform"),
Destroy: false,
Check: resource.ComposeTestCheckFunc(
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckGlueCatalogDatabaseExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "description", "A test catalog from terraform"),
resource.TestCheckResourceAttr(resourceName, "location_uri", "my-location"),
Expand All @@ -57,7 +57,7 @@ func TestAccGlueCatalogDatabase_full(t *testing.T) {
},
{
Config: testAccGlueCatalogDatabase_full(rName, "An updated test catalog from terraform"),
Check: resource.ComposeTestCheckFunc(
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckGlueCatalogDatabaseExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "description", "An updated test catalog from terraform"),
resource.TestCheckResourceAttr(resourceName, "location_uri", "my-location"),
Expand All @@ -70,6 +70,49 @@ func TestAccGlueCatalogDatabase_full(t *testing.T) {
})
}

func TestAccGlueCatalogDatabase_createTablePermission(t *testing.T) {
resourceName := "aws_glue_catalog_database.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, glue.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckGlueDatabaseDestroy,
Steps: []resource.TestStep{
{
Config: testAccGlueCatalogDatabasePermissionConfig(rName, "ALTER"),
Destroy: false,
Check: resource.ComposeTestCheckFunc(
testAccCheckGlueCatalogDatabaseExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "create_table_default_permission.#", "1"),
resource.TestCheckResourceAttr(resourceName, "create_table_default_permission.0.permissions.#", "1"),
resource.TestCheckTypeSetElemAttr(resourceName, "create_table_default_permission.0.permissions.*", "ALTER"),
resource.TestCheckResourceAttr(resourceName, "create_table_default_permission.0.principal.#", "1"),
resource.TestCheckResourceAttr(resourceName, "create_table_default_permission.0.principal.0.data_lake_principal_identifier", "IAM_ALLOWED_PRINCIPALS"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccGlueCatalogDatabasePermissionConfig(rName, "SELECT"),
Destroy: false,
Check: resource.ComposeTestCheckFunc(
testAccCheckGlueCatalogDatabaseExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "create_table_default_permission.#", "1"),
resource.TestCheckResourceAttr(resourceName, "create_table_default_permission.0.permissions.#", "1"),
resource.TestCheckTypeSetElemAttr(resourceName, "create_table_default_permission.0.permissions.*", "SELECT"),
resource.TestCheckResourceAttr(resourceName, "create_table_default_permission.0.principal.#", "1"),
resource.TestCheckResourceAttr(resourceName, "create_table_default_permission.0.principal.0.data_lake_principal_identifier", "IAM_ALLOWED_PRINCIPALS"),
),
},
},
})
}

func TestAccGlueCatalogDatabase_targetDatabase(t *testing.T) {
resourceName := "aws_glue_catalog_database.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
Expand Down Expand Up @@ -220,6 +263,22 @@ resource "aws_glue_catalog_database" "test2" {
`, rName)
}

func testAccGlueCatalogDatabasePermissionConfig(rName, permission string) string {
return fmt.Sprintf(`
resource "aws_glue_catalog_database" "test" {
name = %[1]q

create_table_default_permission {
permissions = [%[2]q]

principal {
data_lake_principal_identifier = "IAM_ALLOWED_PRINCIPALS"
}
}
}
`, rName, permission)
}

func testAccCheckGlueCatalogDatabaseExists(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[name]
Expand Down
26 changes: 26 additions & 0 deletions website/docs/r/glue_catalog_database.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,28 @@ resource "aws_glue_catalog_database" "aws_glue_catalog_database" {
}
```

### Create Table Default Permissions

```terraform
resource "aws_glue_catalog_database" "aws_glue_catalog_database" {
name = "MyCatalogDatabase"

create_table_default_permission {
permissions = ["SELECT"]

principal {
data_lake_principal_identifier = "IAM_ALLOWED_PRINCIPALS"
}
}
}
```

## Argument Reference

The following arguments are supported:

* `catalog_id` - (Optional) ID of the Glue Catalog to create the database in. If omitted, this defaults to the AWS Account ID.
* `create_table_default_permission` - (Optional) Creates a set of default permissions on the table for principals. See [`create_table_default_permission`](#create_table_default_permission) below.
* `description` - (Optional) Description of the database.
* `location_uri` - (Optional) Location of the database (for example, an HDFS path).
* `name` - (Required) Name of the database. The acceptable characters are lowercase letters, numbers, and the underscore character.
Expand All @@ -34,6 +51,15 @@ The following arguments are supported:
* `catalog_id` - (Required) ID of the Data Catalog in which the database resides.
* `database_name` - (Required) Name of the catalog database.

### create_table_default_permission

* `permissions` - (Optional) The permissions that are granted to the principal.
* `principal` - (Optional) The principal who is granted permissions.. See [`principal`](#principal) below.

#### principal

* `data_lake_principal_identifier` - (Optional) An identifier for the Lake Formation principal.

## Attributes Reference

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