func ContainerLoadTest(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("ContainerLoadTest: 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 } Writes := r.PathParam("Writes") if Writes == "" { rest.Error(w, "Writes required", http.StatusBadRequest) return } var writes int writes, err = strconv.Atoi(Writes) if err != nil { logit.Error.Println("ContainerLoadTest:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } node, err := admindb.GetContainer(dbConn, ID) if err != nil { logit.Error.Println("ContainerLoadTest:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var host = node.Name if KubeEnv { host = node.Name + "-db" } results, err2 := loadtest(dbConn, node.Name, host, writes) if err2 != nil { logit.Error.Println("ContainerLoadTest:" + err2.Error()) rest.Error(w, err2.Error(), http.StatusBadRequest) return } w.WriteHeader(http.StatusOK) w.WriteJson(&results) }
func MonitorContainerControldata(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("MonitorContainerControldata: 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("MonitorContainerControldata:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } settings := make([]PostgresControldata, 0) //send the container a pg_controldata command var cdout cpmcontainerapi.ControldataResponse cdout, err = cpmcontainerapi.ControldataClient(node.Name) if err != nil { logit.Error.Println("MonitorContainerControldata:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } logit.Info.Println(cdout.Output) lines := strings.Split(cdout.Output, "\n") //fmt.Println(len(lines)) for i := range lines { //fmt.Println(len(lines[i])) if len(lines[i]) > 1 { setting := PostgresControldata{} columns := strings.Split(lines[i], ":") setting.Name = strings.TrimSpace(columns[0]) setting.Value = strings.TrimSpace(columns[1]) //fmt.Println("name=[" + strings.TrimSpace(columns[0]) + "] value=[" + strings.TrimSpace(columns[1]) + "]") settings = append(settings, setting) } } w.WriteHeader(http.StatusOK) w.WriteJson(&settings) }
func AdminStoppg(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-cluster") if err != nil { logit.Error.Println("AdminStoppg: authorize error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } logit.Info.Println("AdminStoppg:called") ID := r.PathParam("ID") if ID == "" { logit.Error.Println("AdminStoppg:ID not found error") rest.Error(w, "node ID required", http.StatusBadRequest) return } var dbNode admindb.Container dbNode, err = admindb.GetContainer(dbConn, ID) if err != nil { logit.Error.Println("AdminStartpg: " + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } logit.Info.Println("AdminStoppg: in stop with dbnode") if dbNode.Role == "pgpool" { var stoppoolResp cpmcontainerapi.StopPgpoolResponse stoppoolResp, err = cpmcontainerapi.StopPgpoolClient(dbNode.Name) logit.Info.Println("AdminStoppg:" + stoppoolResp.Output) } else { var stoppgResp cpmcontainerapi.StopPGResponse stoppgResp, err = cpmcontainerapi.StopPGClient(dbNode.Name) logit.Info.Println("AdminStoppg:" + stoppgResp.Output) } if err != nil { logit.Error.Println("AdminStoppg:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //give the UI a chance to see the stop time.Sleep(3000 * time.Millisecond) w.WriteHeader(http.StatusOK) status := SimpleStatus{} status.Status = "OK" w.WriteJson(&status) }
func AdminStartNode(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("AdminStartNode: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") if ID == "" { logit.Error.Println("AdminStartNode: error ID required") rest.Error(w, "ID required", http.StatusBadRequest) return } node, err := admindb.GetContainer(dbConn, ID) if err != nil { logit.Error.Println("AdminStartNode:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } server := admindb.Server{} server, err = admindb.GetServer(dbConn, node.ServerID) if err != nil { logit.Error.Println("AdminStartNode:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var url = "http://" + server.IPAddress + ":10001" var response cpmserverapi.DockerStartResponse request := &cpmserverapi.DockerStartRequest{} request.ContainerName = node.Name response, err = cpmserverapi.DockerStartClient(url, request) if err != nil { logit.Error.Println("AdminStartNode: error when trying to start container " + err.Error()) } logit.Info.Println(response.Output) w.WriteHeader(http.StatusOK) status := SimpleStatus{} status.Status = "OK" w.WriteJson(&status) }
func BadgerGenerate(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("BadgerGenerate: 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("BadgerGenerate:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var host = container.Name if KubeEnv { host = container.Name + "-db" } //send the container a pg_controldata command var cdout cpmcontainerapi.BadgerGenerateResponse cdout, err = cpmcontainerapi.BadgerGenerateClient(host) if err != nil { logit.Error.Println("BadgerGenerate:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } logit.Info.Println(cdout.Output) w.WriteHeader(http.StatusOK) w.WriteJson(&cdout) }
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 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 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 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 AdminFailover(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-cluster") if err != nil { logit.Error.Println("AdminFailover: authorize error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") if ID == "" { logit.Error.Println("AdminFailover: node ID required error") rest.Error(w, "node ID required", http.StatusBadRequest) return } //dbNode is the standby node we are going to fail over and //make the new master in the cluster var dbNode admindb.Container dbNode, err = admindb.GetContainer(dbConn, ID) if err != nil { logit.Error.Println("AdminFailover:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } cluster, err := admindb.GetCluster(dbConn, dbNode.ClusterID) if err != nil { logit.Error.Println("AdminFailover:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var failoverResp cpmcontainerapi.FailoverResponse failoverResp, err = cpmcontainerapi.FailoverClient(dbNode.Name) if err != nil { logit.Error.Println("AdminFailover: fail-over error " + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } logit.Info.Println("AdminFailover: fail-over output " + failoverResp.Output) //update the old master to standalone role oldMaster := admindb.Container{} oldMaster, err = admindb.GetContainerMaster(dbConn, dbNode.ClusterID) if err != nil { logit.Error.Println("AdminFailover:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } oldMaster.Role = "standalone" oldMaster.ClusterID = "-1" err = admindb.UpdateContainer(dbConn, oldMaster) if err != nil { logit.Error.Println("AdminFailover:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //update the failover node to master role dbNode.Role = "master" err = admindb.UpdateContainer(dbConn, dbNode) if err != nil { logit.Error.Println("AdminFailover:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //stop pg on the old master //params.IPAddress1 = oldMaster.IPAddress var stopPGResp cpmcontainerapi.StopPGResponse stopPGResp, err = cpmcontainerapi.StopPGClient(oldMaster.Name) if err != nil { logit.Error.Println("AdminFailover: " + err.Error() + stopPGResp.Output) rest.Error(w, err.Error(), http.StatusBadRequest) return } err = configureCluster(dbConn, cluster, false) if err != nil { logit.Error.Println(err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } w.WriteHeader(http.StatusOK) status := SimpleStatus{} status.Status = "OK" w.WriteJson(&status) return }
func GetNode(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("GetNode: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") if ID == "" { logit.Error.Println("GetNode: error node ID required") rest.Error(w, "node ID required", http.StatusBadRequest) return } results, err2 := admindb.GetContainer(dbConn, ID) if results.ID == "" { rest.NotFound(w, r) return } if err2 != nil { logit.Error.Println("GetNode: " + err2.Error()) rest.Error(w, err2.Error(), http.StatusBadRequest) return } var currentStatus = "UNKNOWN" //go get the docker server IPAddress /** server := admindb.Server{} server, err = admindb.GetServer(dbConn, results.ServerID) if err != nil { logit.Error.Println("GetNode: " + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } */ var domain string domain, err = admindb.GetDomain(dbConn) if err != nil { logit.Error.Println("GetNode: " + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } /** request := &cpmserverapi.DockerInspectRequest{} request.ContainerName = results.Name var url = "http://" + server.IPAddress + ":10001" _, err = cpmserverapi.DockerInspectClient(url, request) if err != nil { logit.Error.Println("GetNode: " + err.Error()) currentStatus = CONTAINER_NOT_FOUND } */ //if currentStatus != "CONTAINER NOT FOUND" { //ping the db on that node to get current status var pinghost = results.Name logit.Info.Println("pinging db on " + pinghost + "." + domain) currentStatus, err = GetPGStatus2(dbConn, results.Name, pinghost) if err != nil { logit.Error.Println("GetNode:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } logit.Info.Println("pinging db finished") //} node := ClusterNode{results.ID, results.ClusterID, results.ServerID, results.Name, results.Role, results.Image, results.CreateDate, currentStatus, results.ProjectID, results.ProjectName, results.ServerName, results.ClusterName} w.WriteJson(node) }
func performConfigUpdate(dbConn *sql.DB, ContainerID string) error { logit.Info.Println("performConfigUpdate....") cars, err := GetAllContainerAccessRule(dbConn, ContainerID) if err != nil { logit.Error.Println(err.Error()) return err } container, err := admindb.GetContainer(dbConn, ContainerID) if err != nil { logit.Error.Println("GetNode: " + err.Error()) return err } var currentStatus string currentStatus, err = GetPGStatus2(dbConn, container.Name, container.Name) if err != nil { logit.Error.Println("GetNode:" + err.Error()) return err } if currentStatus != "RUNNING" { logit.Info.Println("performConfigUpdate....starting postgres") if container.Role == "pgpool" { var spgresp cpmcontainerapi.StartPgpoolResponse spgresp, err = cpmcontainerapi.StartPgpoolClient(container.Name) logit.Info.Println("AdminStartpg:" + spgresp.Output) } else { var srep cpmcontainerapi.StartPGResponse srep, err = cpmcontainerapi.StartPGClient(container.Name) logit.Info.Println("AdminStartpg:" + srep.Output) } if err != nil { logit.Error.Println("AdminStartpg:" + err.Error()) return err } //give the UI a chance to see the start time.Sleep(5000 * time.Millisecond) } //make template changes here logit.Info.Println("performConfigUpdate....making template changes") templateChange(dbConn, container.Name, cars, container.Role) //restart postgres logit.Info.Println("performConfigUpdate....stopping postgres") if container.Role == "pgpool" { var stoppoolResp cpmcontainerapi.StopPgpoolResponse stoppoolResp, err = cpmcontainerapi.StopPgpoolClient(container.Name) logit.Info.Println("AdminStoppg:" + stoppoolResp.Output) } else { var stoppgResp cpmcontainerapi.StopPGResponse stoppgResp, err = cpmcontainerapi.StopPGClient(container.Name) logit.Info.Println("AdminStoppg:" + stoppgResp.Output) } if err != nil { logit.Error.Println("AdminStoppg:" + err.Error()) return err } //give the UI a chance to see the stop time.Sleep(5000 * time.Millisecond) logit.Info.Println("performConfigUpdate....starting postgres") if container.Role == "pgpool" { var spgresp cpmcontainerapi.StartPgpoolResponse spgresp, err = cpmcontainerapi.StartPgpoolClient(container.Name) logit.Info.Println("AdminStartpg:" + spgresp.Output) } else { var srep cpmcontainerapi.StartPGResponse srep, err = cpmcontainerapi.StartPGClient(container.Name) logit.Info.Println("AdminStartpg:" + srep.Output) } if err != nil { logit.Error.Println("AdminStartpg:" + err.Error()) return err } return err }
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 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 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 EventJoinCluster(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-cluster") if err != nil { logit.Error.Println("EventJoinCluster: authorize error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } IDList := r.PathParam("IDList") if IDList == "" { logit.Error.Println("EventJoinCluster: error IDList required") rest.Error(w, "IDList required", http.StatusBadRequest) return } else { logit.Info.Println("EventJoinCluster: IDList=[" + IDList + "]") } MasterID := r.PathParam("MasterID") if MasterID == "" { logit.Error.Println("EventJoinCluster: error MasterID required") rest.Error(w, "MasterID required", http.StatusBadRequest) return } else { logit.Info.Println("EventJoinCluster: MasterID=[" + MasterID + "]") } ClusterID := r.PathParam("ClusterID") if ClusterID == "" { logit.Error.Println("EventJoinCluster: error ClusterID required") rest.Error(w, "node ClusterID required", http.StatusBadRequest) return } else { logit.Info.Println("EventJoinCluster: ClusterID=[" + ClusterID + "]") } var idList = strings.Split(IDList, "_") i := 0 pgpoolCount := 0 origDBNode := admindb.Container{} for i = range idList { if idList[i] != "" { logit.Info.Println("EventJoinCluster: idList[" + strconv.Itoa(i) + "]=" + idList[i]) origDBNode, err = admindb.GetContainer(dbConn, idList[i]) if err != nil { logit.Error.Println("EventJoinCluster:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //update the node to be in the cluster origDBNode.ClusterID = ClusterID if origDBNode.Image == CPM_NODE_IMAGE { origDBNode.Role = STANDBY } else { origDBNode.Role = "pgpool" pgpoolCount++ } if pgpoolCount > 1 { logit.Error.Println("EventJoinCluster: more than 1 pgpool is in the cluster") rest.Error(w, "only 1 pgpool is allowed in a cluster", http.StatusBadRequest) return } err = admindb.UpdateContainer(dbConn, origDBNode) if err != nil { logit.Error.Println("EventJoinCluster:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } } i++ } //we use the -1 value to indicate that we are only adding //to an existing cluster, the UI doesn't know who the master //is at this point if MasterID != "-1" { //update the master node origDBNode, err = admindb.GetContainer(dbConn, MasterID) if err != nil { logit.Error.Println("EventJoinCluster:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } origDBNode.ClusterID = ClusterID origDBNode.Role = "master" err = admindb.UpdateContainer(dbConn, origDBNode) if err != nil { logit.Error.Println("EventJoinCluster:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } } w.WriteHeader(http.StatusOK) status := SimpleStatus{} status.Status = "OK" w.WriteJson(&status) }
/* TODO refactor this to share code with DeleteCluster!!!!! */ func DeleteNode(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-container") if err != nil { logit.Error.Println("DeleteNode: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") if ID == "" { logit.Error.Println("DeleteNode: error node ID required") rest.Error(w, "node ID required", http.StatusBadRequest) return } //go get the node we intend to delete var dbNode admindb.Container dbNode, err = admindb.GetContainer(dbConn, ID) if err != nil { logit.Error.Println("DeleteNode: " + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //go get the docker server IPAddress server := admindb.Server{} server, err = admindb.GetServer(dbConn, dbNode.ServerID) if err != nil { logit.Error.Println("DeleteNode: " + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var url = "http://" + server.IPAddress + ":10001" err = admindb.DeleteContainer(dbConn, ID) if err != nil { logit.Error.Println("DeleteNode: " + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } logit.Info.Println("got server IP " + server.IPAddress) //it is possible that someone can remove a container //outside of us, so we let it pass that we can't remove //it request := &cpmserverapi.DockerRemoveRequest{} request.ContainerName = dbNode.Name _, err = cpmserverapi.DockerRemoveClient(url, request) if err != nil { logit.Error.Println("DeleteNode: error when trying to remove container " + err.Error()) } //send the server a deletevolume command request2 := &cpmserverapi.DiskDeleteRequest{} request2.Path = server.PGDataPath + "/" + dbNode.Name _, err = cpmserverapi.DiskDeleteClient(url, request2) if err != nil { fmt.Println(err.Error()) } //we should not have to delete the DNS entries because //of the dnsbridge, it should remove them when we remove //the containers via the docker api w.WriteHeader(http.StatusOK) status := SimpleStatus{} status.Status = "OK" w.WriteJson(&status) }