func process(node *types.Container, credential *types.Credential, gauge *prometheus.GaugeVec) error {
	var err error

	//logit.Info.Println("dbsize node=" + node.Name + " credentials Username:"******" Password:"******" Database:" + credential.Database + " Host:" + credential.Host)
	var db *sql.DB
	db, err = util.GetMonitoringConnection(credential.Host,
		credential.Username, credential.Port, credential.Database, credential.Password)
	defer db.Close()
	if err != nil {
		logit.Error.Println("error in getting connectionto " + credential.Host)
		return err
	}

	var metrics []DBMetric
	//logit.Info.Println("dbsize running pg2 on " + node.Name)
	metrics, err = pg2(db)

	//write metrcs to prometheus

	i := 0
	for i = range metrics {
		//logit.Info.Println("dbsize setting dbsize metric")
		gauge.WithLabelValues(node.Name, metrics[i].Name).Set(metrics[i].Value)
		i++
	}

	return nil

}
// TODO refactor with other ping routine
func ping(credential *types.Credential) (string, error) {
	var db *sql.DB
	var err error

	db, err = util.GetMonitoringConnection(credential.Host,
		credential.Username, credential.Port, credential.Database,
		credential.Password)
	defer db.Close()
	if err != nil {
		logit.Error.Println("error in getting connectionto " + credential.Host)
		return "down", err
	}

	var result string
	err = db.QueryRow("select now()::text").Scan(&result)
	if err != nil {
		logit.Error.Println("could not ping db on " + credential.Host)
		return "down", err
	}
	return "up", nil

}
// GetDatabaseStatus returns a simple status of a container database
func GetDatabaseStatus(proxy types.Proxy, containerid string) (string, error) {
	/**
	node, err := GetContainer(dbConn, containerid)
	if err != nil {
		logit.Error.Println(err.Error())
		return "", err
	}

	var credential types.Credential
	credential, err = GetUserCredentials(dbConn, &node)
	if err != nil {
		logit.Error.Println(err.Error())
		return "", err
	}
	*/

	dbConn2, err := util.GetMonitoringConnection(proxy.Host, proxy.Usename, proxy.Port, proxy.Database, proxy.Passwd)
	defer dbConn2.Close()

	var value string

	err = dbConn2.QueryRow(fmt.Sprintf("select now()::text")).Scan(&value)
	switch {
	case err == sql.ErrNoRows:
		logit.Info.Println("getProxyStatus  no rows returned")
		return "OFFLINE", nil
	case err != nil:
		logit.Info.Println("getProxyStatus error " + err.Error())
		return "OFFLINE", nil
	default:
		logit.Info.Println("getProxyStatus returned " + value)
	}

	return "RUNNING", nil

}
// UpdateContainerUser updates a database users preferences on a given container db
func UpdateContainerUser(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()

	postMsg := types.NodeUser{}
	err = r.DecodeJsonPayload(&postMsg)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	err = secimpl.Authorize(dbConn, postMsg.Token, "perm-user")
	if err != nil {
		logit.Error.Println(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 types.Container
	node, err = admindb.GetContainer(dbConn, postMsg.ID)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if postMsg.Passwd == "" {
	} else {
		//update the password
	}

	var credential types.Credential
	credential, err = admindb.GetUserCredentials(dbConn, &node)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var dbConn2 *sql.DB
	dbConn2, err = util.GetMonitoringConnection(credential.Host,
		credential.Username,
		credential.Port, credential.Database, credential.Password)

	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(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var userexists = true
	_, err = admindb.GetContainerUser(dbConn, node.Name, postMsg.Rolname)
	if err == sql.ErrNoRows {
		// Handle no rows
		userexists = false
	} else if err != nil {
		// Handle actual error
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), 400)
		return
	}

	if postMsg.Passwd != "" {
		//update user's password
		dbuser := types.ContainerUser{}
		dbuser.Containername = node.Name
		dbuser.Passwd = postMsg.Passwd
		dbuser.Rolname = postMsg.Rolname

		if userexists {
			err = admindb.UpdateContainerUser(dbConn, dbuser)
			if err != nil {
				logit.Error.Println(err.Error())
				rest.Error(w, err.Error(), 400)
				return
			}
		}
	}

	w.WriteHeader(http.StatusOK)
	status := types.SimpleStatus{}
	status.Status = "OK"
	w.WriteJson(&status)
}
// GetAllusersForContainer returns a list of all database users on a given db container
func GetAllUsersForContainer(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println(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(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 types.Container
	node, err = admindb.GetContainer(dbConn, ID)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var credential types.Credential
	credential, err = admindb.GetUserCredentials(dbConn, &node)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var dbConn2 *sql.DB
	dbConn2, err = util.GetMonitoringConnection(credential.Host,
		credential.Username,
		credential.Port, credential.Database, credential.Password)
	defer dbConn2.Close()

	users := make([]types.ContainerUser, 0)

	//query results
	var rows *sql.Rows

	rows, err = dbConn2.Query("select rolname::text, rolsuper::text, rolinherit::text, rolcreaterole::text, rolcreatedb::text, rolcanlogin::text, rolreplication::text from pg_roles order by rolname")
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	defer rows.Close()

	for rows.Next() {
		user := types.ContainerUser{}
		if err = rows.Scan(
			&user.Rolname,
			&user.Rolsuper,
			&user.Rolinherit,
			&user.Rolcreaterole,
			&user.Rolcreatedb,
			&user.Rolcanlogin,
			&user.Rolreplication,
		); err != nil {
			logit.Error.Println(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(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	w.WriteHeader(http.StatusOK)
	w.WriteJson(&users)

}
// AddContainerUser creates a new database user for a given container
func AddContainerUser(w rest.ResponseWriter, r *rest.Request) {
	postMsg := types.NodeUser{}
	err := r.DecodeJsonPayload(&postMsg)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	var dbConn *sql.DB
	dbConn, err = util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()

	err = secimpl.Authorize(dbConn, postMsg.Token, "perm-user")
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	if postMsg.ID == "" {
		logit.Error.Println("AddContainerUser: error node ID required")
		rest.Error(w, "ID required", 400)
		return
	}

	if postMsg.Rolname == "" {
		logit.Error.Println("AddContainerUser: error node Rolname required")
		rest.Error(w, "Rolname required", 400)
		return
	}
	if postMsg.Passwd == "" {
		logit.Error.Println("AddContainerUser: error node Passwd required")
		rest.Error(w, "Passwd required", 400)
		return
	}

	//create user on the container
	//get container info
	node, err := admindb.GetContainer(dbConn, postMsg.ID)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var credential types.Credential
	credential, err = admindb.GetUserCredentials(dbConn, &node)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var dbConn2 *sql.DB
	dbConn2, err = util.GetMonitoringConnection(credential.Host,
		credential.Username,
		credential.Port, credential.Database, credential.Password)
	defer dbConn2.Close()

	var SUPERUSER = ""
	var INHERIT = ""
	var CREATEROLE = ""
	var CREATEDB = ""
	var LOGIN = ""
	var REPLICATION = ""

	//logit.Info.Println("Rolsuper is " + strconv.FormatBool(postMsg.Rolsuper))
	if postMsg.Rolsuper {
		SUPERUSER = "******"
	}
	if postMsg.Rolinherit {
		INHERIT = "INHERIT"
	}
	if postMsg.Rolcreaterole {
		CREATEROLE = "CREATEROLE"
	}
	if postMsg.Rolcreatedb {
		CREATEDB = "CREATEDB"
	}
	if postMsg.Rollogin {
		LOGIN = "******"
	}
	if postMsg.Rolreplication {
		REPLICATION = "REPLICATION"
	}
	query := "create user " + postMsg.Rolname + " " +
		SUPERUSER + " " +
		INHERIT + " " +
		CREATEROLE + " " +
		CREATEDB + " " +
		LOGIN + " " +
		REPLICATION + " " +
		"PASSWORD '" + postMsg.Passwd + "'"

	logit.Info.Println(query)

	_, err = dbConn2.Query(query)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	//create user in the admin db
	dbuser := types.ContainerUser{}
	dbuser.Containername = node.Name
	dbuser.Passwd = postMsg.Passwd
	dbuser.Rolname = postMsg.Rolname

	result, err := admindb.AddContainerUser(dbConn, dbuser)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), 400)
		return
	}

	logit.Info.Printf("AddContainerUser: new ID %d\n", result)

	w.WriteHeader(http.StatusOK)
	status := types.SimpleStatus{}
	status.Status = "OK"
	w.WriteJson(&status)
}
// GetContainerUser returns a database user for a given container
func GetContainerUser(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println(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(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(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var credential types.Credential
	credential, err = admindb.GetUserCredentials(dbConn, &node)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var dbConn2 *sql.DB
	dbConn2, err = util.GetMonitoringConnection(credential.Host,
		credential.Username,
		credential.Port, credential.Database, credential.Password)

	defer dbConn2.Close()

	query := "select rolname::text, rolsuper::text, rolinherit::text, rolcreaterole::text, rolcreatedb::text, rolcanlogin::text, rolreplication::text from pg_roles where rolname = '" + Rolname + "' order by rolname"

	logit.Info.Println(query)

	nodeuser := types.ContainerUser{}

	err = dbConn2.QueryRow(query).Scan(
		&nodeuser.Rolname,
		&nodeuser.Rolsuper,
		&nodeuser.Rolinherit,
		&nodeuser.Rolcreaterole,
		&nodeuser.Rolcreatedb,
		&nodeuser.Rolcanlogin,
		&nodeuser.Rolreplication)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	w.WriteJson(&nodeuser)

}
// DeleteContainerUser deletes a database user on a given container
func DeleteContainerUser(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println(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(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(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var userexists = true
	_, err = admindb.GetContainerUser(dbConn, node.Name, rolname)
	if err == sql.ErrNoRows {
		// Handle no rows
		userexists = false
	} else if err != nil {
		// Handle actual error
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), 400)
		return
	}

	//only delete if there is a container user
	if userexists {
		err = admindb.DeleteContainerUser(dbConn, node.Name, rolname)
		if err != nil {
			logit.Error.Println(err.Error())
			rest.Error(w, err.Error(), 400)
			return
		}
	}

	var credential types.Credential
	credential, err = admindb.GetUserCredentials(dbConn, &node)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var dbConn2 *sql.DB
	dbConn2, err = util.GetMonitoringConnection(credential.Host,
		credential.Username,
		credential.Port, credential.Database, credential.Password)
	defer dbConn2.Close()

	query := "drop role " + rolname

	logit.Info.Println(query)

	_, err = dbConn2.Query(query)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	w.WriteHeader(http.StatusOK)
	status := types.SimpleStatus{}
	status.Status = "OK"
	w.WriteJson(&status)

}