Skip to content

Commit 12c2687

Browse files
authored
chore: migrate role api (#34)
* chore: migrate role api * chore: improvement * chore: update tests * chore: update examples * chore: update validation * chore: update diags * fix: lint
1 parent 2300a83 commit 12c2687

14 files changed

+494
-123
lines changed

api/client.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ type Client interface {
3636

3737
// Role
3838
// CreateRole creates the role in the instance.
39-
CreateRole(ctx context.Context, instanceID int, create *RoleUpsert) (*Role, error)
39+
CreateRole(ctx context.Context, environmentID, instanceID string, create *RoleUpsert) (*Role, error)
4040
// GetRole gets the role by instance id and role name.
41-
GetRole(ctx context.Context, instanceID int, roleName string) (*Role, error)
41+
GetRole(ctx context.Context, environmentID, instanceID, roleName string) (*Role, error)
4242
// ListRole lists the role in instance.
43-
ListRole(ctx context.Context, instanceID int) ([]*Role, error)
43+
ListRole(ctx context.Context, environmentID, instanceID string) ([]*Role, error)
4444
// UpdateRole updates the role in instance.
45-
UpdateRole(ctx context.Context, instanceID int, roleName string, patch *RoleUpsert) (*Role, error)
45+
UpdateRole(ctx context.Context, environmentID, instanceID, roleName string, patch *RoleUpsert) (*Role, error)
4646
// DeleteRole deletes the role in the instance.
47-
DeleteRole(ctx context.Context, instanceID int, roleName string) error
47+
DeleteRole(ctx context.Context, environmentID, instanceID, roleName string) error
4848
}

api/database_role.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ type RoleAttribute struct {
1414
// Role is the API message for role.
1515
type Role struct {
1616
Name string `json:"name"`
17-
InstanceID int `json:"instanceId"`
17+
Title string `json:"title"`
1818
ConnectionLimit int `json:"connectionLimit"`
1919
ValidUntil *string `json:"validUntil"`
2020
Attribute *RoleAttribute `json:"attribute"`
2121
}
2222

2323
// RoleUpsert is the API message for upserting a new role.
2424
type RoleUpsert struct {
25-
Name string `json:"name"`
25+
Title string `json:"title"`
2626
Password *string `json:"password"`
2727
ConnectionLimit *int `json:"connectionLimit"`
2828
ValidUntil *string `json:"validUntil"`

client/database_role.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import (
1111
)
1212

1313
// CreateRole creates the role in the instance.
14-
func (c *client) CreateRole(ctx context.Context, instanceID int, create *api.RoleUpsert) (*api.Role, error) {
14+
func (c *client) CreateRole(ctx context.Context, environmentID, instanceID string, create *api.RoleUpsert) (*api.Role, error) {
1515
payload, err := json.Marshal(create)
1616
if err != nil {
1717
return nil, err
1818
}
1919

20-
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s/instance/%d/role", c.HostURL, instanceID), strings.NewReader(string(payload)))
20+
req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s/environments/%s/instances/%s/roles", c.HostURL, environmentID, instanceID), strings.NewReader(string(payload)))
2121
if err != nil {
2222
return nil, err
2323
}
@@ -37,8 +37,8 @@ func (c *client) CreateRole(ctx context.Context, instanceID int, create *api.Rol
3737
}
3838

3939
// GetRole gets the role by instance id and role name.
40-
func (c *client) GetRole(ctx context.Context, instanceID int, roleName string) (*api.Role, error) {
41-
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s/instance/%d/role/%s", c.HostURL, instanceID, roleName), nil)
40+
func (c *client) GetRole(ctx context.Context, environmentID, instanceID, roleName string) (*api.Role, error) {
41+
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s/environments/%s/instances/%s/roles/%s", c.HostURL, environmentID, instanceID, roleName), nil)
4242
if err != nil {
4343
return nil, err
4444
}
@@ -58,8 +58,8 @@ func (c *client) GetRole(ctx context.Context, instanceID int, roleName string) (
5858
}
5959

6060
// ListRole lists the role in instance.
61-
func (c *client) ListRole(ctx context.Context, instanceID int) ([]*api.Role, error) {
62-
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s/instance/%d/role", c.HostURL, instanceID), nil)
61+
func (c *client) ListRole(ctx context.Context, environmentID, instanceID string) ([]*api.Role, error) {
62+
req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s/environments/%s/instances/%s/roles", c.HostURL, environmentID, instanceID), nil)
6363
if err != nil {
6464
return nil, err
6565
}
@@ -82,13 +82,30 @@ func (c *client) ListRole(ctx context.Context, instanceID int) ([]*api.Role, err
8282
}
8383

8484
// UpdateRole updates the role in instance.
85-
func (c *client) UpdateRole(ctx context.Context, instanceID int, roleName string, patch *api.RoleUpsert) (*api.Role, error) {
85+
func (c *client) UpdateRole(ctx context.Context, environmentID, instanceID, roleName string, patch *api.RoleUpsert) (*api.Role, error) {
8686
payload, err := json.Marshal(patch)
8787
if err != nil {
8888
return nil, err
8989
}
9090

91-
req, err := http.NewRequestWithContext(ctx, "PATCH", fmt.Sprintf("%s/instance/%d/role/%s", c.HostURL, instanceID, roleName), strings.NewReader(string(payload)))
91+
paths := []string{}
92+
if patch.Title != roleName {
93+
paths = append(paths, "role.title")
94+
}
95+
if patch.Password != nil {
96+
paths = append(paths, "role.password")
97+
}
98+
if patch.ConnectionLimit != nil {
99+
paths = append(paths, "role.connection_limit")
100+
}
101+
if patch.ValidUntil != nil {
102+
paths = append(paths, "role.valid_until")
103+
}
104+
if patch.Attribute != nil {
105+
paths = append(paths, "role.attribute")
106+
}
107+
108+
req, err := http.NewRequestWithContext(ctx, "PATCH", fmt.Sprintf("%s/environments/%s/instances/%s/roles/%s?update_mask=%s", c.HostURL, environmentID, instanceID, roleName, strings.Join(paths, ",")), strings.NewReader(string(payload)))
92109
if err != nil {
93110
return nil, err
94111
}
@@ -108,8 +125,8 @@ func (c *client) UpdateRole(ctx context.Context, instanceID int, roleName string
108125
}
109126

110127
// DeleteRole deletes the role in the instance.
111-
func (c *client) DeleteRole(ctx context.Context, instanceID int, roleName string) error {
112-
req, err := http.NewRequestWithContext(ctx, "DELETE", fmt.Sprintf("%s/instance/%d/role/%s", c.HostURL, instanceID, roleName), nil)
128+
func (c *client) DeleteRole(ctx context.Context, environmentID, instanceID, roleName string) error {
129+
req, err := http.NewRequestWithContext(ctx, "DELETE", fmt.Sprintf("%s/environments/%s/instances/%s/roles/%s", c.HostURL, environmentID, instanceID, roleName), nil)
113130
if err != nil {
114131
return err
115132
}

examples/instances/main.tf

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ locals {
2929
data "bytebase_instance_list" "all" {}
3030

3131
output "all_instances" {
32-
value = data.bytebase_instance_list.all.instances
32+
value = data.bytebase_instance_list.all
3333
}
3434

3535
# List all instances in dev environment
@@ -57,7 +57,6 @@ data "bytebase_instance" "prod" {
5757
environment = local.environment_id_prod
5858
}
5959

60-
6160
output "prod_instance" {
6261
value = data.bytebase_instance.prod
6362
}

examples/role/main.tf

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,22 @@ provider "bytebase" {
1818
}
1919

2020
locals {
21-
role_name_dev = "dev_role_test"
22-
instance_name_dev = "dev_instance_test"
21+
role_name_dev = "dev_role_test"
22+
instance_id_dev = "dev-instance"
23+
environment_id_dev = "dev"
2324
}
2425

2526
# Find the instance
2627
data "bytebase_instance" "dev" {
27-
name = local.instance_name_dev
28+
resource_id = local.instance_id_dev
29+
environment = local.environment_id_dev
2830
}
2931

3032
# Find the role "dev_role_test" in the instance "dev_instance_test"
3133
data "bytebase_database_role" "dev" {
32-
name = local.role_name_dev
33-
instance = data.bytebase_instance.dev.name
34+
name = local.role_name_dev
35+
instance = data.bytebase_instance.dev.resource_id
36+
environment = data.bytebase_instance.dev.environment
3437
}
3538

3639
output "dev_role" {
@@ -39,7 +42,8 @@ output "dev_role" {
3942

4043
# List all roles in the instance "dev_instance_test"
4144
data "bytebase_database_role_list" "all" {
42-
instance = data.bytebase_instance.dev.name
45+
instance = data.bytebase_instance.dev.resource_id
46+
environment = data.bytebase_instance.dev.environment
4347
}
4448

4549
output "list_role" {

examples/setup/main.tf

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ resource "bytebase_instance" "prod" {
9191

9292
# Create a new role named "dev_role_test" in the instance "dev_instance_test"
9393
resource "bytebase_database_role" "dev" {
94-
name = local.role_name_dev
95-
instance = bytebase_instance.dev.name
94+
name = local.role_name_dev
95+
instance = bytebase_instance.dev.resource_id
96+
environment = bytebase_instance.dev.environment
97+
9698
password = "123456"
9799
connection_limit = 10
98100
valid_until = "2022-12-31T00:00:00+08:00"

provider/data_source_database_role.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,31 @@ import (
88
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
99

1010
"github.com/bytebase/terraform-provider-bytebase/api"
11+
"github.com/bytebase/terraform-provider-bytebase/provider/internal"
1112
)
1213

1314
func dataSourceDatabaseRole() *schema.Resource {
1415
return &schema.Resource{
1516
Description: "The database role data source.",
1617
ReadContext: dataSourceRoleRead,
1718
Schema: map[string]*schema.Schema{
18-
"id": {
19-
Type: schema.TypeString,
20-
Computed: true,
21-
Description: "The database role id.",
22-
},
2319
"name": {
2420
Type: schema.TypeString,
2521
Required: true,
2622
Description: "The role unique name.",
2723
ValidateFunc: validation.StringIsNotEmpty,
2824
},
25+
"environment": {
26+
Type: schema.TypeString,
27+
Required: true,
28+
Description: "The environment resource id.",
29+
ValidateFunc: internal.ResourceIDValidation,
30+
},
2931
"instance": {
3032
Type: schema.TypeString,
3133
Required: true,
32-
Description: "The instance unique name.",
33-
ValidateFunc: validation.StringIsNotEmpty,
34+
Description: "The instance resource id.",
35+
ValidateFunc: internal.ResourceIDValidation,
3436
},
3537
"connection_limit": {
3638
Type: schema.TypeInt,
@@ -92,14 +94,12 @@ func dataSourceDatabaseRole() *schema.Resource {
9294

9395
func dataSourceRoleRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
9496
c := m.(api.Client)
95-
roleName := d.Get("name").(string)
9697

97-
// TODO: migrate role api
98-
role, err := c.GetRole(ctx, 0, roleName)
98+
role, err := c.GetRole(ctx, d.Get("environment").(string), d.Get("instance").(string), d.Get("name").(string))
9999
if err != nil {
100100
return diag.FromErr(err)
101101
}
102102

103-
d.SetId(getRoleIdentifier(role))
103+
d.SetId(role.Name)
104104
return setRole(d, role)
105105
}

provider/data_source_database_role_list.go

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,37 @@ import (
1010
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1111

1212
"github.com/bytebase/terraform-provider-bytebase/api"
13+
"github.com/bytebase/terraform-provider-bytebase/provider/internal"
1314
)
1415

1516
func dataSourceDatabaseRoleList() *schema.Resource {
1617
return &schema.Resource{
1718
Description: "The database role data source list.",
1819
ReadContext: dataSourceRoleListRead,
1920
Schema: map[string]*schema.Schema{
21+
"environment": {
22+
Type: schema.TypeString,
23+
Required: true,
24+
Description: "The environment resource id.",
25+
ValidateFunc: internal.ResourceIDValidation,
26+
},
2027
"instance": {
2128
Type: schema.TypeString,
2229
Required: true,
23-
Description: "The instance unique name.",
24-
ValidateFunc: validation.StringIsNotEmpty,
30+
Description: "The instance resource id.",
31+
ValidateFunc: internal.ResourceIDValidation,
2532
},
2633
"roles": {
2734
Type: schema.TypeList,
2835
Computed: true,
2936
Elem: &schema.Resource{
3037
Schema: map[string]*schema.Schema{
31-
"id": {
32-
Type: schema.TypeString,
33-
Computed: true,
34-
Description: "The database role id.",
35-
},
3638
"name": {
3739
Type: schema.TypeString,
3840
Required: true,
3941
Description: "The role unique name.",
4042
ValidateFunc: validation.StringIsNotEmpty,
4143
},
42-
"instance": {
43-
Type: schema.TypeString,
44-
Required: true,
45-
Description: "The instance unique name.",
46-
ValidateFunc: validation.StringIsNotEmpty,
47-
},
4844
"connection_limit": {
4945
Type: schema.TypeInt,
5046
Computed: true,
@@ -109,20 +105,23 @@ func dataSourceDatabaseRoleList() *schema.Resource {
109105
func dataSourceRoleListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
110106
c := m.(api.Client)
111107

112-
instanceName := d.Get("instance").(string)
108+
instanceID := d.Get("instance").(string)
109+
environmentID := d.Get("environment").(string)
113110

114-
// TODO: migrate role api
115-
roleList, err := c.ListRole(ctx, 0)
111+
roleList, err := c.ListRole(ctx, environmentID, instanceID)
116112
if err != nil {
117113
return diag.FromErr(err)
118114
}
119115

120116
roles := []map[string]interface{}{}
121117
for _, raw := range roleList {
118+
_, _, roleName, err := internal.GetEnvironmentInstanceRoleID(raw.Name)
119+
if err != nil {
120+
return diag.FromErr(err)
121+
}
122+
122123
role := make(map[string]interface{})
123-
role["id"] = getRoleIdentifier(raw)
124-
role["name"] = raw.Name
125-
role["instance"] = instanceName
124+
role["name"] = roleName
126125
role["connection_limit"] = raw.ConnectionLimit
127126
role["valid_until"] = raw.ValidUntil
128127

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package provider
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
9+
"github.com/bytebase/terraform-provider-bytebase/provider/internal"
10+
)
11+
12+
func TestAccDatabaseRoleListDataSource(t *testing.T) {
13+
instanceName := "test-instance"
14+
roleName := "test_role"
15+
outputName := "role_list"
16+
resourceName := fmt.Sprintf("data.bytebase_database_role_list.%s", outputName)
17+
18+
resource.Test(t, resource.TestCase{
19+
PreCheck: func() {
20+
testAccPreCheck(t)
21+
},
22+
Providers: testAccProviders,
23+
CheckDestroy: testAccCheckRoleDestroy,
24+
Steps: []resource.TestStep{
25+
{
26+
Config: fmt.Sprintf(`
27+
%s
28+
29+
data "bytebase_database_role_list" "%s" {
30+
instance = bytebase_instance.%s.resource_id
31+
environment = bytebase_instance.%s.environment
32+
}
33+
`, mockInstanceResource(instanceName), outputName, instanceName, instanceName),
34+
Check: resource.ComposeTestCheckFunc(
35+
internal.TestCheckResourceExists(resourceName),
36+
resource.TestCheckResourceAttr(resourceName, "roles.#", "0"),
37+
),
38+
},
39+
{
40+
Config: fmt.Sprintf(`
41+
%s
42+
43+
resource "bytebase_database_role" "%s" {
44+
name = "%s"
45+
instance = bytebase_instance.%s.resource_id
46+
environment = bytebase_instance.%s.environment
47+
48+
attribute {}
49+
}
50+
51+
data "bytebase_database_role_list" "%s" {
52+
instance = bytebase_instance.%s.resource_id
53+
environment = bytebase_instance.%s.environment
54+
55+
depends_on = [
56+
bytebase_database_role.%s
57+
]
58+
}
59+
`, mockInstanceResource(instanceName), roleName, roleName, instanceName, instanceName, outputName, instanceName, instanceName, roleName),
60+
Check: resource.ComposeTestCheckFunc(
61+
internal.TestCheckResourceExists(resourceName),
62+
resource.TestCheckResourceAttr(resourceName, "roles.#", "1"),
63+
resource.TestCheckResourceAttr(resourceName, "roles.0.name", roleName),
64+
resource.TestCheckResourceAttr(resourceName, "roles.0.connection_limit", "-1"),
65+
resource.TestCheckResourceAttr(resourceName, "roles.0.valid_until", ""),
66+
),
67+
},
68+
},
69+
})
70+
}

0 commit comments

Comments
 (0)