Skip to content

Commit 88590b3

Browse files
authored
Merge pull request #22 from karim-fc/feature/add-accesstoken-auth-option
Feature/add accesstoken auth option
2 parents 4c7bee4 + 355bf87 commit 88590b3

18 files changed

Lines changed: 671 additions & 328 deletions

docs/index.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,23 @@ provider "cloudsqlpostgresql" {
3333
<!-- schema generated by tfplugindocs -->
3434
## Schema
3535

36-
### Optional
36+
### Required
37+
38+
- `connection_configs` (Attributes Map) A map of connections of Postgresql database instances (see [below for nested schema](#nestedatt--connection_configs))
39+
40+
<a id="nestedatt--connection_configs"></a>
41+
### Nested Schema for `connection_configs`
42+
43+
Required:
3744

3845
- `connection_name` (String) The connection name of the Google Cloud SQL Postgresql instance. The `connection_name` format should be `<project>:<region>:<instance>`
3946
- `password` (String, Sensitive) The password to use to authenticate using the built-in database authentication
47+
- `username` (String) The username to use to authenticate with the Cloud SQL Postgresql instance
48+
49+
Optional:
50+
51+
- `database` (String) The database to connect to. Defaults to `postgres`.
4052
- `private_ip` (Boolean) Use the private IP address of the Cloud SQL Postgresql instance to connect to
4153
- `proxy` (String) Proxy socks url if used. Format needs to be `socks5://<ip>:<port>`
4254
- `psc` (Boolean) Use the Private Service Connect endpoint of the Cloud SQL Postgresql instance to connect to
4355
- `ssl_mode` (String) Determine the security of the connection to the Cloud SQL Postgresql instance
44-
- `username` (String) The username to use to authenticate with the Cloud SQL Postgresql instance

docs/resources/default_privileges.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ The `cloudsqlpostgresql_default_privileges` resource allows to set the privilege
1717

1818
### Required
1919

20-
- `database` (String) The database
20+
- `connection_config` (String) The key of the connection defined in the provider
2121
- `owner` (String) The target role
2222
- `privileges` (Attributes Set) A list of privileges (see [below for nested schema](#nestedatt--privileges))
2323
- `role` (String) The role

docs/resources/grant_database.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ resource "cloudsqlpostgresql_grant_database" "default" {
2929

3030
### Required
3131

32+
- `connection_config` (String) The key of the connection defined in the provider
3233
- `database` (String) The database on which the privileges will be granted for this role.
3334
- `privileges` (Attributes Set) A list of privileges to grant on the database for this role. (see [below for nested schema](#nestedatt--privileges))
3435
- `role` (String) The name of the role to grant privileges on the database. Can be username or role.

docs/resources/grant_role.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ The `cloudsqlpostgresql_grant_role` resource creates and manages role membership
1717

1818
### Required
1919

20+
- `connection_config` (String) The key of the connection defined in the provider
2021
- `group_role` (String) The `group_role` that will get the `role` as member
2122
- `role` (String) The `role` that will be a member of the `group_role`
2223

docs/resources/grant_schema.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ resource "cloudsqlpostgresql_grant_database" "default" {
3030

3131
### Required
3232

33-
- `database` (String) The database where the schema resides.
33+
- `connection_config` (String) The key of the connection defined in the provider
3434
- `privileges` (Attributes Set) A list of privileges to grant on the schema for this role. (see [below for nested schema](#nestedatt--privileges))
3535
- `role` (String) The name of the role to grant privileges on the schema. Can be username or role.
3636
- `schema` (String) The schema on which the privileges will be granted for this role.

docs/resources/grant_table.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ resource "cloudsqlpostgresql_grant_table" "default" {
3434

3535
### Required
3636

37-
- `database` (String) The database where the table resides.
37+
- `connection_config` (String) The key of the connection defined in the provider
3838
- `privileges` (Attributes Set) A list of privileges to grant on the table for this role. (see [below for nested schema](#nestedatt--privileges))
3939
- `role` (String) The name of the role to grant privileges on the table. Can be username or role.
4040
- `schema` (String) The schema where the table resides.

docs/resources/role.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ The `cloudsqlpostgresql_role` resource creates and manages a role. The superuser
1717

1818
### Required
1919

20+
- `connection_config` (String) The key of the connection defined in the provider
2021
- `name` (String) The name of the role
2122

2223
### Optional

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/hashicorp/terraform-plugin-go v0.22.1
1111
github.com/hashicorp/terraform-plugin-log v0.9.0
1212
golang.org/x/net v0.24.0
13+
golang.org/x/oauth2 v0.18.0
1314
)
1415

1516
require (
@@ -83,7 +84,6 @@ require (
8384
golang.org/x/crypto v0.22.0 // indirect
8485
golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 // indirect
8586
golang.org/x/mod v0.15.0 // indirect
86-
golang.org/x/oauth2 v0.18.0 // indirect
8787
golang.org/x/sys v0.19.0 // indirect
8888
golang.org/x/text v0.14.0 // indirect
8989
golang.org/x/time v0.5.0 // indirect

internal/provider/config.go

Lines changed: 97 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,124 @@
11
package provider
22

33
import (
4+
"context"
45
"database/sql"
56
"fmt"
7+
"net"
8+
"net/url"
69
"sync"
10+
11+
"cloud.google.com/go/cloudsqlconn"
12+
"cloud.google.com/go/cloudsqlconn/postgres/pgxv4"
13+
"github.com/hashicorp/terraform-plugin-log/tflog"
14+
"golang.org/x/net/proxy"
15+
"golang.org/x/oauth2"
716
)
817

918
type Config struct {
10-
dsnTemplate string
1119
dbRegistry map[string]*sql.DB
1220
dbRegistryMutex sync.Mutex
21+
dbDrivers map[string]bool
22+
dbDriversMutex sync.Mutex
23+
connections map[string]*ConnectionConfig
1324
}
1425

15-
func NewConfig(dsnTemplate string) *Config {
26+
func NewConfig() *Config {
1627
return &Config{
17-
dsnTemplate: dsnTemplate,
1828
dbRegistry: make(map[string]*sql.DB),
29+
dbDrivers: make(map[string]bool),
30+
connections: make(map[string]*ConnectionConfig),
1931
}
2032
}
2133

22-
func (c *Config) connectToPostgresqlDb(dbName string) (*sql.DB, error) {
23-
dsn := fmt.Sprintf(c.dsnTemplate, "dbname="+dbName)
24-
return c.connectToPostgresql(dsn)
25-
}
26-
27-
func (c *Config) connectToPostgresqlNoDb() (*sql.DB, error) {
28-
dsn := fmt.Sprintf(c.dsnTemplate, "dbname=postgres")
29-
return c.connectToPostgresql(dsn)
30-
}
31-
32-
func (c *Config) connectToPostgresql(dsn string) (*sql.DB, error) {
34+
func (c *Config) connectToPostgresql(ctx context.Context, cc *ConnectionConfig) (*sql.DB, error) {
3335
c.dbRegistryMutex.Lock()
3436
defer c.dbRegistryMutex.Unlock()
3537

36-
if c.dbRegistry[dsn] != nil {
37-
return c.dbRegistry[dsn], nil
38+
key := cc.DsnKey()
39+
40+
if c.dbRegistry[key] != nil {
41+
return c.dbRegistry[key], nil
42+
}
43+
44+
err := c.registerDriver(ctx, cc)
45+
if err != nil {
46+
return nil, err
3847
}
3948

40-
db, err := sql.Open("cloudsql-postgres", dsn)
49+
db, err := sql.Open(cc.DriverKey(), cc.Dsn())
4150
if err != nil {
4251
return nil, err
4352
}
44-
c.dbRegistry[dsn] = db
45-
return c.dbRegistry[dsn], nil
53+
54+
c.dbRegistry[key] = db
55+
return c.dbRegistry[key], nil
56+
}
57+
58+
func (c *Config) registerDriver(ctx context.Context, cc *ConnectionConfig) error {
59+
c.dbDriversMutex.Lock()
60+
defer c.dbDriversMutex.Unlock()
61+
62+
key := cc.DriverKey()
63+
64+
if c.dbDrivers[key] {
65+
return nil
66+
}
67+
68+
var (
69+
dialOptions []cloudsqlconn.DialOption
70+
options []cloudsqlconn.Option
71+
)
72+
73+
if cc.PrivateIP.ValueBool() {
74+
dialOptions = append(dialOptions, cloudsqlconn.WithPrivateIP())
75+
}
76+
77+
if cc.PSC.ValueBool() {
78+
dialOptions = append(dialOptions, cloudsqlconn.WithPSC())
79+
}
80+
81+
options = append(options, cloudsqlconn.WithDefaultDialOptions(dialOptions...))
82+
83+
if cc.GoogleApiAccessToken.ValueString() != "" {
84+
token := &oauth2.Token{AccessToken: cc.GoogleApiAccessToken.ValueString()}
85+
options = append(options, cloudsqlconn.WithTokenSource(oauth2.StaticTokenSource(token)))
86+
}
87+
88+
if !cc.Proxy.IsNull() {
89+
options = append(options, cloudsqlconn.WithDialFunc(createDialer(cc.Proxy.ValueString(), ctx)))
90+
}
91+
92+
_, err := pgxv4.RegisterDriver(key, options...)
93+
if err != nil {
94+
return err
95+
}
96+
97+
c.dbDrivers[key] = true
98+
return nil
99+
}
100+
101+
func createDialer(proxyInput string, ctxProvider context.Context) func(ctx context.Context, network, addr string) (net.Conn, error) {
102+
return func(ctx context.Context, network, address string) (net.Conn, error) {
103+
tflog.Info(ctxProvider, "Creating Dialer with proxy: "+proxyInput)
104+
if len(proxyInput) == 0 {
105+
return nil, fmt.Errorf("proxy is empty")
106+
}
107+
108+
proxyURL, err := url.Parse(proxyInput)
109+
if err != nil {
110+
return nil, err
111+
}
112+
d, err := proxy.FromURL(proxyURL, proxy.Direct)
113+
if err != nil {
114+
return nil, err
115+
}
116+
117+
if xd, ok := d.(proxy.ContextDialer); ok {
118+
return xd.DialContext(ctx, network, address)
119+
}
120+
121+
tflog.Warn(ctxProvider, "net.Conn created without context.Context")
122+
return d.Dial(network, address) // TODO: force use of context?
123+
}
46124
}

0 commit comments

Comments
 (0)