func GetServer(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("GetServer: authorize error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") logit.Info.Println("in GetServer with ID=" + ID) results, err := admindb.GetServer(dbConn, ID) if err != nil { logit.Error.Println("GetServer:" + err.Error()) rest.Error(w, err.Error(), http.StatusInternalServerError) return } server := Server{results.ID, results.Name, results.IPAddress, results.DockerBridgeIP, results.PGDataPath, results.ServerClass, results.CreateDate} logit.Info.Println("GetServer: results=" + results.ID) w.WriteJson(&server) }
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 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 DeleteCluster(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("DeleteCluster: authorize error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ID := r.PathParam("ID") if ID == "" { logit.Error.Println("DeleteCluster: error cluster ID required") rest.Error(w, "cluster ID required", http.StatusBadRequest) return } cluster, err := admindb.GetCluster(dbConn, ID) if err != nil { logit.Error.Println("DeleteCluster:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) } //delete docker containers containers, err := admindb.GetAllContainersForCluster(dbConn, cluster.ID) if err != nil { logit.Error.Println("DeleteCluster:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) } i := 0 i = 0 server := admindb.Server{} for i = range containers { //go get the docker server IPAddress server, err = admindb.GetServer(dbConn, containers[i].ServerID) if err != nil { logit.Error.Println("DeleteCluster:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } logit.Info.Println("DeleteCluster: 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 //err = removeContainer(server.IPAddress, containers[i].Name) dremreq := &cpmserverapi.DockerRemoveRequest{} dremreq.ContainerName = containers[i].Name logit.Info.Println("will attempt to delete container " + dremreq.ContainerName) var url = "http://" + server.IPAddress + ":10001" _, err = cpmserverapi.DockerRemoveClient(url, dremreq) if err != nil { logit.Error.Println("DeleteCluster: error when trying to remove container" + err.Error()) } //send the server a deletevolume command url = "http://" + server.IPAddress + ":10001" ddreq := &cpmserverapi.DiskDeleteRequest{} ddreq.Path = server.PGDataPath + "/" + containers[i].Name _, err = cpmserverapi.DiskDeleteClient(url, ddreq) if err != nil { logit.Error.Println("DeleteCluster: error when trying to remove disk volume" + err.Error()) } i++ } //delete the container entries //delete the cluster entry admindb.DeleteCluster(dbConn, ID) for i = range containers { err = admindb.DeleteContainer(dbConn, containers[i].ID) if err != nil { logit.Error.Println("DeleteCluster:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } } status := SimpleStatus{} status.Status = "OK" w.WriteHeader(http.StatusOK) w.WriteJson(&status) }
//monitor server - get info func MonitorServerGetInfo(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("MonitorServerGetInfo: authorize error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } ServerID := r.PathParam("ServerID") Metric := r.PathParam("Metric") if ServerID == "" { logit.Error.Println("MonitorServerGetInfo: error ServerID required") rest.Error(w, "ServerID required", http.StatusBadRequest) return } if Metric == "" { logit.Error.Println("MonitorServerGetInfo: error metric required") rest.Error(w, "Metric required", http.StatusBadRequest) return } //go get the IPAddress server, err := admindb.GetServer(dbConn, ServerID) if err != nil { logit.Error.Println("MonitorServerGetInfo:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var output string url := "http://" + server.IPAddress + ":10001" if Metric == "cpmiostat" { iostatreq := cpmserverapi.MetricIostatRequest{} var iostatResp cpmserverapi.MetricIostatResponse iostatResp, err = cpmserverapi.MetricIostatClient(url, &iostatreq) if err != nil { logit.Error.Println("MonitorServerGetInfo:" + err.Error()) rest.Error(w, err.Error(), 400) return } output = iostatResp.Output } else if Metric == "cpmdf" { dfreq := cpmserverapi.MetricDfRequest{} var dfResp cpmserverapi.MetricDfResponse dfResp, err = cpmserverapi.MetricDfClient(url, &dfreq) if err != nil { logit.Error.Println("MonitorServerGetInfo:" + err.Error()) rest.Error(w, err.Error(), 400) return } output = dfResp.Output } else { logit.Error.Println("unknown Metric received") rest.Error(w, err.Error(), http.StatusBadRequest) return } w.(http.ResponseWriter).Write([]byte(output)) //w.Header().set("Content-Type", "text/json") w.WriteHeader(http.StatusOK) }
func AdminStopServerContainers(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("AdminStopServerContainers: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } //serverID serverid := r.PathParam("ID") if serverid == "" { logit.Error.Println("AdminStopoServerContainers: error ID required") rest.Error(w, "ID required", http.StatusBadRequest) return } //fetch the server containers, err := admindb.GetAllContainersForServer(dbConn, serverid) if err != nil { logit.Error.Println("AdminStopServerContainers:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } var url string //for each, get server, stop container for i := range containers { server := admindb.Server{} server, err = admindb.GetServer(dbConn, containers[i].ServerID) if err != nil { logit.Error.Println("AdminStopServerContainers:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //send stop command before stopping container if containers[i].Role == "pgpool" { var stoppoolResp cpmcontainerapi.StopPgpoolResponse stoppoolResp, err = cpmcontainerapi.StopPgpoolClient(containers[i].Name) logit.Info.Println("AdminStoppg:" + stoppoolResp.Output) } else { var stopResp cpmcontainerapi.StopPGResponse stopResp, err = cpmcontainerapi.StopPGClient(containers[i].Name) logit.Info.Println("AdminStoppg:" + stopResp.Output) } if err != nil { logit.Error.Println("AdminStopServerContainers:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } time.Sleep(2000 * time.Millisecond) //stop container request := &cpmserverapi.DockerStopRequest{} request.ContainerName = containers[i].Name url = "http://" + server.IPAddress + ":10001" _, err = cpmserverapi.DockerStopClient(url, request) if err != nil { logit.Error.Println("AdminStopServerContainers: error when trying to start container " + err.Error()) } } w.WriteHeader(http.StatusOK) status := SimpleStatus{} status.Status = "OK" w.WriteJson(&status) }
func AdminStartServerContainers(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("AdminStartServerContainers: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } //serverID serverid := r.PathParam("ID") if serverid == "" { logit.Error.Println("AdminStartServerContainers: error ID required") rest.Error(w, "ID required", http.StatusBadRequest) return } containers, err := admindb.GetAllContainersForServer(dbConn, serverid) if err != nil { logit.Error.Println("AdminStartServerContainers:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //for each, get server, start container //use a 'best effort' approach here since containers //can be removed outside of CPM's control var url string for i := range containers { //fetch the server server := admindb.Server{} server, err = admindb.GetServer(dbConn, containers[i].ServerID) if err != nil { logit.Error.Println("AdminStartServerContainers:" + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } //start the container var response cpmserverapi.DockerStartResponse var err error request := &cpmserverapi.DockerStartRequest{} request.ContainerName = containers[i].Name url = "http://" + server.IPAddress + ":10001" response, err = cpmserverapi.DockerStartClient(url, request) if err != nil { logit.Error.Println("AdminStartServerContainers: 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 GetAllNodesForServer(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("GetAllNodesForServer: validate token error " + err.Error()) rest.Error(w, err.Error(), http.StatusUnauthorized) return } serverID := r.PathParam("ServerID") if serverID == "" { logit.Error.Println("GetAllNodesForServer: error serverID required") rest.Error(w, "serverID required", http.StatusBadRequest) return } results, err := admindb.GetAllContainersForServer(dbConn, serverID) if err != nil { logit.Error.Println("GetAllNodesForServer:" + err.Error()) logit.Error.Println("error " + err.Error()) rest.Error(w, err.Error(), http.StatusBadRequest) return } server, err2 := admindb.GetServer(dbConn, serverID) if err2 != nil { logit.Error.Println("GetAllNodesForServer:" + err2.Error()) logit.Error.Println("error " + err2.Error()) rest.Error(w, err2.Error(), http.StatusBadRequest) return } var response cpmserverapi.DockerInspectResponse var e error var url string nodes := make([]ClusterNode, len(results)) i := 0 for i = range results { nodes[i].ID = results[i].ID nodes[i].Name = results[i].Name nodes[i].ClusterID = results[i].ClusterID nodes[i].ServerID = results[i].ServerID nodes[i].Role = results[i].Role nodes[i].Image = results[i].Image nodes[i].CreateDate = results[i].CreateDate nodes[i].ProjectID = results[i].ProjectID nodes[i].ProjectName = results[i].ProjectName nodes[i].ServerName = results[i].ServerName nodes[i].Status = "down" request := &cpmserverapi.DockerInspectRequest{} request.ContainerName = results[i].Name url = "http://" + server.IPAddress + ":10001" response, e = cpmserverapi.DockerInspectClient(url, request) logit.Info.Println("GetAllNodesForServer:" + results[i].Name + " " + response.IPAddress + " " + response.RunningState) if e != nil { logit.Error.Println("GetAllNodesForServer:" + e.Error()) logit.Error.Println(e.Error()) nodes[i].Status = "notfound" } else { logit.Info.Println("GetAllNodesForServer: setting " + results[i].Name + " to " + response.RunningState) nodes[i].Status = response.RunningState } i++ } w.WriteJson(&nodes) }
/* 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) }
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 }