Skip to content

Commit 18c0738

Browse files
authored
Merge pull request #40 from IvanOfThings/feat/roles-and-users
feat/roles and users
2 parents 97c9500 + 502b792 commit 18c0738

22 files changed

+1400
-14
lines changed

.github/workflows/test.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ jobs:
6666
services:
6767
clickhouse:
6868
image: clickhouse/clickhouse-server
69-
69+
70+
env:
71+
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: 1
7072
ports:
7173
- 8123:8123
7274
- 9090:9000

docs/resources/role.md

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "clickhouse_role Resource - terraform-provider-clickhouse"
4+
subcategory: ""
5+
description: |-
6+
Resource to manage Clickhouse roles
7+
---
8+
9+
# clickhouse_role (Resource)
10+
11+
Resource to manage Clickhouse roles
12+
13+
14+
15+
<!-- schema generated by tfplugindocs -->
16+
## Schema
17+
18+
### Required
19+
20+
- `database` (String) Database where to grant permissions to the user
21+
- `name` (String) Role name
22+
23+
### Optional
24+
25+
- `privileges` (Set of String) Granted privileges to the role. Privileges will be granted at DB level
26+
27+
### Read-Only
28+
29+
- `id` (String) The ID of this resource.
30+
31+

docs/resources/user.md

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "clickhouse_user Resource - terraform-provider-clickhouse"
4+
subcategory: ""
5+
description: |-
6+
Resource to manage Clickhouse users
7+
---
8+
9+
# clickhouse_user (Resource)
10+
11+
Resource to manage Clickhouse users
12+
13+
14+
15+
<!-- schema generated by tfplugindocs -->
16+
## Schema
17+
18+
### Required
19+
20+
- `name` (String) User name
21+
- `password` (String) User password
22+
23+
### Optional
24+
25+
- `roles` (Set of String) User role
26+
27+
### Read-Only
28+
29+
- `id` (String) The ID of this resource.
30+
31+

examples/resources/clickhouse_db/main.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ resource "clickhouse_db" "test_db" {
2323
// see: https://github.com/Altinity/clickhouse-operator/blob/master/docs/replication_setup.md
2424
resource "clickhouse_db" "test_db_clusterd" {
2525
name = "clustered_test_database"
26-
comment = "This is a culstered test database"
26+
comment = "This is a clustered test database"
2727
cluster = "'{cluster}'"
2828
}
2929

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
terraform {
2+
required_providers {
3+
clickhouse = {
4+
version = "2.0.0"
5+
source = "hashicorp.com/ivanofthings/clickhouse"
6+
}
7+
}
8+
}
9+
10+
provider "clickhouse" {
11+
port = 8123
12+
}
13+
14+
resource "clickhouse_db" "awesome_database" {
15+
name = "awesome_database"
16+
comment = "This is an awesome database"
17+
}
18+
19+
resource "clickhouse_role" "awesome_role" {
20+
name = "awesome_role"
21+
database = clickhouse_db.awesome_database.name
22+
privileges = ["INSERT"]
23+
}
24+
25+
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
terraform {
2+
required_providers {
3+
clickhouse = {
4+
version = "2.0.0"
5+
source = "hashicorp.com/ivanofthings/clickhouse"
6+
}
7+
}
8+
}
9+
10+
provider "clickhouse" {
11+
port = 8123
12+
}
13+
14+
resource "clickhouse_db" "awesome_database" {
15+
name = "awesome_database"
16+
comment = "This is an awesome database"
17+
}
18+
19+
resource "clickhouse_role" "awesome_role_1" {
20+
name = "awesome_role_1"
21+
database = clickhouse_db.awesome_database.name
22+
privileges = ["SELECT"]
23+
}
24+
25+
resource "clickhouse_role" "awesome_role_2" {
26+
name = "awesome_role_2"
27+
database = clickhouse_db.awesome_database.name
28+
privileges = ["INSERT"]
29+
}
30+
31+
resource "clickhouse_user" "awesome_user" {
32+
name = "awesome_user"
33+
password = "awesome_user_password"
34+
roles = [clickhouse_role.awesome_role_1.name, clickhouse_role.awesome_role_2.name]
35+
}
36+
37+

pkg/common/utils.go

+26
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package common
33
import (
44
"encoding/json"
55
"fmt"
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
67
"strconv"
78
"strings"
89

@@ -78,3 +79,28 @@ func GetClusterStatement(cluster string, defaultCluster string) (clusterStatemen
7879
}
7980
return clusterStatement, clusterToUse
8081
}
82+
83+
// Quote all strings on a string slice
84+
func Quote(elems []string) []string {
85+
var quotedElems []string
86+
for _, elem := range elems {
87+
quotedElems = append(quotedElems, fmt.Sprintf("%q", elem))
88+
}
89+
return quotedElems
90+
}
91+
92+
func StringSetToList(set *schema.Set) []string {
93+
var list []string
94+
for _, item := range set.List() {
95+
list = append(list, item.(string))
96+
}
97+
return list
98+
}
99+
100+
func StringListToSet(list []string) *schema.Set {
101+
var set []interface{}
102+
for _, item := range list {
103+
set = append(set, item)
104+
}
105+
return schema.NewSet(schema.HashString, set)
106+
}

pkg/provider/provider.go

+10-6
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"github.com/IvanOfThings/terraform-provider-clickhouse/pkg/resources/db"
8+
"github.com/IvanOfThings/terraform-provider-clickhouse/pkg/resources/role"
9+
"github.com/IvanOfThings/terraform-provider-clickhouse/pkg/resources/table"
10+
"github.com/IvanOfThings/terraform-provider-clickhouse/pkg/resources/user"
711
"net/url"
812
"os"
913

1014
"github.com/IvanOfThings/terraform-provider-clickhouse/pkg/common"
1115
"github.com/IvanOfThings/terraform-provider-clickhouse/pkg/datasources"
12-
"github.com/IvanOfThings/terraform-provider-clickhouse/pkg/resources"
1316
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1417
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1518
"github.com/joho/godotenv"
@@ -84,13 +87,14 @@ func New(version string) func() *schema.Provider {
8487
"clickhouse_dbs": datasources.DataSourceDbs(),
8588
},
8689
ResourcesMap: map[string]*schema.Resource{
87-
"clickhouse_db": resources.ResourceDb(),
88-
"clickhouse_table": resources.ResourceTable(),
90+
"clickhouse_db": resourcedb.ResourceDb(),
91+
"clickhouse_table": resourcetable.ResourceTable(),
92+
"clickhouse_role": resourcerole.ResourceRole(),
93+
"clickhouse_user": resourceuser.ResourceUser(),
8994
},
95+
ConfigureContextFunc: configure(),
9096
}
9197

92-
p.ConfigureContextFunc = configure(version, p)
93-
9498
return p
9599
}
96100
}
@@ -105,7 +109,7 @@ func getEnvVar(envVarName string) (any, error) {
105109

106110
}
107111

108-
func configure(version string, p *schema.Provider) func(context.Context, *schema.ResourceData) (any, diag.Diagnostics) {
112+
func configure() func(context.Context, *schema.ResourceData) (any, diag.Diagnostics) {
109113
return func(ctx context.Context, d *schema.ResourceData) (any, diag.Diagnostics) {
110114

111115
clickhouseUrl := d.Get("host").(string)

pkg/resources/resource_db.go renamed to pkg/resources/db/resource_db.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package resources
1+
package resourcedb
22

33
import (
44
"context"

pkg/resources/resource_db_acceptance_test.go renamed to pkg/resources/db/resource_db_acceptance_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package resources_test
1+
package resourcedb_test
22

33
import (
44
"fmt"

pkg/resources/role/model.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package resourcerole
2+
3+
import (
4+
"fmt"
5+
"github.com/IvanOfThings/terraform-provider-clickhouse/pkg/common"
6+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
7+
)
8+
9+
type CHGrant struct {
10+
RoleName string
11+
AccessType string
12+
Database string
13+
}
14+
15+
type CHRole struct {
16+
Name string
17+
Privileges []CHGrant
18+
}
19+
20+
type RoleResource struct {
21+
Name string
22+
Database string
23+
Privileges *schema.Set
24+
}
25+
26+
func (r *CHRole) ToRoleResource() (*RoleResource, error) {
27+
var database string
28+
var privileges []string
29+
for i := 0; i < len(r.Privileges); i++ {
30+
if database != "" && r.Privileges[i].Database != "" && r.Privileges[i].Database != database {
31+
return nil, fmt.Errorf("role %s has privileges on different databases", r.Name)
32+
}
33+
database = r.Privileges[i].Database
34+
privileges = append(privileges, r.Privileges[i].AccessType)
35+
}
36+
37+
return &RoleResource{Name: r.Name, Database: database, Privileges: common.StringListToSet(privileges)}, nil
38+
}
39+
40+
func (r *CHRole) GetPrivilegesList() []string {
41+
var privileges []string
42+
for _, privilege := range r.Privileges {
43+
privileges = append(privileges, privilege.AccessType)
44+
}
45+
return privileges
46+
}

0 commit comments

Comments
 (0)