//currently we define default DB users (postgres, cpmtest, pgpool) //for all database containers func createDBUsers(dbConn *sql.DB, dbnode admindb.Container) error { var err error var password admindb.Setting //get the postgres password password, err = admindb.GetSetting(dbConn, "POSTGRESPSW") if err != nil { logit.Error.Println(err.Error()) return err } //register postgres user var user = admindb.ContainerUser{} user.Containername = dbnode.Name user.Rolname = "postgres" user.Passwd = password.Value _, err = admindb.AddContainerUser(dbConn, user) if err != nil { logit.Error.Println(err.Error()) return err } //cpmtest and pgpool users are created by the node-setup.sql script //here, we just register them when we create a new node //get the cpmtest password password, err = admindb.GetSetting(dbConn, "CPMTESTPSW") if err != nil { logit.Error.Println(err.Error()) return err } //register cpmtest user user.Containername = dbnode.Name user.Rolname = "cpmtest" user.Passwd = password.Value _, err = admindb.AddContainerUser(dbConn, user) if err != nil { logit.Error.Println(err.Error()) return err } //get the pgpool password password, err = admindb.GetSetting(dbConn, "PGPOOLPSW") if err != nil { logit.Error.Println(err.Error()) return err } user.Containername = dbnode.Name user.Rolname = "pgpool" user.Passwd = password.Value //register pgpool user _, err = admindb.AddContainerUser(dbConn, user) if err != nil { logit.Error.Println(err.Error()) return err } return err }
func templateChange(dbConn *sql.DB, containerName string, cars []ContainerAccessRule, containerRole string) error { var err error logit.Info.Println("templateChange called") //create pg_hba.conf var mode = containerRole domainname, err := admindb.GetSetting(dbConn, "DOMAIN-NAME") if err != nil { logit.Error.Println("templateChange:DOMAIN-NAME error " + err.Error()) return err } rules := make([]template.Rule, 0) var ar Rule for i := range cars { logit.Info.Println("templateChange cars found") if cars[i].Selected == "true" { logit.Info.Println("templateChange cars found to be true") rule := template.Rule{} ar, err = GetAccessRule(dbConn, cars[i].AccessRuleID) if err != nil { logit.Error.Println("templateChange:get access rule error " + err.Error()) return err } rule.Type = ar.Type rule.Database = ar.Database rule.User = ar.User rule.Address = ar.Address rule.Method = ar.Method rules = append(rules, rule) } } logit.Info.Printf("templateChange rules going to template %d\n", len(rules)) var data string data, err = template.Hba(dbConn, mode, containerName, "", "", domainname.Value, rules) if err != nil { logit.Error.Println("templateChange:" + err.Error()) return err } fqdn := containerName + "." + domainname.Value //place pg_hba.conf on node _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/pg_hba.conf", data, fqdn) if err != nil { logit.Error.Println("templateChange:" + err.Error()) return err } return err }
func getPort(dbConn *sql.DB) (string, error) { var err error var port admindb.Setting port, err = admindb.GetSetting(dbConn, "PG-PORT") if err != nil { logit.Error.Println(err.Error()) return port.Value, err } return port.Value, nil }
//return the CPU MEM settings func getDockerResourceSettings(dbConn *sql.DB, size string) (string, string, error) { var CPU, MEM string var setting admindb.Setting var err error switch size { case "SM": setting, err = admindb.GetSetting(dbConn, "S-DOCKER-PROFILE-CPU") CPU = setting.Value setting, err = admindb.GetSetting(dbConn, "S-DOCKER-PROFILE-MEM") MEM = setting.Value case "MED": setting, err = admindb.GetSetting(dbConn, "M-DOCKER-PROFILE-CPU") CPU = setting.Value setting, err = admindb.GetSetting(dbConn, "M-DOCKER-PROFILE-MEM") MEM = setting.Value default: setting, err = admindb.GetSetting(dbConn, "L-DOCKER-PROFILE-CPU") CPU = setting.Value setting, err = admindb.GetSetting(dbConn, "L-DOCKER-PROFILE-MEM") MEM = setting.Value } return CPU, MEM, err }
func GetPGStatus2(dbConn *sql.DB, nodename string, hostname string) (string, error) { //fetch cpmtest user credentials nodeuser, err := admindb.GetContainerUser(dbConn, nodename, "cpmtest") if err != nil { logit.Error.Println(err.Error()) return "", err } logit.Info.Println("cpmtest password is " + nodeuser.Passwd) var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") dbConn2, err := util.GetMonitoringConnection(hostname, "cpmtest", pgport.Value, "cpmtest", nodeuser.Passwd) defer dbConn2.Close() if err != nil { logit.Error.Println(err.Error()) return "", err } var value string err = dbConn2.QueryRow(fmt.Sprintf("select now()::text")).Scan(&value) switch { case err == sql.ErrNoRows: logit.Info.Println("getpgstatus 2 no rows returned") return "OFFLINE", nil case err != nil: logit.Info.Println("getpgstatus2 error " + err.Error()) return "OFFLINE", nil default: logit.Info.Println("getpgstatus2 returned " + value) } return "RUNNING", nil }
func ContainerInfoStatrepl(w rest.ResponseWriter, r *rest.Request) { dbConn, err := util.GetConnection(CLUSTERADMIN_DB) if err != nil { logit.Error.Println("BackupNow: error " + err.Error()) rest.Error(w, err.Error(), 400) return } defer dbConn.Close() err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read") if err != nil { logit.Error.Println("ContainerStatrepl: authorize error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") if ID == "" { rest.Error(w, "ID required", http.StatusBadRequest) return } node, err := admindb.GetContainer(dbConn, ID) if err != nil { logit.Error.Println("ContainerStatrepl:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var host = node.Name if KubeEnv { host = node.Name + "-db" } //fetch cpmtest user credentials var nodeuser admindb.ContainerUser nodeuser, err = admindb.GetContainerUser(dbConn, node.Name, CPMTEST_USER) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //get port var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") dbConn2, err := util.GetMonitoringConnection(host, CPMTEST_DB, pgport.Value, CPMTEST_USER, nodeuser.Passwd) defer dbConn2.Close() stats := make([]Statrepl, 0) var rows *sql.Rows rows, err = dbConn2.Query("SELECT pid , usesysid , usename , application_name , client_addr , coalesce(client_hostname, ' ') , client_port , to_char(backend_start, 'YYYY-MM-DD HH24:MI-SS') as backend_start , state , sent_location , write_location , flush_location , replay_location , sync_priority , sync_state from pg_stat_replication") if err != nil { logit.Error.Println("ContainerStatrepl:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } defer rows.Close() for rows.Next() { stat := Statrepl{} if err = rows.Scan( &stat.Pid, &stat.Usesysid, &stat.Usename, &stat.AppName, &stat.ClientAddr, &stat.ClientHostname, &stat.ClientPort, &stat.BackendStart, &stat.State, &stat.SentLocation, &stat.WriteLocation, &stat.FlushLocation, &stat.ReplayLocation, &stat.SyncPriority, &stat.SyncState, ); err != nil { logit.Error.Println("ContainerStatrepl:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } stats = append(stats, stat) } if err = rows.Err(); err != nil { logit.Error.Println("ContainerStatrepl:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } w.WriteHeader(http.StatusOK) w.WriteJson(&stats) }
func provisionImpl(dbConn *sql.DB, params *cpmserverapi.DockerRunRequest, PROFILE string, standby bool) error { logit.Info.Println("PROFILE: provisionImpl starts 1") var errorStr string //make sure the container name is not already taken _, err := admindb.GetContainerByName(dbConn, params.ContainerName) if err != nil { if err != sql.ErrNoRows { return err } } else { errorStr = "container name" + params.ContainerName + " already used can't provision" logit.Error.Println("Provision error" + errorStr) return errors.New(errorStr) } //create the container by constructing a template and calling openshift params.CPU, params.MEM, err = getDockerResourceSettings(dbConn, PROFILE) if err != nil { logit.Error.Println("Provision: problem in getting profiles call" + err.Error()) return err } //remove any existing pods and services with this name var username = "******" var password = "******" var objectName = params.ContainerName var objectType = "pod" err = OpenshiftDelete(username, password, objectName, objectType) if err != nil { logit.Info.Println("Provision:" + err.Error()) } objectName = params.ContainerName err = OpenshiftDelete(username, password, objectName, objectType) if err != nil { logit.Info.Println("Provision:" + err.Error()) } podInfo := template.KubePodParams{ NAME: params.ContainerName, ID: params.ContainerName, PODID: params.ContainerName, CPU: params.CPU, MEM: params.MEM, IMAGE: params.Image, VOLUME: params.PGDataPath, PORT: "13000", BACKUP_NAME: "", BACKUP_SERVERNAME: "", BACKUP_SERVERIP: "", BACKUP_SCHEDULEID: "", BACKUP_PROFILENAME: "", BACKUP_CONTAINERNAME: "", BACKUP_PATH: "", BACKUP_HOST: "", BACKUP_PORT: "", BACKUP_USER: "", BACKUP_SERVER_URL: "", } //generate the pod template var podTemplateData []byte podTemplateData, err = template.KubeNodePod(podInfo) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } logit.Info.Println("pod template=" + string(podTemplateData[:])) //create the pod file, err := ioutil.TempFile("/tmp", "openshift-template") if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } defer os.Remove(file.Name()) err = ioutil.WriteFile(file.Name(), podTemplateData, 0644) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } err = OpenshiftCreate(username, password, file.Name()) if err != nil { logit.Info.Println("Provision:" + err.Error()) } var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") if err != nil { logit.Error.Println("Provision:PG-PORT setting error " + err.Error()) return err } //generate the admin service template serviceInfo := template.KubeServiceParams{ SERVICENAME: params.ContainerName, NAME: params.ContainerName, PORT: "10001", DBPORT: pgport.Value, } //create the admin service template var serviceTemplateData []byte serviceTemplateData, err = template.KubeNodeService(serviceInfo) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } logit.Info.Println("service template=" + string(serviceTemplateData[:])) file, err = ioutil.TempFile("/tmp", "openshift-template") if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } defer os.Remove(file.Name()) err = ioutil.WriteFile(file.Name(), serviceTemplateData, 0644) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } //create the service err = OpenshiftCreate(username, password, file.Name()) if err != nil { logit.Info.Println("Provision:" + err.Error()) } dbnode := admindb.Container{} dbnode.ID = "" dbnode.Name = params.ContainerName dbnode.Image = params.Image dbnode.ClusterID = "-1" dbnode.ProjectID = params.ProjectID dbnode.ServerID = params.ServerID if params.Standalone == "true" { dbnode.Role = "standalone" } else { dbnode.Role = "unassigned" } var strid int strid, err = admindb.InsertContainer(dbConn, dbnode) newid := strconv.Itoa(strid) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } dbnode.ID = newid //register default db users on the new node err = createDBUsers(dbConn, dbnode) return err }
func BackupNow(w rest.ResponseWriter, r *rest.Request) { dbConn, err := util.GetConnection(CLUSTERADMIN_DB) if err != nil { logit.Error.Println("BackupNow: error " + err.Error()) rest.Error(w, err.Error(), 400) return } defer dbConn.Close() postMsg := BackupNowPost{} err = r.DecodeJsonPayload(&postMsg) if err != nil { logit.Error.Println("BackupNow: error in decode" + err.Error()) rest.Error(w, err.Error(), http.StatusInternalServerError) return } err = secimpl.Authorize(dbConn, postMsg.Token, "perm-backup") if err != nil { logit.Error.Println("BackupNow: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } if postMsg.ServerID == "" { logit.Error.Println("BackupNow: error node ServerID required") rest.Error(w, "server ID required", 400) return } if postMsg.ProfileName == "" { logit.Error.Println("BackupNow: error node ProfileName required") rest.Error(w, "ProfileName required", 400) return } if postMsg.ScheduleID == "" { logit.Error.Println("BackupNow: error schedule ID required") rest.Error(w, "schedule ID required", 400) return } schedule, err2 := backup.GetSchedule(dbConn, postMsg.ScheduleID) if err2 != nil { logit.Error.Println("BackupNow: " + err2.Error()) rest.Error(w, err2.Error(), 400) return } //get the server details for where the backup should be made server := admindb.Server{} server, err = admindb.GetServer(dbConn, postMsg.ServerID) if err != nil { logit.Error.Println("BackupNow: " + err.Error()) rest.Error(w, err.Error(), 400) return } //get the domain name //get domain name var domainname admindb.Setting domainname, err = admindb.GetSetting(dbConn, "DOMAIN-NAME") if err != nil { logit.Error.Println("BackupNow: DOMAIN-NAME err " + err.Error()) } request := backup.BackupRequest{} request.ScheduleID = postMsg.ScheduleID request.ServerID = server.ID if KubeEnv { request.ContainerName = schedule.ContainerName + "-db" } else { request.ContainerName = schedule.ContainerName } request.ServerName = server.Name request.ServerIP = server.IPAddress request.ProfileName = postMsg.ProfileName backupServerURL := "cpm-backup." + domainname.Value + ":13000" output, err := backup.BackupNowClient(backupServerURL, request) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), http.StatusInternalServerError) return } logit.Info.Println("output=" + output) w.WriteHeader(http.StatusOK) status := SimpleStatus{} status.Status = "OK" w.WriteJson(&status) }
func UpdateSchedule(w rest.ResponseWriter, r *rest.Request) { dbConn, err := util.GetConnection(CLUSTERADMIN_DB) if err != nil { logit.Error.Println("BackupNow: error " + err.Error()) rest.Error(w, err.Error(), 400) return } defer dbConn.Close() postMsg := AddSchedulePost{} err = r.DecodeJsonPayload(&postMsg) if err != nil { logit.Error.Println("UpdateSchedule: error in decode" + err.Error()) rest.Error(w, err.Error(), http.StatusInternalServerError) return } err = secimpl.Authorize(dbConn, postMsg.Token, "perm-backup") if err != nil { logit.Error.Println("UpdateSchedule: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } if postMsg.ID == "" { logit.Error.Println("UpdateSchedule: error schedule ID required") rest.Error(w, "schedule ID required", 400) return } if postMsg.ServerID == "" { logit.Error.Println("UpdateSchedule: error ServerID required") rest.Error(w, "schedule ID required", 400) return } if postMsg.Enabled == "" { logit.Error.Println("UpdateSchedule: error Enabled required") rest.Error(w, "Enabled required", 400) return } if postMsg.Minutes == "" { logit.Error.Println("UpdateSchedule: error Minutes required") rest.Error(w, "schedule Minutes required", 400) return } if postMsg.Hours == "" { logit.Error.Println("UpdateSchedule: error Hours required") rest.Error(w, "schedule Hours required", 400) return } if postMsg.DayOfMonth == "" { logit.Error.Println("UpdateSchedule: error DayOfMonth required") rest.Error(w, "schedule DayOfMonth required", 400) return } if postMsg.Month == "" { logit.Error.Println("UpdateSchedule: error Month required") rest.Error(w, "schedule Month required", 400) return } if postMsg.DayOfWeek == "" { logit.Error.Println("UpdateSchedule: error DayOfWeek required") rest.Error(w, "schedule DayOfWeek required", 400) return } if postMsg.Name == "" { logit.Error.Println("UpdateSchedule: error Name required") rest.Error(w, "schedule Name required", 400) return } s := backup.BackupSchedule{} s.ID = postMsg.ID s.ServerID = postMsg.ServerID s.Minutes = postMsg.Minutes s.Hours = postMsg.Hours s.Enabled = postMsg.Enabled s.DayOfMonth = postMsg.DayOfMonth s.Month = postMsg.Month s.DayOfWeek = postMsg.DayOfWeek s.Name = postMsg.Name err = backup.UpdateSchedule(dbConn, s) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), 400) return } //notify backup server to reload it's schedules //get the domain name //get domain name var domainname admindb.Setting domainname, err = admindb.GetSetting(dbConn, "DOMAIN-NAME") if err != nil { logit.Error.Println("BackupNow: DOMAIN-NAME err " + err.Error()) } backupServerURL := "cpm-backup." + domainname.Value + ":13000" output, err := backup.ReloadClient(backupServerURL, s) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), 400) return } logit.Info.Println("reload output=" + output) w.WriteHeader(http.StatusOK) status := SimpleStatus{} status.Status = "OK" w.WriteJson(&status) }
func DeleteSchedule(w rest.ResponseWriter, r *rest.Request) { dbConn, err := util.GetConnection(CLUSTERADMIN_DB) if err != nil { logit.Error.Println("BackupNow: error " + err.Error()) rest.Error(w, err.Error(), 400) return } defer dbConn.Close() err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-backup") if err != nil { logit.Error.Println("DeleteSchedule: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") if ID == "" { rest.Error(w, "schedule ID required", 400) return } err = backup.DeleteSchedule(dbConn, ID) if err != nil { logit.Error.Println("DeleteSchedule: " + err.Error()) rest.Error(w, err.Error(), 400) return } //notify backup server to reload schedules //get the domain name //get domain name var domainname admindb.Setting domainname, err = admindb.GetSetting(dbConn, "DOMAIN-NAME") if err != nil { logit.Error.Println("DeleteSchedule: DOMAIN-NAME err " + err.Error()) rest.Error(w, err.Error(), 400) return } s := backup.BackupSchedule{} backupServerURL := "cpm-backup." + domainname.Value + ":13000" var output string output, err = backup.ReloadClient(backupServerURL, s) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), 400) return } logit.Info.Println("reload output=" + output) w.WriteHeader(http.StatusOK) status := SimpleStatus{} status.Status = "OK" w.WriteJson(&status) }
func DeleteContainerUser(w rest.ResponseWriter, r *rest.Request) { dbConn, err := util.GetConnection(CLUSTERADMIN_DB) if err != nil { logit.Error.Println("BackupNow: error " + err.Error()) rest.Error(w, err.Error(), 400) return } defer dbConn.Close() err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-backup") if err != nil { logit.Error.Println("DeleteContainerUser: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ContainerID := r.PathParam("ContainerID") if ContainerID == "" { rest.Error(w, "ContainerID required", 400) return } rolname := r.PathParam("Rolname") if rolname == "" { rest.Error(w, "Rolname required", 400) return } //get node info node, err := admindb.GetContainer(dbConn, ContainerID) if err != nil { logit.Error.Println("AddContainUser: "******"DeleteContainerUser: "******"-db" } //fetch cpmtest user credentials var cpmuser admindb.ContainerUser cpmuser, err = admindb.GetContainerUser(dbConn, node.Name, CPMTEST_USER) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //get port var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") dbConn2, err := util.GetMonitoringConnection(host, CPMTEST_DB, pgport.Value, CPMTEST_USER, cpmuser.Passwd) defer dbConn2.Close() query := "drop role " + rolname logit.Info.Println(query) _, err = dbConn2.Query(query) if err != nil { logit.Error.Println("DeleteContainerUser:"******"OK" w.WriteJson(&status) }
func configureCluster(dbConn *sql.DB, cluster admindb.Cluster, autocluster bool) error { logit.Info.Println("configureCluster:GetCluster") //get master node for this cluster master, err := admindb.GetContainerMaster(dbConn, cluster.ID) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:GetContainerMaster") //configure master postgresql.conf file var data string if cluster.ClusterType == "synchronous" { data, err = template.Postgresql("master", pgport.Value, "*") } else { data, err = template.Postgresql("master", pgport.Value, "") } if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:master postgresql.conf generated") //write master postgresql.conf file remotely _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/postgresql.conf", data, master.Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:master postgresql.conf copied to remote") //get domain name var domainname admindb.Setting domainname, err = admindb.GetSetting(dbConn, "DOMAIN-NAME") if err != nil { logit.Error.Println("configureCluster: DOMAIN-NAME err " + err.Error()) return err } //configure master pg_hba.conf file rules := make([]template.Rule, 0) data, err = template.Hba(dbConn, "master", master.Name, pgport.Value, cluster.ID, domainname.Value, rules) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:master pg_hba.conf generated") //write master pg_hba.conf file remotely _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/pg_hba.conf", data, master.Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:master pg_hba.conf copied remotely") //restart postgres after the config file changes var stopResp cpmcontainerapi.StopPGResponse stopResp, err = cpmcontainerapi.StopPGClient(master.Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster: master stoppg output was" + stopResp.Output) var startResp cpmcontainerapi.StartPGResponse startResp, err = cpmcontainerapi.StartPGClient(master.Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:master startpg output was" + startResp.Output) //sleep loop until the master's PG can respond var found = false var currentStatus string var masterhost = master.Name for i := 0; i < 20; i++ { currentStatus, err = GetPGStatus2(dbConn, master.Name, masterhost) if currentStatus == "RUNNING" { logit.Info.Println("master is running...continuing") found = true break } else { logit.Info.Println("sleeping 1 sec waiting on master..") time.Sleep(1000 * time.Millisecond) } } if !found { logit.Info.Println("configureCluster: timed out waiting on master pg to start") return errors.New("timeout waiting for master pg to respond") } standbynodes, err2 := admindb.GetAllStandbyContainers(dbConn, cluster.ID) if err2 != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } //configure all standby nodes var stopPGResp cpmcontainerapi.StopPGResponse i := 0 for i = range standbynodes { if standbynodes[i].Role == STANDBY { //stop standby if !autocluster { stopPGResp, err = cpmcontainerapi.StopPGClient(standbynodes[i].Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:stop output was" + stopPGResp.Output) } //create base backup from master var backupresp cpmcontainerapi.BasebackupResponse backupresp, err = cpmcontainerapi.BasebackupClient(masterhost+"."+domainname.Value, standbynodes[i].Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:basebackup output was" + backupresp.Output) data, err = template.Recovery(masterhost, pgport.Value, "postgres") if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:standby recovery.conf generated") //write standby recovery.conf file remotely _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/recovery.conf", data, standbynodes[i].Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:standby recovery.conf copied remotely") data, err = template.Postgresql(STANDBY, pgport.Value, "") if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } //write standby postgresql.conf file remotely _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/postgresql.conf", data, standbynodes[i].Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:standby postgresql.conf copied remotely") //configure standby pg_hba.conf file data, err = template.Hba(dbConn, STANDBY, standbynodes[i].Name, pgport.Value, cluster.ID, domainname.Value, rules) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:standby pg_hba.conf generated") //write standby pg_hba.conf file remotely _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/pg_hba.conf", data, standbynodes[i].Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:standby pg_hba.conf copied remotely") //start standby var stResp cpmcontainerapi.StartPGOnStandbyResponse stResp, err = cpmcontainerapi.StartPGOnStandbyClient(standbynodes[i].Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:standby startpg output was" + stResp.Output) } i++ } logit.Info.Println("configureCluster: sleeping 5 seconds before configuring pgpool...") time.Sleep(5000 * time.Millisecond) pgpoolNode, err4 := admindb.GetContainerPgpool(dbConn, cluster.ID) logit.Info.Println("configureCluster: lookup pgpool node") if err4 != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:" + pgpoolNode.Name) //configure the pgpool includes all standby nodes AND the master node poolnames := make([]string, len(standbynodes)+1) i = 0 for i = range standbynodes { poolnames[i] = standbynodes[i].Name + "." + domainname.Value i++ } poolnames[i] = master.Name + "." + domainname.Value //generate pgpool.conf HOST_LIST data, err = template.Poolconf(poolnames) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:pgpool pgpool.conf generated") //write pgpool.conf to remote pool node _, err = cpmcontainerapi.RemoteWritefileClient(util.GetBase()+"/bin/"+"pgpool.conf", data, pgpoolNode.Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:pgpool pgpool.conf copied remotely") //generate pool_passwd data, err = template.Poolpasswd() if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:pgpool pool_passwd generated") //write pgpool.conf to remote pool node _, err = cpmcontainerapi.RemoteWritefileClient(util.GetBase()+"/bin/"+"pool_passwd", data, pgpoolNode.Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:pgpool pool_passwd copied remotely") //generate pool_hba.conf data, err = template.Poolhba() if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:pgpool pool_hba generated") //write pgpool.conf to remote pool node _, err = cpmcontainerapi.RemoteWritefileClient(util.GetBase()+"/bin/"+"pool_hba.conf", data, pgpoolNode.Name) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } logit.Info.Println("configureCluster:pgpool pool_hba copied remotely") //start pgpool var startPoolResp cpmcontainerapi.StartPgpoolResponse startPoolResp, err = cpmcontainerapi.StartPgpoolClient(pgpoolNode.Name) if err != nil { logit.Error.Println("configureCluster: " + err.Error()) return err } logit.Info.Println("configureCluster: pgpool startpgpool output was" + startPoolResp.Output) //finally, update the cluster to show that it is //initialized! cluster.Status = "initialized" err = admindb.UpdateCluster(dbConn, cluster) if err != nil { logit.Error.Println("configureCluster:" + err.Error()) return err } return nil }
func MonitorStatements(w rest.ResponseWriter, r *rest.Request) { dbConn, err := util.GetConnection(CLUSTERADMIN_DB) if err != nil { logit.Error.Println("BackupNow: error " + err.Error()) rest.Error(w, err.Error(), 400) return } defer dbConn.Close() err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read") if err != nil { logit.Error.Println("MonitorStatements: authorize error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") if ID == "" { rest.Error(w, "ID required", http.StatusBadRequest) return } container, err := admindb.GetContainer(dbConn, ID) if err != nil { logit.Error.Println("MonitorStatements:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var host = container.Name if KubeEnv { host = container.Name + "-db" } //fetch cpmtest user credentials var nodeuser admindb.ContainerUser nodeuser, err = admindb.GetContainerUser(dbConn, container.Name, CPMTEST_USER) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //get port var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") dbConn2, err := util.GetMonitoringConnection(host, CPMTEST_DB, pgport.Value, CPMTEST_USER, nodeuser.Passwd) defer dbConn2.Close() //get the list of databases databases := make([]string, 0) var rows *sql.Rows rows, err = dbConn2.Query( "SELECT datname from pg_database where datname not in ('template1', 'template0') order by datname") if err != nil { logit.Error.Println("MonitorStatements:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var datname string for rows.Next() { if err = rows.Scan( &datname, ); err != nil { logit.Error.Println("MonitorContainerSettings:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } databases = append(databases, datname) } if err = rows.Err(); err != nil { logit.Error.Println("MonitorStatements:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } rows.Close() statements := make([]PostgresStatement, 0) for i := range databases { //get a database connection to a specific database dbConn3, err := util.GetMonitoringConnection(host, databases[i], pgport.Value, CPMTEST_USER, nodeuser.Passwd) defer dbConn3.Close() rows, err = dbConn3.Query( "SELECT query, calls, total_time, rows, to_char(coalesce(100.0 * shared_blks_hit / nullif(shared_blks_hit + shared_blks_read, 0), -1), '999D99') AS hit_percent FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5") if err != nil { logit.Error.Println("MonitorStatements:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } defer rows.Close() for rows.Next() { stat := PostgresStatement{} stat.Database = databases[i] if err = rows.Scan( &stat.Query, &stat.Calls, &stat.TotalTime, &stat.Rows, &stat.HitPercent, ); err != nil { logit.Error.Println("MonitorContainerSettings:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } statements = append(statements, stat) } if err = rows.Err(); err != nil { logit.Error.Println("MonitorStatements:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } } w.WriteHeader(http.StatusOK) w.WriteJson(&statements) }
func MonitorContainerSettings(w rest.ResponseWriter, r *rest.Request) { dbConn, err := util.GetConnection(CLUSTERADMIN_DB) if err != nil { logit.Error.Println("BackupNow: error " + err.Error()) rest.Error(w, err.Error(), 400) return } defer dbConn.Close() err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read") if err != nil { logit.Error.Println("MonitorContainerSettings: authorize error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") if ID == "" { rest.Error(w, "ID required", http.StatusBadRequest) return } node, err := admindb.GetContainer(dbConn, ID) if err != nil { logit.Error.Println("MonitorContainerGetInfo:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var host = node.Name if KubeEnv { host = node.Name + "-db" } //fetch cpmtest user credentials var nodeuser admindb.ContainerUser nodeuser, err = admindb.GetContainerUser(dbConn, node.Name, CPMTEST_USER) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } logit.Info.Println("cpmtest password is " + nodeuser.Passwd) //get port var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") dbConn2, err := util.GetMonitoringConnection(host, CPMTEST_DB, pgport.Value, CPMTEST_USER, nodeuser.Passwd) defer dbConn2.Close() settings := make([]PostgresSetting, 0) var rows *sql.Rows rows, err = dbConn2.Query("select name, current_setting(name), source from pg_settings where source not in ('default','override')") if err != nil { logit.Error.Println("MonitorContainerSettings:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } defer rows.Close() for rows.Next() { setting := PostgresSetting{} if err = rows.Scan( &setting.Name, &setting.CurrentSetting, &setting.Source, ); err != nil { logit.Error.Println("MonitorContainerSettings:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } settings = append(settings, setting) } if err = rows.Err(); err != nil { logit.Error.Println("MonitorContainerSettings:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } w.WriteHeader(http.StatusOK) w.WriteJson(&settings) }
func provisionImplInit(dbConn *sql.DB, params *cpmserverapi.DockerRunRequest, PROFILE string, standby bool) error { //go get the domain name from the settings var domainname admindb.Setting var pgport admindb.Setting var err error domainname, err = admindb.GetSetting(dbConn, "DOMAIN-NAME") if err != nil { logit.Error.Println("Provision:DOMAIN-NAME setting error " + err.Error()) return err } pgport, err = admindb.GetSetting(dbConn, "PG-PORT") if err != nil { logit.Error.Println("Provision:PG-PORT setting error " + err.Error()) return err } fqdn := params.ContainerName + "." + domainname.Value //we are depending on a DNS entry being created shortly after //creating the node in Docker //you might need to wait here until you can reach the new node's agent logit.Info.Println("PROFILE waiting till DNS ready") err = waitTillReady(fqdn) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } logit.Info.Println("checkpt 1") if standby { logit.Info.Println("standby node being created, will not initdb") } else { //initdb on the new node logit.Info.Println("PROFILE running initdb on the node") var resp cpmcontainerapi.InitdbResponse logit.Info.Println("checkpt 2") resp, err = cpmcontainerapi.InitdbClient(fqdn) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } logit.Info.Println("checkpt 3") logit.Info.Println("initdb output was" + resp.Output) logit.Info.Println("PROFILE initdb completed") //create postgresql.conf var data string var mode = "standalone" data, err = template.Postgresql(mode, pgport.Value, "") //place postgresql.conf on new node _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/"+params.ContainerName+"/postgresql.conf", data, fqdn) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } //create pg_hba.conf rules := make([]template.Rule, 0) data, err = template.Hba(dbConn, mode, params.ContainerName, pgport.Value, "", domainname.Value, rules) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } //place pg_hba.conf on new node _, err = cpmcontainerapi.RemoteWritefileClient("/pgdata/"+params.ContainerName+"/pg_hba.conf", data, fqdn) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } logit.Info.Println("PROFILE templates all built and copied to node") //start pg on new node var startResp cpmcontainerapi.StartPGResponse startResp, err = cpmcontainerapi.StartPGClient(fqdn) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } logit.Info.Println("startpg output was" + startResp.Output) //seed database with initial objects var seedResp cpmcontainerapi.SeedResponse seedResp, err = cpmcontainerapi.SeedClient(fqdn) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } logit.Info.Println("seed output was" + seedResp.Output) } logit.Info.Println("PROFILE node provisioning completed") return nil }
func ContainerInfoStatdatabase(w rest.ResponseWriter, r *rest.Request) { dbConn, err := util.GetConnection(CLUSTERADMIN_DB) if err != nil { logit.Error.Println("BackupNow: error " + err.Error()) rest.Error(w, err.Error(), 400) return } defer dbConn.Close() err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read") if err != nil { logit.Error.Println("ContainerStatdatabase: authorize error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") if ID == "" { rest.Error(w, "ID required", http.StatusBadRequest) return } node, err := admindb.GetContainer(dbConn, ID) if err != nil { logit.Error.Println("ContainerStatdatabase:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var host = node.Name if KubeEnv { host = node.Name + "-db" } //get password var nodeuser admindb.ContainerUser nodeuser, err = admindb.GetContainerUser(dbConn, node.Name, CPMTEST_USER) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //get port var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") dbConn2, err := util.GetMonitoringConnection(host, CPMTEST_DB, pgport.Value, CPMTEST_USER, nodeuser.Passwd) defer dbConn2.Close() stats := make([]Statdatabase, 0) var rows *sql.Rows rows, err = dbConn2.Query("SELECT datname, blks_read::text, tup_returned::text, tup_fetched::text, tup_inserted::text, tup_updated::text, tup_deleted::text, coalesce(to_char(stats_reset, 'YYYY-MM-DD HH24:MI:SS'), ' ') as stats_reset from pg_stat_database") if err != nil { logit.Error.Println("ContainerStatdatabase:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } defer rows.Close() for rows.Next() { stat := Statdatabase{} if err = rows.Scan( &stat.Datname, &stat.BlksRead, &stat.TupReturned, &stat.TupFetched, &stat.TupInserted, &stat.TupUpdated, &stat.TupDeleted, &stat.StatsReset, ); err != nil { logit.Error.Println("ContainerStatdatabase:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } stats = append(stats, stat) } if err = rows.Err(); err != nil { logit.Error.Println("ContainerStatdatabase:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } w.WriteHeader(http.StatusOK) w.WriteJson(&stats) }
func ContainerInfoBgwriter(w rest.ResponseWriter, r *rest.Request) { dbConn, err := util.GetConnection(CLUSTERADMIN_DB) if err != nil { logit.Error.Println("BackupNow: error " + err.Error()) rest.Error(w, err.Error(), 400) return } defer dbConn.Close() err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read") if err != nil { logit.Error.Println("ContainerBgwriter: authorize error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") if ID == "" { rest.Error(w, "ID required", http.StatusBadRequest) return } node, err := admindb.GetContainer(dbConn, ID) if err != nil { logit.Error.Println("ContainerBgwriter:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var host = node.Name if KubeEnv { host = node.Name + "-db" } //get password var nodeuser admindb.ContainerUser nodeuser, err = admindb.GetContainerUser(dbConn, node.Name, CPMTEST_USER) if err != nil { logit.Error.Println("ContainerBgwriter:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //get port var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") var dbConn2 *sql.DB dbConn2, err = util.GetMonitoringConnection(host, CPMTEST_DB, pgport.Value, CPMTEST_USER, nodeuser.Passwd) defer dbConn2.Close() info := Bgwriter{} err = dbConn2.QueryRow("SELECT to_char(now(), 'mm/dd/yy HH12:MI:SS') now, to_char(block_size::numeric * buffers_alloc / (1024 * 1024 * seconds), 'FM999999999999D9999') AS alloc_mbps, to_char(block_size::numeric * buffers_checkpoint / (1024 * 1024 * seconds), 'FM999999999999D9999') AS checkpoint_mbps, to_char(block_size::numeric * buffers_clean / (1024 * 1024 * seconds), 'FM999999999999D9999') AS clean_mbps, to_char(block_size::numeric * buffers_backend/ (1024 * 1024 * seconds), 'FM999999999999D9999') AS backend_mbps, to_char(block_size::numeric * (buffers_checkpoint + buffers_clean + buffers_backend) / (1024 * 1024 * seconds), 'FM999999999999D9999') AS write_mbps FROM ( SELECT now() AS sample,now() - stats_reset AS uptime,EXTRACT(EPOCH FROM now()) - extract(EPOCH FROM stats_reset) AS seconds, b.*,p.setting::integer AS block_size FROM pg_stat_bgwriter b,pg_settings p WHERE p.name='block_size') bgw").Scan(&info.Now, &info.AllocMbps, &info.CheckpointMbps, &info.CleanMbps, &info.BackendMbps, &info.WriteMbps) switch { case err == sql.ErrNoRows: logit.Error.Println("ContainerBgwriter:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return case err != nil: logit.Error.Println("ContainerBgwriter:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } w.WriteHeader(http.StatusOK) w.WriteJson(&info) }
func GetContainerUser(w rest.ResponseWriter, r *rest.Request) { dbConn, err := util.GetConnection(CLUSTERADMIN_DB) if err != nil { logit.Error.Println("BackupNow: error " + err.Error()) rest.Error(w, err.Error(), 400) return } defer dbConn.Close() err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read") if err != nil { logit.Error.Println("GetContainerUser: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ContainerID := r.PathParam("ContainerID") if ContainerID == "" { rest.Error(w, "ContainerID required", 400) return } Rolname := r.PathParam("Rolname") if Rolname == "" { rest.Error(w, "Rolname required", 400) return } //get container info node, err := admindb.GetContainer(dbConn, ContainerID) if err != nil { logit.Error.Println("AddContainUser: "******"-db" } //fetch user credentials var nodeuser admindb.ContainerUser nodeuser, err = admindb.GetContainerUser(dbConn, node.Name, Rolname) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //fetch cpmtest user credentials var cpmuser admindb.ContainerUser cpmuser, err = admindb.GetContainerUser(dbConn, node.Name, CPMTEST_USER) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //get port var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") dbConn2, err := util.GetMonitoringConnection(host, CPMTEST_DB, pgport.Value, CPMTEST_USER, cpmuser.Passwd) defer dbConn2.Close() query := "select rolname::text, rolsuper::text, rolinherit::text, rolcreaterole::text, rolcreatedb::text, rolcatupdate::text, rolcanlogin::text, rolreplication::text from pg_roles where rolname = '" + Rolname + "' order by rolname" logit.Info.Println(query) err = dbConn2.QueryRow(query).Scan( &nodeuser.Rolname, &nodeuser.Rolsuper, &nodeuser.Rolinherit, &nodeuser.Rolcreaterole, &nodeuser.Rolcreatedb, &nodeuser.Rolcatupdate, &nodeuser.Rolcanlogin, &nodeuser.Rolreplication) if err != nil { logit.Error.Println("GetContainerUser:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } w.WriteJson(&nodeuser) }
func UpdateContainerUser(w rest.ResponseWriter, r *rest.Request) { dbConn, err := util.GetConnection(CLUSTERADMIN_DB) if err != nil { logit.Error.Println("BackupNow: error " + err.Error()) rest.Error(w, err.Error(), 400) return } defer dbConn.Close() postMsg := NodeUser{} err = r.DecodeJsonPayload(&postMsg) if err != nil { logit.Error.Println("UpdateContainerUser: error in decode" + err.Error()) rest.Error(w, err.Error(), http.StatusInternalServerError) return } err = secimpl.Authorize(dbConn, postMsg.Token, "perm-user") if err != nil { logit.Error.Println("UpdateContainerUser: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } if postMsg.ID == "" { logit.Error.Println("UpdateContainerUser: error node ID required") rest.Error(w, "ID required", 400) return } if postMsg.Rolname == "" { logit.Error.Println("UpdateContainerUser: error node Rolname required") rest.Error(w, "Rolname required", 400) return } //create user on the container //get container info var node admindb.Container node, err = admindb.GetContainer(dbConn, postMsg.ID) if err != nil { logit.Error.Println("AddContainUser: "******"" { } else { //update the password } //get connection to container's database var host = node.Name if KubeEnv { host = node.Name + "-db" } //fetch cpmtest user credentials var cpmuser admindb.ContainerUser cpmuser, err = admindb.GetContainerUser(dbConn, node.Name, CPMTEST_USER) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //get port var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") var dbConn2 *sql.DB dbConn2, err = util.GetMonitoringConnection(host, CPMTEST_DB, pgport.Value, CPMTEST_USER, cpmuser.Passwd) defer dbConn2.Close() var SUPERUSER = "******" var INHERIT = "INHERIT" var CREATEROLE = "CREATEROLE" var CREATEDB = "CREATEDB" var LOGIN = "******" var REPLICATION = "REPLICATION" logit.Info.Println("Rolsuper is " + strconv.FormatBool(postMsg.Rolsuper)) if !postMsg.Rolsuper { SUPERUSER = "******" } if !postMsg.Rolinherit { INHERIT = "NOINHERIT" } if !postMsg.Rolcreaterole { CREATEROLE = "NOCREATEROLE" } if !postMsg.Rolcreatedb { CREATEDB = "NOCREATEDB" } if !postMsg.Rollogin { LOGIN = "******" } if !postMsg.Rolreplication { REPLICATION = "NOREPLICATION" } query := "alter user " + postMsg.Rolname + " " + SUPERUSER + " " + INHERIT + " " + CREATEROLE + " " + CREATEDB + " " + LOGIN + " " + REPLICATION + " " if postMsg.Passwd != "" { query = query + " PASSWORD '" + postMsg.Passwd + "'" } logit.Info.Println(query) _, err = dbConn2.Query(query) if err != nil { logit.Error.Println("UpdateContainerUser:"******"" { //update user's password dbuser := admindb.ContainerUser{} dbuser.Containername = node.Name dbuser.Passwd = postMsg.Passwd dbuser.Rolname = postMsg.Rolname err = admindb.UpdateContainerUser(dbConn, dbuser) if err != nil { logit.Error.Println("UpdateContainerUser: "******"OK" w.WriteJson(&status) }
func GetAllUsersForContainer(w rest.ResponseWriter, r *rest.Request) { dbConn, err := util.GetConnection(CLUSTERADMIN_DB) if err != nil { logit.Error.Println("BackupNow: error " + err.Error()) rest.Error(w, err.Error(), 400) return } defer dbConn.Close() err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read") if err != nil { logit.Error.Println("GetAllUsersForContainer: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") if ID == "" { rest.Error(w, "ID required", 400) return } //get container info var node admindb.Container node, err = admindb.GetContainer(dbConn, ID) if err != nil { logit.Error.Println("GetAllUsersForContainer: " + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //get connection to container's database var host = node.Name if KubeEnv { host = node.Name + "-db" } //fetch cpmtest user credentials var nodeuser admindb.ContainerUser nodeuser, err = admindb.GetContainerUser(dbConn, node.Name, CPMTEST_USER) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } logit.Info.Println("cpmtest password is " + nodeuser.Passwd) //get port var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") var dbConn2 *sql.DB dbConn2, err = util.GetMonitoringConnection(host, CPMTEST_DB, pgport.Value, CPMTEST_USER, nodeuser.Passwd) defer dbConn2.Close() users := make([]admindb.ContainerUser, 0) //query results var rows *sql.Rows rows, err = dbConn2.Query("select rolname::text, rolsuper::text, rolinherit::text, rolcreaterole::text, rolcreatedb::text, rolcatupdate::text, rolcanlogin::text, rolreplication::text from pg_roles order by rolname") if err != nil { logit.Error.Println("GetAllUsersForContainer:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } defer rows.Close() for rows.Next() { user := admindb.ContainerUser{} if err = rows.Scan( &user.Rolname, &user.Rolsuper, &user.Rolinherit, &user.Rolcreaterole, &user.Rolcreatedb, &user.Rolcatupdate, &user.Rolcanlogin, &user.Rolreplication, ); err != nil { logit.Error.Println("GetAllUsersForContainer:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } user.Containername = node.Name user.ContainerID = node.ID users = append(users, user) } if err = rows.Err(); err != nil { logit.Error.Println("GetAllUsersForContainer:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } w.WriteHeader(http.StatusOK) w.WriteJson(&users) }
func loadtest(dbConn *sql.DB, nodename string, host string, writes int) ([]Loadtestresults, error) { var err error var name string var query string var id int var i int var dbConn2 *sql.DB var results = make([]Loadtestresults, 4) //get port var pgport admindb.Setting pgport, err = admindb.GetSetting(dbConn, "PG-PORT") //fetch cpmtest user credentials var nodeuser admindb.ContainerUser nodeuser, err = admindb.GetContainerUser(dbConn, nodename, CPMTEST_USER) if err != nil { logit.Error.Println(err.Error()) return results, err } //get db connection dbConn2, err = util.GetMonitoringConnection(host, CPMTEST_USER, pgport.Value, CPMTEST_DB, nodeuser.Passwd) if err != nil { logit.Error.Println("loadtest connection error:" + err.Error()) return results, err } defer dbConn2.Close() start := time.Now() //inserts results[0].Operation = "inserts" results[0].Count = writes for i = 0; i < writes; i++ { query = fmt.Sprintf("insert into loadtest ( id, name ) values ( %d, 'this is a row for load test') returning id ", i) err = dbConn2.QueryRow(query).Scan(&id) switch { case err != nil: logit.Error.Println("loadtest insert error:" + err.Error()) return results, err } } results[0].Results = time.Since(start).String() start = time.Now() //selects results[1].Operation = "selects" results[1].Count = writes for i = 0; i < writes; i++ { err = dbConn2.QueryRow(fmt.Sprintf("select name from loadtest where id=%d", i)).Scan(&name) switch { case err == sql.ErrNoRows: logit.Error.Println("no row with that id") return results, err case err != nil: logit.Error.Println(err.Error()) return results, err } } results[1].Results = time.Since(start).String() start = time.Now() //updates results[2].Operation = "updates" results[2].Count = writes for i = 0; i < writes; i++ { query = fmt.Sprintf("update loadtest set ( name ) = ('howdy' ) where id = %d returning id", i) err = dbConn2.QueryRow(query).Scan(&id) switch { case err != nil: return results, err } } results[2].Results = time.Since(start).String() start = time.Now() //deletes results[3].Operation = "deletes" results[3].Count = writes for i = 0; i < writes; i++ { query = fmt.Sprintf("delete from loadtest where id=%d returning id", i) err := dbConn2.QueryRow(query).Scan(&id) switch { case err != nil: return results, err } } results[3].Results = time.Since(start).String() return results, nil }
func ProvisionBackupJob(dbConn *sql.DB, args *BackupRequest) error { logit.Info.Println("backup.Provision called") logit.Info.Println("with scheduleid=" + args.ScheduleID) logit.Info.Println("with serverid=" + args.ServerID) logit.Info.Println("with servername=" + args.ServerName) logit.Info.Println("with serverip=" + args.ServerIP) logit.Info.Println("with containername=" + args.ContainerName) logit.Info.Println("with profilename=" + args.ProfileName) params := &cpmserverapi.DockerRunRequest{} params.Image = "crunchydata/cpm-backup-job" params.ServerID = args.ServerID backupcontainername := args.ContainerName + "-backup" params.ContainerName = backupcontainername params.Standalone = "false" //get server info server, err := admindb.GetServer(dbConn, params.ServerID) if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } params.PGDataPath = server.PGDataPath + "/" + backupcontainername + "/" + getFormattedDate() //get the docker profile settings var setting admindb.Setting setting, err = admindb.GetSetting(dbConn, "S-DOCKER-PROFILE-CPU") params.CPU = setting.Value setting, err = admindb.GetSetting(dbConn, "S-DOCKER-PROFILE-MEM") params.MEM = setting.Value params.EnvVars = make(map[string]string) setting, err = admindb.GetSetting(dbConn, "DOMAIN-NAME") if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } var domain = setting.Value params.EnvVars["BACKUP_NAME"] = backupcontainername params.EnvVars["BACKUP_SERVERNAME"] = server.Name params.EnvVars["BACKUP_SERVERIP"] = server.IPAddress params.EnvVars["BACKUP_SCHEDULEID"] = args.ScheduleID params.EnvVars["BACKUP_PROFILENAME"] = args.ProfileName params.EnvVars["BACKUP_CONTAINERNAME"] = args.ContainerName params.EnvVars["BACKUP_PATH"] = params.PGDataPath params.EnvVars["BACKUP_HOST"] = args.ContainerName + "." + setting.Value setting, err = admindb.GetSetting(dbConn, "PG-PORT") if err != nil { logit.Error.Println("Provision:" + err.Error()) return err } params.EnvVars["BACKUP_PORT"] = setting.Value params.EnvVars["BACKUP_USER"] = "******" params.EnvVars["BACKUP_SERVER_URL"] = "cpm-backup" + "." + domain + ":" + "13000" //provision the volume request := &cpmserverapi.DiskProvisionRequest{"/tmp/foo"} request.Path = params.PGDataPath var url = "http://" + server.IPAddress + ":10001" _, err = cpmserverapi.DiskProvisionClient(url, request) if err != nil { logit.Error.Println(err.Error()) return err } //run the container params.CommandPath = "docker-run-backup.sh" var response cpmserverapi.DockerRunResponse url = "http://" + server.IPAddress + ":10001" response, err = cpmserverapi.DockerRunClient(url, params) if err != nil { logit.Error.Println("Provision: " + response.Output) return err } logit.Info.Println("docker-run-backup.sh output=" + response.Output) return nil }