Skip to content

Commit

Permalink
GCP wrapper (#83)
Browse files Browse the repository at this point in the history
* GCP wrapper

Add a GCP wrapper to work on Google SQL instances

* PR fixes

mod doc to readme and query to const
  • Loading branch information
aroundthecode authored Apr 6, 2022
1 parent 57dc133 commit 2297402
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ unit-test:
go tool cover -func coverage.out
unit-test-coverage: unit-test
go tool cover -html coverage.out
linux-build:
@GOBIN=/work/bin GO111MODULE=on GOOS=linux GOARC=x86_64 go build --mod=vendor -o operator github.com/movetokube/postgres-operator/cmd/manager
docker-build:
docker run -ti -v $(PWD):/work -w /work golang:1.13.15-stretch make linux-build
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ In order for this operator to work correctly with Azure managed PostgreSQL datab
* `POSTGRES_CLOUD_PROVIDER` set to `Azure`
* `POSTGRES_DEFAULT_DATABASE` set to your default database, i.e. `postgres`

### GCP

In order for this operator to work correctly with GCP, you need to set `POSTGRES_CLOUD_PROVIDER` to `GCP`

To have operator work with GCP properly you have to:
* use postgresql connection in secret
* manually create a Master role e.g. "devops-operators"
* use such role in database CR e.g. spec.masterRole: devops-operator

DropRole method will check for db owner and will skip master role dropping

## Installation

This operator requires a Kubernetes Secret to be created in the same namespace as operator itself.
Expand Down
3 changes: 3 additions & 0 deletions pkg/postgres/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ const (
GRANT_USAGE_SCHEMA = `GRANT USAGE ON SCHEMA "%s" TO "%s"`
GRANT_ALL_TABLES = `GRANT %s ON ALL TABLES IN SCHEMA "%s" TO "%s"`
DEFAULT_PRIVS_SCHEMA = `ALTER DEFAULT PRIVILEGES FOR ROLE "%s" IN SCHEMA "%s" GRANT %s ON TABLES TO "%s"`
REVOKE_CONNECT = `REVOKE CONNECT ON DATABASE "%s" FROM public`
TERMINATE_BACKEND = `SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = "%s" AND pid <> pg_backend_pid()`
GET_DB_OWNER = `SELECT pg_catalog.pg_get_userbyid(d.datdba) FROM pg_catalog.pg_database d WHERE d.datname = "%s"`
GRANT_CREATE_SCHEMA = `GRANT CREATE ON DATABASE "%s" TO "%s"`
)

Expand Down
85 changes: 85 additions & 0 deletions pkg/postgres/gcp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package postgres

import (
"fmt"

"github.com/go-logr/logr"
"github.com/lib/pq"
)

type gcppg struct {
pg
}

func newGCPPG(postgres *pg) PG {
return &gcppg{
*postgres,
}
}

func (c *gcppg) DropDatabase(database string, logger logr.Logger) error {

_, err := c.db.Exec(fmt.Sprintf(REVOKE_CONNECT, database))
// Error code 3D000 is returned if database doesn't exist
if err != nil && err.(*pq.Error).Code != "3D000" {
return err
}

_, err = c.db.Exec(fmt.Sprintf(TERMINATE_BACKEND, database))
// Error code 3D000 is returned if database doesn't exist
if err != nil && err.(*pq.Error).Code != "3D000" {
return err
}
_, err = c.db.Exec(fmt.Sprintf(DROP_DATABASE, database))
// Error code 3D000 is returned if database doesn't exist
if err != nil && err.(*pq.Error).Code != "3D000" {
return err
}

logger.Info(fmt.Sprintf("Dropped database %s", database))

return nil
}

func (c *gcppg) CreateDB(dbname, role string) error {

err := c.GrantRole(role, c.user)
if err != nil {
return err
}
err = c.pg.CreateDB(dbname, role)
if err != nil {
return err
}
return nil
}

func (c *gcppg) DropRole(role, newOwner, database string, logger logr.Logger) error {

tmpDb, err := GetConnection(c.user, c.pass, c.host, database, c.args, logger)
q := fmt.Sprintf(GET_DB_OWNER, database)
logger.Info("Checking master role: "+ q)
rows, err := tmpDb.Query(q)
if err != nil {
return err
}
var masterRole string
for rows.Next() {
rows.Scan(&masterRole)
}

if( role != masterRole){
q = fmt.Sprintf(DROP_ROLE, role)
logger.Info("GCP Drop Role: "+ q)
_, err = tmpDb.Exec(q)
// Check if error exists and if different from "ROLE NOT FOUND" => 42704
if err != nil && err.(*pq.Error).Code != "42704" {
return err
}

defer tmpDb.Close()
} else {
logger.Info(fmt.Sprintf("GCP refusing DropRole on master role " + masterRole))
}
return nil
}
6 changes: 6 additions & 0 deletions pkg/postgres/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,16 @@ func NewPG(host, user, password, uri_args, default_database, cloud_type string,

switch cloud_type {
case "AWS":
logger.Info("Using AWS wrapper")
return newAWSPG(postgres), nil
case "Azure":
logger.Info("Using Azure wrapper")
return newAzurePG(postgres), nil
case "GCP":
logger.Info("Using GCP wrapper")
return newGCPPG(postgres), nil
default:
logger.Info("Using default postgres implementation")
return postgres, nil
}
}
Expand Down

0 comments on commit 2297402

Please sign in to comment.