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

feat(rdb): Adding privileges support #844

Merged
merged 10 commits into from
Jul 9, 2021
35 changes: 35 additions & 0 deletions docs/data-sources/rdb_privilege.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
layout: "scaleway"
page_title: "Scaleway: scaleway_rdb_privilege"
description: |-
Gets information about the privilege on a RDB database.
---

# scaleway_rdb_privilege

Gets information about the privilege on a RDB database.

## Example Usage

```hcl
# Get the database privilege for the user "my-user" on the database "my-database" hosted on instance id fr-par/11111111-1111-1111-1111-111111111111
data "scaleway_rdb_privilege" "find_priv" {
instance_id = "fr-par/11111111-1111-111111111111"
user_name = "my-user"
database_name = "my-database"
}
```

## Argument Reference

- `instance_id` - (Required) The RDB instance ID.

- `user_name` - (Required) The user name.

- `database_name` - (Required) The database name.

## Attributes Reference

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

- `permission` - The permission for this user on the database
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add valid values ? Valid values are readonly, readwrite, all, custom and none

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it's the data source: it's an exported value. Is it useful ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will be a different page on the website :) that's why it is useful to put it in both places

44 changes: 44 additions & 0 deletions docs/resources/rdb_privilege.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
page_title: "Scaleway: scaleway_rdb_privilege"
description: |-
Manages Scaleway RDB Database Privilege.
---

# scaleway_rdb_privilege

Create and manage Scaleway RDB database privilege.
For more information, see [the documentation](https://developers.scaleway.com/en/products/rdb/api).

## Example usage


```hcl
resource "scaleway_rdb_privilege" "priv" {
instance_id = scaleway_rdb_instance.rdb.id
user_name = "my-db-user"
database_name = "my-db-name"
permission = "all"
}
```

## Argument Reference

The following arguments are supported:

- `instance_id` - (Required) UUID of the instance where to create the database.

- `user_name` - (Required) Name of the user (e.g. `my-db-user`).

- `database_name` - (Required) Name of the database (e.g. `my-db-name`).

- `permission` - (Required) Permission to set. Valid values are `readonly`, `readwrite`, `all`, `custom` and `none`).

## Attributes Reference

- `instance_id` - See Argument Reference above.

- `user_name` - See Argument Reference above.

- `database_name` - See Argument Reference above.

- `permission` - See Argument Reference above.
27 changes: 27 additions & 0 deletions scaleway/data_source_rdb_privilege.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package scaleway

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceScalewayRDBPrivilege() *schema.Resource {
// Generate datasource schema from resource
dsSchema := datasourceSchemaFromResourceSchema(resourceScalewayRdbPrivilege().Schema)

fixDatasourceSchemaFlags(dsSchema, true, "instance_id", "user_name", "database_name")

return &schema.Resource{
ReadContext: dataSourceScalewayRDBPrivilegeRead,
Schema: dsSchema,
}
}

func dataSourceScalewayRDBPrivilegeRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
instanceID, _ := d.Get("instance_id").(string)

d.SetId(instanceID)
return resourceScalewayRdbPrivilegeRead(ctx, d, meta)
}
87 changes: 87 additions & 0 deletions scaleway/data_source_rdb_privilege_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package scaleway

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccScalewayDataSourceRdbPrivilege_Basic(t *testing.T) {
tt := NewTestTools(t)
defer tt.Cleanup()
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: testAccCheckScalewayRdbInstanceDestroy(tt),
Steps: []resource.TestStep{
{
Config: `
resource "scaleway_rdb_instance" "instance" {
name = "test-privilege"
node_type = "db-dev-s"
engine = "PostgreSQL-12"
is_ha_cluster = false
tags = [ "terraform-test", "scaleway_rdb_user", "minimal" ]
}
resource "scaleway_rdb_database" "db" {
instance_id = scaleway_rdb_instance.instance.id
name = "foo"
}
resource "scaleway_rdb_user" "foo" {
instance_id = scaleway_rdb_instance.instance.id
name = "foo"
password = "R34lP4sSw#Rd"
}
resource "scaleway_rdb_privilege" "priv" {
instance_id = scaleway_rdb_instance.instance.id
user_name = scaleway_rdb_user.foo.name
database_name = scaleway_rdb_database.db.name
permission = "all"
}`,
},
{
Config: `
resource "scaleway_rdb_instance" "instance" {
name = "test-privilege"
node_type = "db-dev-s"
engine = "PostgreSQL-12"
is_ha_cluster = false
tags = [ "terraform-test", "scaleway_rdb_user", "minimal" ]
}
resource "scaleway_rdb_database" "db" {
instance_id = scaleway_rdb_instance.instance.id
name = "foo"
}
resource "scaleway_rdb_user" "foo" {
instance_id = scaleway_rdb_instance.instance.id
name = "foo"
password = "R34lP4sSw#Rd"
}
resource "scaleway_rdb_privilege" "priv" {
instance_id = scaleway_rdb_instance.instance.id
user_name = scaleway_rdb_user.foo.name
database_name = scaleway_rdb_database.db.name
permission = "all"
}
data "scaleway_rdb_privilege" "find_priv" {
instance_id = scaleway_rdb_instance.instance.id
user_name = scaleway_rdb_user.foo.name
database_name = scaleway_rdb_database.db.name
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckRdbDatabaseExists(tt, "scaleway_rdb_instance.instance", "scaleway_rdb_database.db"),

resource.TestCheckResourceAttr("data.scaleway_rdb_privilege.find_priv", "permission", "all"),
),
},
},
})
}
2 changes: 2 additions & 0 deletions scaleway/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {
"scaleway_rdb_acl": resourceScalewayRdbACL(),
"scaleway_rdb_database": resourceScalewayRdbDatabase(),
"scaleway_rdb_instance": resourceScalewayRdbInstance(),
"scaleway_rdb_privilege": resourceScalewayRdbPrivilege(),
"scaleway_rdb_user": resourceScalewayRdbUser(),
"scaleway_object_bucket": resourceScalewayObjectBucket(),
"scaleway_vpc_private_network": resourceScalewayVPCPrivateNetwork(),
Expand All @@ -97,6 +98,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {
"scaleway_rdb_acl": dataSourceScalewayRDBACL(),
"scaleway_rdb_instance": dataSourceScalewayRDBInstance(),
"scaleway_rdb_database": dataSourceScalewayRDBDatabase(),
"scaleway_rdb_privilege": dataSourceScalewayRDBPrivilege(),
"scaleway_k8s_cluster": dataSourceScalewayK8SCluster(),
"scaleway_k8s_pool": dataSourceScalewayK8SPool(),
"scaleway_lb_ip": dataSourceScalewayLbIP(),
Expand Down
154 changes: 154 additions & 0 deletions scaleway/resource_rdb_privilege.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package scaleway

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/scaleway/scaleway-sdk-go/api/rdb/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
)

func resourceScalewayRdbPrivilege() *schema.Resource {
return &schema.Resource{
CreateContext: resourceScalewayRdbPrivilegeCreate,
ReadContext: resourceScalewayRdbPrivilegeRead,
DeleteContext: resourceScalewayRdbPrivilegeDelete,
UpdateContext: resourceScalewayRdbPrivilegeUpdate,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Timeouts: &schema.ResourceTimeout{
Default: schema.DefaultTimeout(defaultRdbInstanceTimeout),
},
SchemaVersion: 0,
Schema: map[string]*schema.Schema{
"instance_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validationUUIDorUUIDWithLocality(),
Description: "Instance on which the database is created",
},
"user_name": {
Type: schema.TypeString,
Description: "User name",
Required: true,
},
"database_name": {
Type: schema.TypeString,
Description: "Database name",
Required: true,
},
"permission": {
Type: schema.TypeString,
Description: "Privilege",
ValidateFunc: validationPrivilegePermission(),
Required: true,
},
},
}
}

func resourceScalewayRdbPrivilegeCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
rdbAPI := newRdbAPI(meta)

region, instanceID, err := parseRegionalID(d.Get("instance_id").(string))
if err != nil {
return diag.FromErr(err)
}

createReq := &rdb.SetPrivilegeRequest{
Region: region,
InstanceID: instanceID,
DatabaseName: d.Get("database_name").(string),
UserName: d.Get("user_name").(string),
Permission: rdb.Permission(d.Get("permission").(string)),
}

_, err = rdbAPI.SetPrivilege(createReq, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

d.SetId(newRegionalIDString(region, instanceID))
return resourceScalewayRdbPrivilegeRead(ctx, d, meta)
}

func resourceScalewayRdbPrivilegeRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
rdbAPI := newRdbAPI(meta)
region, instanceID, err := parseRegionalID(d.Get("instance_id").(string))
if err != nil {
return diag.FromErr(err)
}

dbName, _ := d.Get("database_name").(string)
userName, _ := d.Get("user_name").(string)

res, err := rdbAPI.ListPrivileges(&rdb.ListPrivilegesRequest{
Region: region,
InstanceID: instanceID,
DatabaseName: &dbName,
UserName: &userName,
}, scw.WithContext(ctx))

if err != nil {
if is404Error(err) {
d.SetId("")
return nil
}
return diag.FromErr(err)
}

var privilege = res.Privileges[0]
_ = d.Set("database_name", privilege.DatabaseName)
_ = d.Set("user_name", privilege.UserName)
_ = d.Set("permission", privilege.Permission)
_ = d.Set("instance_id", newRegionalIDString(region, instanceID))

return nil
}

func resourceScalewayRdbPrivilegeUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
rdbAPI := newRdbAPI(meta)
region, instanceID, err := parseRegionalID(d.Get("instance_id").(string))
if err != nil {
return diag.FromErr(err)
}

updateReq := &rdb.SetPrivilegeRequest{
Region: region,
InstanceID: instanceID,
DatabaseName: d.Get("database_name").(string),
UserName: d.Get("user_name").(string),
Permission: rdb.Permission(d.Get("permission").(string)),
}
_, err = rdbAPI.SetPrivilege(updateReq, scw.WithContext(ctx))
if err != nil && !is404Error(err) {
return diag.FromErr(err)
}

return nil
}

func resourceScalewayRdbPrivilegeDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
_ = d.Set("permission", rdb.PermissionNone)
return resourceScalewayRdbPrivilegeUpdate(ctx, d, meta)
}

func validationPrivilegePermission() func(interface{}, string) ([]string, []error) {
return func(v interface{}, key string) (warnings []string, errors []error) {
sV, isString := v.(string)
if isString {
perm := rdb.Permission(sV)

switch perm {
case rdb.PermissionReadonly, rdb.PermissionReadwrite, rdb.PermissionAll, rdb.PermissionCustom, rdb.PermissionNone:
return
}
return nil, []error{fmt.Errorf("'%s' is not a valid permission", key)}
}
return nil, []error{fmt.Errorf("'%s' is not a string", key)}
}
}
Loading