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

GCP wrapper #83

Merged
merged 3 commits into from
Apr 6, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions pkg/postgres/gcp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package postgres

/*
To have operator work with GCP you have
aroundthecode marked this conversation as resolved.
Show resolved Hide resolved
1) use postgresql connection in secret
2) manually create a Master role e.g. "devops-operators"
3) 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
*/
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 ON DATABASE \"%s\" FROM public;", 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("select pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '%s' AND pid <> pg_backend_pid();", 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))

aroundthecode marked this conversation as resolved.
Show resolved Hide resolved
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("SELECT pg_catalog.pg_get_userbyid(d.datdba) FROM pg_catalog.pg_database d WHERE d.datname = '%s';", database)
aroundthecode marked this conversation as resolved.
Show resolved Hide resolved
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){

aroundthecode marked this conversation as resolved.
Show resolved Hide resolved
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
}

aroundthecode marked this conversation as resolved.
Show resolved Hide resolved
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