in oracle/controllers/config_agent_helpers.go [231:352]
func CreateDatabase(ctx context.Context, r client.Reader, dbClientFactory DatabaseClientFactory, namespace, instName string, req CreateDatabaseRequest) (string, error) {
klog.InfoS("config_agent_helpers/CreateDatabase", "namespace", namespace, "instName", instName, "cdbName", req.CdbName, "pdbName", req.Name)
var pwd string
var err error
toUpdatePlaintextAdminPwd := req.Password != "" && req.Password != req.LastPassword
if toUpdatePlaintextAdminPwd {
pwd = req.Password
}
toUpdateGsmAdminPwd := req.AdminPasswordGsmSecretRef != nil && (req.AdminPasswordGsmSecretRef.Version != req.AdminPasswordGsmSecretRef.LastVersion || req.AdminPasswordGsmSecretRef.Version == "latest")
if toUpdateGsmAdminPwd {
pwd, err = AccessSecretVersionFunc(ctx, fmt.Sprintf(gsmSecretStr, req.AdminPasswordGsmSecretRef.ProjectId, req.AdminPasswordGsmSecretRef.SecretId, req.AdminPasswordGsmSecretRef.Version))
if err != nil {
return "", fmt.Errorf("config_agent_helpers/CreateDatabase: failed to retrieve secret from Google Secret Manager: %v", err)
}
}
p, err := buildPDB(req.CdbName, req.Name, pwd, version, consts.ListenerNames, true)
if err != nil {
return "", err
}
dbClient, closeConn, err := dbClientFactory.New(ctx, r, namespace, instName)
if err != nil {
return "", fmt.Errorf("config_agent_helpers/CreateDatabase: failed to create database daemon dbdClient: %v", err)
}
defer closeConn()
klog.InfoS("config_agent_helpers/CreateDatabase: checking CDB state")
_, err = dbClient.CheckDatabaseState(ctx, &dbdpb.CheckDatabaseStateRequest{IsCdb: true, DatabaseName: req.CdbName, DbDomain: req.DbDomain})
if err != nil {
return "", fmt.Errorf("config_agent_helpers/CreateDatabase: failed to check a CDB state: %v", err)
}
klog.InfoS("config_agent_helpers/CreateDatabase: pre-flight check#1: CDB is up and running")
pdbCheckCmd := []string{fmt.Sprintf("select open_mode, restricted from v$pdbs where name = '%s'", sql.StringParam(p.pluggableDatabaseName))}
resp, err := dbClient.RunSQLPlusFormatted(ctx, &dbdpb.RunSQLPlusCMDRequest{Commands: pdbCheckCmd, Suppress: false})
if err != nil {
return "", fmt.Errorf("config_agent_helpers/CreateDatabase: failed to check if a PDB called %s already exists: %v", p.pluggableDatabaseName, err)
}
klog.InfoS("config_agent_helpers/CreateDatabase pre-flight check#2", "pdb", p.pluggableDatabaseName, "resp", resp)
if resp != nil && resp.Msg != nil {
if toUpdateGsmAdminPwd || toUpdatePlaintextAdminPwd {
sqls := append([]string{sql.QuerySetSessionContainer(p.pluggableDatabaseName)}, []string{sql.QueryAlterUser(pdbAdmin, pwd)}...)
if _, err := dbClient.RunSQLPlus(ctx, &dbdpb.RunSQLPlusCMDRequest{
Commands: sqls,
Suppress: true,
}); err != nil {
return "", fmt.Errorf("failed to alter user %s: %v", pdbAdmin, err)
}
klog.InfoS("config_agent_helpers/CreateDatabase update pdb admin user succeeded", "user", pdbAdmin)
return "AdminUserSyncCompleted", nil
}
klog.InfoS("config_agent_helpers/CreateDatabase pre-flight check#2", "pdb", p.pluggableDatabaseName, "respMsg", resp.Msg)
return "AlreadyExists", nil
}
klog.InfoS("config_agent_helpers/CreateDatabase pre-flight check#2: pdb doesn't exist, proceeding to create", "pdb", p.pluggableDatabaseName)
cdbDir := fmt.Sprintf(consts.DataDir, consts.DataMount, req.CdbName)
pdbDir := filepath.Join(cdbDir, strings.ToUpper(req.Name))
toCreate := []string{
fmt.Sprintf("%s/data", pdbDir),
fmt.Sprintf("%s/%s", pdbDir, consts.DpdumpDir.Linux),
fmt.Sprintf("%s/rman", consts.OracleBase),
}
var dirs []*dbdpb.CreateDirsRequest_DirInfo
for _, d := range toCreate {
dirs = append(dirs, &dbdpb.CreateDirsRequest_DirInfo{
Path: d,
Perm: 0760,
})
}
if _, err := dbClient.CreateDirs(ctx, &dbdpb.CreateDirsRequest{Dirs: dirs}); err != nil {
return "", fmt.Errorf("failed to create PDB dirs: %v", err)
}
pdbCmd := []string{sql.QueryCreatePDB(p.pluggableDatabaseName, pdbAdmin, p.pluggableAdminPasswd, p.dataFilesDir, p.defaultTablespace, p.defaultTablespaceDatafile, p.fileConvertFrom, p.fileConvertTo)}
_, err = dbClient.RunSQLPlus(ctx, &dbdpb.RunSQLPlusCMDRequest{Commands: pdbCmd, Suppress: false})
if err != nil {
return "", fmt.Errorf("config_agent_helpers/CreateDatabase: failed to create a PDB %s: %v", p.pluggableDatabaseName, err)
}
klog.InfoS("config_agent_helpers/CreateDatabase create a PDB Done", "pdb", p.pluggableDatabaseName)
pdbOpen := []string{
fmt.Sprintf("alter pluggable database %s open read write", sql.MustBeObjectName(p.pluggableDatabaseName)),
fmt.Sprintf("alter pluggable database %s save state", sql.MustBeObjectName(p.pluggableDatabaseName)),
}
_, err = dbClient.RunSQLPlus(ctx, &dbdpb.RunSQLPlusCMDRequest{Commands: pdbOpen, Suppress: false})
if err != nil {
return "", fmt.Errorf("config_agent_helpers/CreatePDBDatabase: PDB %s open failed: %v", p.pluggableDatabaseName, err)
}
klog.InfoS("config_agent_helpers/CreateDatabase PDB open", "pdb", p.pluggableDatabaseName)
_, err = dbClient.RunSQLPlus(ctx, &dbdpb.RunSQLPlusCMDRequest{Commands: []string{
sql.QuerySetSessionContainer(p.pluggableDatabaseName),
sql.QueryGrantPrivileges("create session, dba", pdbAdmin),
sql.QueryGrantPrivileges("create session, resource, datapump_imp_full_database, datapump_exp_full_database, unlimited tablespace", consts.PDBLoaderUser),
}, Suppress: false})
if err != nil {
// Until we have a proper error handling, just log an error here.
klog.ErrorS(err, "CreateDatabase: failed to create a PDB_ADMIN user and/or PDB loader user")
}
klog.InfoS("config_agent_helpers/CreateDatabase: created PDB_ADMIN and PDB Loader users")
// Separate out the directory treatment for the ease of troubleshooting.
_, err = dbClient.RunSQLPlus(ctx, &dbdpb.RunSQLPlusCMDRequest{Commands: []string{
sql.QuerySetSessionContainer(p.pluggableDatabaseName),
sql.QueryCreateDir(consts.DpdumpDir.Oracle, filepath.Join(p.pathPrefix, consts.DpdumpDir.Linux)),
sql.QueryGrantPrivileges(fmt.Sprintf("read,write on directory %s", consts.DpdumpDir.Oracle), consts.PDBLoaderUser),
}, Suppress: false})
if err != nil {
klog.ErrorS(err, "CreateDatabase: failed to create a Data Pump directory", "datapumpDir", consts.DpdumpDir)
}
klog.InfoS("config_agent_helpers/CreateDatabase: DONE", "pdb", p.pluggableDatabaseName)
return "Ready", nil
}