create dbs on cluster create
This commit is contained in:
parent
5cfdabb63e
commit
00194d0130
|
|
@ -14,7 +14,8 @@ spec:
|
||||||
- createdb
|
- createdb
|
||||||
allowedSourceRanges: #Load balancer source ranges
|
allowedSourceRanges: #Load balancer source ranges
|
||||||
- 127.0.0.1/32
|
- 127.0.0.1/32
|
||||||
|
databases:
|
||||||
|
foo: zalando
|
||||||
#Expert section
|
#Expert section
|
||||||
postgresql:
|
postgresql:
|
||||||
version: "9.6"
|
version: "9.6"
|
||||||
|
|
|
||||||
|
|
@ -228,10 +228,14 @@ func (c *Cluster) Create() error {
|
||||||
c.logger.Infof("pods are ready")
|
c.logger.Infof("pods are ready")
|
||||||
|
|
||||||
if !(c.masterLess || c.databaseAccessDisabled()) {
|
if !(c.masterLess || c.databaseAccessDisabled()) {
|
||||||
err = c.createRoles()
|
if err := c.createRoles(); err != nil {
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not create users: %v", err)
|
return fmt.Errorf("could not create users: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := c.createDatabases(); err != nil {
|
||||||
|
return fmt.Errorf("could not create databases: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
c.logger.Infof("users have been successfully created")
|
c.logger.Infof("users have been successfully created")
|
||||||
} else {
|
} else {
|
||||||
if c.masterLess {
|
if c.masterLess {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ import (
|
||||||
"github.com/zalando-incubator/postgres-operator/pkg/util/constants"
|
"github.com/zalando-incubator/postgres-operator/pkg/util/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
var getUserSQL = `SELECT a.rolname, COALESCE(a.rolpassword, ''), a.rolsuper, a.rolinherit,
|
const (
|
||||||
|
getUserSQL = `SELECT a.rolname, COALESCE(a.rolpassword, ''), a.rolsuper, a.rolinherit,
|
||||||
a.rolcreaterole, a.rolcreatedb, a.rolcanlogin,
|
a.rolcreaterole, a.rolcreatedb, a.rolcanlogin,
|
||||||
ARRAY(SELECT b.rolname
|
ARRAY(SELECT b.rolname
|
||||||
FROM pg_catalog.pg_auth_members m
|
FROM pg_catalog.pg_auth_members m
|
||||||
|
|
@ -21,6 +22,10 @@ var getUserSQL = `SELECT a.rolname, COALESCE(a.rolpassword, ''), a.rolsuper, a.r
|
||||||
WHERE a.rolname = ANY($1)
|
WHERE a.rolname = ANY($1)
|
||||||
ORDER BY 1;`
|
ORDER BY 1;`
|
||||||
|
|
||||||
|
getDatabasesSQL = `SELECT datname, a.rolname AS owner FROM pg_database d INNER JOIN pg_authid a ON a.oid = d.datdba;`
|
||||||
|
createDatabaseSQL = `CREATE DATABASE "%s" OWNER "%s";`
|
||||||
|
)
|
||||||
|
|
||||||
func (c *Cluster) pgConnectionString() string {
|
func (c *Cluster) pgConnectionString() string {
|
||||||
hostname := fmt.Sprintf("%s.%s.svc.cluster.local", c.Name, c.Namespace)
|
hostname := fmt.Sprintf("%s.%s.svc.cluster.local", c.Name, c.Namespace)
|
||||||
username := c.systemUsers[constants.SuperuserKeyName].Name
|
username := c.systemUsers[constants.SuperuserKeyName].Name
|
||||||
|
|
@ -106,6 +111,88 @@ func (c *Cluster) readPgUsersFromDatabase(userNames []string) (users spec.PgUser
|
||||||
return users, nil
|
return users, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Cluster) getDatabases() (map[string]string, error) {
|
||||||
|
var (
|
||||||
|
rows *sql.Rows
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
dbs := make(map[string]string, 0)
|
||||||
|
|
||||||
|
if err := c.initDbConn(); err != nil {
|
||||||
|
return nil, fmt.Errorf("could not init db connection")
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := c.closeDbConn(); err != nil {
|
||||||
|
c.logger.Errorf("could not close db connection: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if rows, err = c.pgDb.Query(getDatabasesSQL); err != nil {
|
||||||
|
return nil, fmt.Errorf("could not query database: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if err2 := rows.Close(); err2 != nil {
|
||||||
|
err = fmt.Errorf("error when closing query cursor: %v", err2)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var datname, owner string
|
||||||
|
|
||||||
|
err := rows.Scan(&datname, &owner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error when processing row: %v", err)
|
||||||
|
}
|
||||||
|
dbs[datname] = owner
|
||||||
|
}
|
||||||
|
|
||||||
|
return dbs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cluster) createDatabases() error {
|
||||||
|
newDbs := c.Spec.Databases
|
||||||
|
curDbs, err := c.getDatabases()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not get current databases: %v", err)
|
||||||
|
}
|
||||||
|
for datname := range curDbs {
|
||||||
|
delete(newDbs, datname)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(newDbs) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.initDbConn(); err != nil {
|
||||||
|
return fmt.Errorf("could not init db connection")
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := c.closeDbConn(); err != nil {
|
||||||
|
c.logger.Errorf("could not close db connection: %v", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for datname, owner := range newDbs {
|
||||||
|
if _, ok := c.pgUsers[owner]; !ok {
|
||||||
|
c.logger.Infof("skipping creationg of the %q database, user %q does not exist", datname, owner)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !alphaNumericRegexp.MatchString(datname) {
|
||||||
|
c.logger.Infof("database %q has invalid name", datname)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c.logger.Infof("creating database %q with owner %q", datname, owner)
|
||||||
|
|
||||||
|
if _, err = c.pgDb.Query(fmt.Sprintf(createDatabaseSQL, datname, owner)); err != nil {
|
||||||
|
return fmt.Errorf("could not query database: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func makeUserFlags(rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin bool) (result []string) {
|
func makeUserFlags(rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin bool) (result []string) {
|
||||||
if rolsuper {
|
if rolsuper {
|
||||||
result = append(result, constants.RoleFlagSuperuser)
|
result = append(result, constants.RoleFlagSuperuser)
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ type PostgresSpec struct {
|
||||||
MaintenanceWindows []MaintenanceWindow `json:"maintenanceWindows,omitempty"`
|
MaintenanceWindows []MaintenanceWindow `json:"maintenanceWindows,omitempty"`
|
||||||
Clone CloneDescription `json:"clone"`
|
Clone CloneDescription `json:"clone"`
|
||||||
ClusterName string `json:"-"`
|
ClusterName string `json:"-"`
|
||||||
|
Databases map[string]string `json:"databases,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostgresqlList defines a list of PostgreSQL clusters.
|
// PostgresqlList defines a list of PostgreSQL clusters.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue