Example #1
0
func httpAuth(h http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, request *http.Request) {
		if len(request.Header["Authorization"]) == 0 {
			log.Trace(fmt.Sprintf("httpAuth(): Authorization Required"))
			http.Error(w, "Authorization Required", http.StatusUnauthorized)
			return
		}

		auth := strings.SplitN(request.Header["Authorization"][0], " ", 2)
		if len(auth) != 2 || auth[0] != "Basic" {
			log.Error(fmt.Sprintf("httpAuth(): Unhandled Authorization Type, Expected Basic"))
			http.Error(w, "Unhandled Authroization Type, Expected Basic\n", http.StatusBadRequest)
			return
		}
		payload, err := base64.StdEncoding.DecodeString(auth[1])
		if err != nil {
			log.Error(fmt.Sprintf("httpAuth(): Authorization Failed"))
			http.Error(w, "Authorization Failed\n", http.StatusUnauthorized)
			return
		}
		nv := strings.SplitN(string(payload), ":", 2)
		if (len(nv) != 2) || !isAuthorized(nv[0], nv[1]) {
			log.Error(fmt.Sprintf("httpAuth(): Authorization Failed"))
			http.Error(w, "Authorization Failed\n", http.StatusUnauthorized)
			return
		}
		h(w, request)
	}
}
Example #2
0
// TODO: Instead pass back *sql.DB
func (r *RDPG) OpenDB(dbname string) error {
	if r.DB == nil {
		u, err := url.Parse(r.URI)
		if err != nil {
			log.Error(fmt.Sprintf("Failed parsing URI %s err: %s", r.URI, err))
		}
		u.Path = dbname
		r.URI = u.String()
		db, err := sqlx.Connect("postgres", r.URI)
		if err != nil {
			log.Error(fmt.Sprintf("Failed connecting to %s err: %s", rdpgURI, err))
			return err
		}
		r.DB = db
	} else {
		err := r.DB.Ping()
		if err != nil {
			db, err := sqlx.Connect("postgres", r.URI)
			if err != nil {
				log.Error(fmt.Sprintf("Failed connecting to %s err: %s", rdpgURI, err))
				proc, _ := os.FindProcess(os.Getpid())
				proc.Signal(syscall.SIGTERM)
				return err
			}
			r.DB = db
		}
	}
	return nil
}
Example #3
0
func (c *Catalog) Fetch() (err error) {
	r := rdpg.New()
	err = r.OpenDB("rdpg")
	if err != nil {
		log.Error(fmt.Sprintf("Failed fetching catalog from database: %s", err))
		return
	}
	db := r.DB

	err = db.Select(&c.Services, `SELECT service_id,name,description,bindable FROM cfsb.services;`)
	if err != nil {
		log.Error(fmt.Sprintf("Catalog#Fetch() selecting from cfsb.services %s", err.Error()))
		return
	}

	// TODO: Account for plans being associated with a service.
	for i, _ := range c.Services {
		service := &c.Services[i]
		err = db.Select(&service.Plans, `SELECT plan_id,name,description FROM cfsb.plans;`)
		if err != nil {
			log.Error(fmt.Sprintf("Catalog#Fetch() Service Plans %s", err.Error()))
			return
		}
		c.Services[i].Tags = []string{"rdpg", "postgresql"}
		// c.Services[i].Dashboard = DashboardClient{}
	}
	return
}
Example #4
0
func (n *Node) CreateDatabase(dbname, owner string) (err error) {
	n.Database = "postgres"
	db, err := n.Connect()
	if err != nil {
		log.Error(fmt.Sprintf("Node#CreateDatabase(%s) %s ! %s", dbname, n.Host, err))
		return
	}
	defer db.Close()

	sq := fmt.Sprintf(`CREATE DATABASE %s WITH OWNER %s TEMPLATE template0 ENCODING 'UTF8'`, dbname, owner)
	log.Trace(fmt.Sprintf(`Node#CreateDatabase(%s) %s > %s`, dbname, n.Host, sq))
	_, err = db.Query(sq)
	if err != nil {
		log.Error(fmt.Sprintf("Node#CreateDatabase(%s) %s ! %s", dbname, n.Host, err))
		return
	}

	sq = fmt.Sprintf(`REVOKE ALL ON DATABASE "%s" FROM public`, dbname)
	log.Trace(fmt.Sprintf(`Node#CreateDatabase(%s) %s > %s`, dbname, n.Host, sq))
	_, err = db.Exec(sq)
	if err != nil {
		log.Error(fmt.Sprintf("Node#CreateDatabase(%s) %s ! %s", dbname, n.Host, err))
	}

	sq = fmt.Sprintf(`GRANT ALL PRIVILEGES ON DATABASE %s TO %s`, dbname, owner)
	log.Trace(fmt.Sprintf(`Node#CreateDatabase(%s) %s > %s`, dbname, n.Host, sq))
	_, err = db.Query(sq)
	if err != nil {
		log.Error(fmt.Sprintf(`Node#CreateDatabase(%s) %s ! %s`, dbname, n.Host, err))
		return
	}
	return nil
}
Example #5
0
/*
(FC) GET /v2/catalog
*/
func CatalogHandler(w http.ResponseWriter, request *http.Request) {
	log.Trace(fmt.Sprintf("%s /v2/catalog", request.Method))
	switch request.Method {
	case "GET":
		c := Catalog{}
		err := c.Fetch()
		if err != nil {
			msg := fmt.Sprintf(`{"status": %d, "description": "%s"}`, http.StatusInternalServerError, err)
			log.Error(msg)
			http.Error(w, msg, http.StatusInternalServerError)
			return
		}
		jsonCatalog, err := json.Marshal(c)
		if err != nil {
			msg := fmt.Sprintf(`{"status": %d, "description": "%s"}`, http.StatusInternalServerError, err)
			log.Error(msg)
			http.Error(w, msg, http.StatusInternalServerError)
		} else {
			w.Header().Set("Content-Type", "application/json; charset=UTF-8")
			w.WriteHeader(http.StatusOK)
			w.Write(jsonCatalog)
		}
	default:
		msg := fmt.Sprintf(`{"status": %d, "description": "Allowed Methods: GET"}`, http.StatusMethodNotAllowed)
		log.Error(msg)
		http.Error(w, msg, http.StatusMethodNotAllowed)
	}
	return
}
Example #6
0
func (r *RDPG) CreateUser(username, password string) (err error) {
	for _, node := range r.Nodes() {
		node.Database = `postgres`
		db, err := node.Connect()
		if err != nil {
			log.Error(fmt.Sprintf(`RDPG#CreateUser(%s) %s ! %s`, username, node.Host, err))
			return err
		}

		// TODO: Check if user exists first
		sq := fmt.Sprintf(`CREATE USER %s;`, username)
		log.Trace(fmt.Sprintf(`RDPG#CreateUser(%s) %s > %s`, username, node.Host, sq))
		_, err = db.Exec(sq)
		if err != nil {
			log.Error(fmt.Sprintf("RDPG#CreateUser(%s) %s ! %s", username, node.Host, err))
			db.Close()
			return err
		}

		sq = fmt.Sprintf(`ALTER USER %s ENCRYPTED PASSWORD '%s'`, username, password)
		log.Trace(fmt.Sprintf(`RDPG#CreateUser(%s) %s > %s`, username, node.Host, sq))
		_, err = db.Exec(sq)
		if err != nil {
			log.Error(fmt.Sprintf("RDPG#CreateUser(%s) %s ! %s", username, node.Host, err))
		}
		db.Close()
	}
	return nil
}
Example #7
0
/*
POST /services/{service}/{action}
*/
func ServiceHandler(w http.ResponseWriter, request *http.Request) {
	vars := mux.Vars(request)
	log.Trace(fmt.Sprintf("%s /services/%s/%s", request.Method, vars["service"], vars["action"]))
	switch request.Method {
	case "PUT":
		service, err := NewService(vars["service"])
		if err != nil {
			log.Error(fmt.Sprintf("ServiceHandler(): NewService(%s)"))
			http.Error(w, `{"status": %d, "description": "%s"}`, http.StatusInternalServerError)
			return
		}

		switch vars["action"] {
		case "configure":
			err := service.Configure()
			if err != nil {
				msg := fmt.Sprintf(`{"status": %d, "description": "%s"}`, http.StatusInternalServerError, err)
				log.Error(msg)
				http.Error(w, msg, http.StatusInternalServerError)
			}
			msg := fmt.Sprintf(`{"status": %d, "description": "%s %s"}`, http.StatusOK, vars["service"], vars["action"])
			log.Trace(msg)
			w.WriteHeader(http.StatusOK)
			fmt.Fprintf(w, msg)
		default:
			msg := fmt.Sprintf(`{"status": %d, "description": "Invalid Action %s for %s"}`, http.StatusBadRequest, vars["action"], vars["service"])
			log.Error(msg)
			http.Error(w, msg, http.StatusBadRequest)
		}
	default:
		msg := fmt.Sprintf(`{"status": %d, "description": "Method not allowed %s"}`, http.StatusMethodNotAllowed, request.Method)
		log.Error(msg)
		http.Error(w, msg, http.StatusMethodNotAllowed)
	}
}
Example #8
0
func (r *RDPG) DropDatabase(dbname string) (err error) {
	nodes := r.Nodes()
	for i := len(nodes) - 1; i >= 0; i-- {
		node := nodes[i]

		node.Database = "postgres"
		db, err := node.Connect()
		if err != nil {
			log.Error(fmt.Sprintf("RDPG#DropDatabase(%s) %s ! %s", dbname, node.Host, err))
			return err
		}

		// sq := fmt.Sprintf(SELECT slot_name FROM pg_replication_slots WHERE database='%s',dbname);
		// pg_recvlogical --drop-slot

		// TODO: How do we drop a database in bdr properly?
		sq := fmt.Sprintf(`DROP DATABASE IF EXISTS %s`, dbname)
		log.Trace(fmt.Sprintf(`RDPG#DropDatabase(%s) %s DROP > %s`, dbname, node.Host, sq))
		_, err = db.Exec(sq)
		if err != nil {
			log.Error(fmt.Sprintf("RDPG#DropDatabase(%s) DROP %s ! %s", dbname, node.Host, err))
		}
		db.Close()
	}
	return nil
}
Example #9
0
func (r *RDPG) connect() (db *sqlx.DB, err error) {
	db, err = sqlx.Connect("postgres", r.URI)
	if err != nil {
		log.Error(fmt.Sprintf("rdpg.Node#Connect() %s ! %s", r.URI, err))
	}
	return db, err
}
Example #10
0
// TODO: RDPG Struct => RDPG Struct, allowing for multiple instances of RDPG
func NewRDPG(uri string) *RDPG {
	if uri == "" || uri[0:13] != "postgresql://" {
		log.Error(fmt.Sprintf("rdpg.NewRDPG() uri malformed ! %s", uri))
		return nil
	}
	return &RDPG{URI: uri}
}
Example #11
0
func RemoveBinding(bindingId string) (binding *Binding, err error) {
	binding, err = FindBinding(bindingId)
	if err != nil {
		log.Error(fmt.Sprintf(`cfsb.CreateBinding(%s) ! %s`, bindingId, err))
		return
	}
	r := rdpg.New()
	sq := `UPDATE cfsb.bindings SET ineffective_at = CURRENT_TIMESTAMP WHERE binding_id = $1;`
	log.Trace(fmt.Sprintf(`cfsb.RemoveBinding(%s) > %s`, bindingId, sq))
	r.OpenDB("rdpg")
	_, err = r.DB.Query(sq, bindingId)
	if err != nil {
		log.Error(fmt.Sprintf(`cfsb.CreateBinding(%s) ! %s`, bindingId, err))
	}
	r.DB.Close()
	return
}
Example #12
0
func (n *Node) Connect() (db *sqlx.DB, err error) {
	uri := n.URI()
	db, err = sqlx.Connect(`postgres`, uri) // n.LocalDSN)
	if err != nil {
		log.Error(fmt.Sprintf(`rdpg.Node#Connect() %s ! %s`, uri, err))
		return db, err
	}
	return db, nil
}
Example #13
0
func (i *Instance) Provision() (err error) {
	i.Pass = strings.ToLower(strings.Replace(rdpg.NewUUID().String(), "-", "", -1))
	r := rdpg.New()

	// TODO: Alter this logic based on "plan"
	err = r.CreateUser(i.User, i.Pass)
	if err != nil {
		log.Error(fmt.Sprintf("Instance#Provision(%s) CreateUser(%s) ! %s", i.InstanceId, i.User, err))
		return err
	}

	err = r.CreateDatabase(i.Database, i.User)
	if err != nil {
		log.Error(fmt.Sprintf("Instance#Provision(%s) CreateDatabase(%s,%s) ! %s", i.InstanceId, i.Database, i.User, err))
		return err
	}

	err = r.CreateReplicationGroup(i.Database)
	if err != nil {
		log.Error(fmt.Sprintf("Instance#Provision(%s) CreateReplicationGroup(%s) ! %s", i.InstanceId, i.Database, err))
		return err
	}

	r.OpenDB("rdpg")
	sq := `INSERT INTO cfsb.instances 
(instance_id, service_id, plan_id, organization_id, space_id, dbname, uname, pass)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8);
`
	_, err = r.DB.Query(sq, i.InstanceId, i.ServiceId, i.PlanId, i.OrganizationId, i.SpaceId, i.Database, i.User, i.Pass)
	if err != nil {
		log.Error(fmt.Sprintf(`Instance#Provision(%s) ! %s`, i.InstanceId, err))
	}

	nodes := r.Nodes()
	for _, node := range nodes {
		err := node.AdminAPI("PUT", "services/pgbouncer/configure")
		if err != nil {
			log.Error(fmt.Sprintf(`Instance#Provision(%s) %s ! %s`, i.InstanceId, node.Host, err))
		}
	}
	r.DB.Close()
	return nil
}
Example #14
0
func (i *Instance) Remove() (err error) {
	r := rdpg.New()
	r.OpenDB("rdpg")
	_, err = r.DB.Exec(`UPDATE cfsb.instances SET ineffective_at = CURRENT_TIMESTAMP WHERE id=$1`, i.Id)
	if err != nil {
		log.Error(fmt.Sprintf("Instance#Remove(%s) ! %s", i.InstanceId, err))
	}

	time.Sleep(1) // Wait for the update to propigate to the other nodes.

	for _, node := range r.Nodes() {
		err := node.AdminAPI("PUT", "services/pgbouncer/configure")
		if err != nil {
			log.Error(fmt.Sprintf(`Instance#Provision(%s) %s ! %s`, i.InstanceId, node.Host, err))
		}
	}
	r.DB.Close()
	return
}
Example #15
0
func (n *Node) CreateUser(name, password string) (err error) {
	if n.User != `postgres` {
		return errors.New(fmt.Sprintf(`Node user is not postgres, can not create a user with '%s'`, n.User))
	}

	uri := n.URI()
	db, err := sqlx.Connect(`postgres`, uri)
	if err != nil {
		log.Error(fmt.Sprintf(`Node#CreateUser(%s) %s ! %s`, name, uri, err))
		return err
	}
	defer db.Close()

	err = db.Get(&name, `SELECT rolname FROM pg_roles WHERE rolname=? LIMIT 1;`, name)
	if err != nil {
		log.Error(fmt.Sprintf(`Node#CreateUser(%s) %s ! %s`, name, n.Host, err))
		return err
	}
	if name != "" {
		log.Debug(fmt.Sprintf(`User %s already exists, skipping.`, name))
		return nil
	}

	sq := fmt.Sprintf(`CREATE USER %s WITH SUPERUSER CREATEDB CREATEROLE INHERIT;`, name)
	result, err := db.Exec(sq)
	rows, _ := result.RowsAffected()
	if rows > 0 {
		log.Debug(fmt.Sprintf(`Node#CreateUser(%s) %s User Created`, n.Host, name))
	}
	if err != nil {
		log.Error(fmt.Sprintf(`Node#CreateUser(%s) %s ! %s`, name, n.Host, err))
		return err
	}
	sq = fmt.Sprintf(`ALTER USER %s ENCRYPTED PASSWORD %s;`, name, password)
	_, err = db.Exec(sq)
	if err != nil {
		log.Error(fmt.Sprintf(`Node#CreateUser(%s) %s ! %s`, name, n.Host, err))
		return err
	}

	return nil
}
Example #16
0
func CreateBinding(instanceId, bindingId string) (binding *Binding, err error) {
	instance, err := FindInstance(instanceId)
	if err != nil {
		log.Error(fmt.Sprintf(`cfsb.CreateBinding(%s,%s) ! %s`, instanceId, bindingId, err))
		return
	}
	binding = &Binding{BindingId: bindingId, InstanceId: instanceId}

	dns := instance.ExternalDNS()
	s := strings.Split(dns, ":")

	binding.Creds = Credentials{
		URI:      instance.URI(),
		DSN:      instance.DSN(),
		JDBCURI:  "jdbc:" + instance.URI(),
		Host:     s[0],
		Port:     s[1],
		UserName: instance.User,
		Password: instance.Pass,
		Database: instance.Database,
	}

	r := rdpg.New()
	r.OpenDB("rdpg")

	sq := `INSERT INTO cfsb.bindings (instance_id,binding_id) VALUES ($1,$2);`
	_, err = r.DB.Query(sq, binding.InstanceId, binding.BindingId)
	if err != nil {
		log.Error(fmt.Sprintf(`cfsb.CreateBinding(%s) ! %s`, bindingId, err))
	}

	sq = `INSERT INTO cfsb.credentials (instance_id,binding_id,host,port,uname,pass,dbname) VALUES ($1,$2,$3,$4,$5,$6,$7);`
	_, err = r.DB.Query(sq, binding.InstanceId, binding.BindingId, binding.Creds.Host, binding.Creds.Port, binding.Creds.UserName, binding.Creds.Password, binding.Creds.Database)
	if err != nil {
		log.Error(fmt.Sprintf(`cfsb.CreateBinding(%s) ! %s`, bindingId, err))
	}

	r.DB.Close()

	return
}
Example #17
0
func (n *Node) CreateExtensions(exts []string) (err error) {
	db, err := n.Connect()
	if err != nil {
		log.Error(fmt.Sprintf("Node#CreateExtensions() %s ! %s", n.URI(), err))
		return
	}
	defer db.Close()

	_, err = db.Query(`CREATE EXTENSION IF NOT EXISTS btree_gist`)
	if err != nil {
		log.Error(fmt.Sprintf("Node#CreateExtensions() %s ! %s", n.Host, err))
		return
	}

	_, err = db.Query(`CREATE EXTENSION IF NOT EXISTS bdr`)
	if err != nil {
		log.Error(fmt.Sprintf("Node#CreateExtensions() %s ! %s", n.Host, err))
		return
	}
	return
}
Example #18
0
func FindPlan(planId string) (plan *Plan, err error) {
	r := rdpg.New()
	r.OpenDB("rdpg")
	plan = &Plan{}
	sq := `SELECT id,name,description FROM cfsb.plans WHERE id=$1 LIMIT 1;`
	err = r.DB.Get(&plan, sq, planId)
	if err != nil {
		log.Error(fmt.Sprintf("cfsb.FindPlan(%s) %s", planId, err))
	}
	r.DB.Close()
	return plan, err
}
Example #19
0
func (r *RDPG) DropUser(name string) (err error) {
	nodes := r.Nodes()
	for i := len(nodes) - 1; i >= 0; i-- {
		node := nodes[i]

		node.Database = "postgres"
		db, err := node.Connect()
		if err != nil {
			log.Error(fmt.Sprintf("RDPG#DropUser(%s) %s ! %s", name, node.Host, err))
			return err
		}

		sq := fmt.Sprintf(`DROP USER %s`, name)
		log.Trace(fmt.Sprintf(`RDPG#DropUser(%s) %s > %s`, name, node.Host, sq))
		_, err = db.Exec(sq)
		if err != nil {
			log.Error(fmt.Sprintf("RDPG#DropUser(%s) %s ! %s", name, node.Host, err))
		}
		db.Close()
	}
	return nil
}
Example #20
0
func (r *RDPG) Nodes() (nodes []Node) {
	db, err := r.connect()
	if err != nil {
		log.Error(fmt.Sprintf("RDPG#Nodes() ! %s", err))
	}

	// TODO: Populate list of rdpg nodes for given URL,
	//`SELECT node_local_dsn FROM bdr.bdr_nodes INTO rdpg.nodes (node_local_dsn);`

	type dsn struct {
		DSN string `db:"node_local_dsn"`
	}

	dsns := []dsn{}
	err = db.Select(&dsns, SQL["bdr_nodes_dsn"])
	if err != nil {
		log.Error(fmt.Sprintf("RDPG#Nodes() %s ! %s", SQL["bdr_nodes"], err))
	}

	for _, t := range dsns {
		node := Node{}
		s := strings.Split(t.DSN, " ")
		node.LocalDSN = t.DSN
		node.Host = strings.Split(s[0], "=")[1]
		node.Port = strings.Split(s[1], "=")[1]
		node.User = strings.Split(s[2], "=")[1]
		node.Database = `postgres` // strings.Split(s[3], "=")[1]
		nodes = append(nodes, node)
	}
	// TODO: Get this information into the database and then out of the rdpg.nodes
	//rows, err := db.Query("SELECT host,port,user,'postgres' FROM rdpg.nodes;")
	//if err != nil {
	//	log.Error(fmt.Sprintf("Nodes() %s", err))
	//} else {
	//	sqlx.StructScan(rows, nodes)
	//}
	db.Close()
	return nodes
}
Example #21
0
func (r *RDPG) DisableDatabase(dbname string) (err error) {
	nodes := r.Nodes()
	for i := len(nodes) - 1; i >= 0; i-- {
		node := nodes[i]

		node.Database = "postgres"
		db, err := node.Connect()
		if err != nil {
			log.Error(fmt.Sprintf("RDPG#DisableDatabase(%s) %s ! %s", dbname, node.Host, err))
			return err
		}
		sq := fmt.Sprintf(`SELECT rdpg.bdr_disable_database('%s');`, dbname)
		log.Trace(fmt.Sprintf(`RDPG#DisableDatabase(%s) DISABLE %s > %s`, dbname, node.Host, sq))
		_, err = db.Exec(sq)
		if err != nil {
			log.Error(fmt.Sprintf("RDPG#DisableDatabase(%s) DISABLE %s ! %s", dbname, node.Host, err))
		}
		db.Close()
	}

	return nil
}
Example #22
0
/*
(CB) PUT /v2/service_instances/:instance_id/service_bindings/:binding_id
(RB) DELETE /v2/service_instances/:instance_id/service_bindings/:binding_id
*/
func BindingHandler(w http.ResponseWriter, request *http.Request) {
	vars := mux.Vars(request)
	body, err := ioutil.ReadAll(request.Body)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(w, `{"status": %d,"description": %s}`, http.StatusInternalServerError, err)
		return
	}
	log.Trace(fmt.Sprintf("%s /v2/service_instances/:instance_id/service_bindings/:binding_id :: %+v :: %s", request.Method, vars, body))
	switch request.Method {
	case "PUT":
		binding, err := CreateBinding(vars["instance_id"], vars["binding_id"])
		if err != nil {
			log.Error(fmt.Sprintf("%s /v2/service_instances/:instance_id/service_bindings/:binding_id %s", request.Method, err))
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, `{"status": %d,"description": %s}`, http.StatusInternalServerError, err)
			return
		}
		j, err := json.Marshal(binding)
		if err != nil {
			log.Error(fmt.Sprintf("%s /v2/service_instances/:instance_id/service_bindings/:binding_id %s", request.Method, err))
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, `{"status": %d,"description": %s}`, http.StatusInternalServerError, err)
		} else {
			w.WriteHeader(http.StatusOK)
			w.Write(j)
			return
		}
	case "DELETE":
		// Question, do we need to do anything else?
		w.WriteHeader(http.StatusOK)
		fmt.Fprintf(w, `{"status": %d,"description": "Binding Removed"}`, http.StatusOK)
	default:
		w.WriteHeader(http.StatusMethodNotAllowed)
		fmt.Fprintf(w, `{"status": %d,"description": "Allowed Methods: PUT, DELETE"}`, http.StatusMethodNotAllowed)
		return
	}
}
Example #23
0
func FindInstance(instanceId string) (i *Instance, err error) {
	r := rdpg.New()
	in := Instance{}
	sq := `SELECT id, instance_id, service_id, plan_id, organization_id, space_id, dbname, uname, pass FROM cfsb.instances WHERE instance_id=lower($1) LIMIT 1;`
	r.OpenDB("rdpg")
	err = r.DB.Get(&in, sq, instanceId)
	if err != nil {
		// TODO: Change messaging if err is sql.NoRows then say couldn't find instance with instanceId
		log.Error(fmt.Sprintf("cfsb.FindInstance(%s) ! %s", instanceId, err))
	}
	r.DB.Close()
	i = &in
	return
}
Example #24
0
func Instances() (si []Instance, err error) {
	r := rdpg.New()
	r.OpenDB("rdpg")
	si = []Instance{}
	// TODO: Move this into a versioned SQL Function.
	sq := `SELECT instance_id, service_id, plan_id, organization_id, space_id, dbname, uname, 'md5'||md5(cfsb.instances.pass||uname) as pass FROM cfsb.instances WHERE ineffective_at IS NULL; `
	err = r.DB.Select(&si, sq)
	if err != nil {
		// TODO: Change messaging if err is sql.NoRows then say couldn't find instance with instanceId
		log.Error(fmt.Sprintf("cfsb.Instances() ! %s", err))
	}
	r.DB.Close()
	return
}
Example #25
0
func init() {
	rdpgURI = os.Getenv("RDPG_ADMIN_PG_URI")
	if rdpgURI == "" || rdpgURI[0:13] != "postgresql://" {
		log.Error("ERROR: RDPG_ADMIN_PG_URI is not set.")
		proc, _ := os.FindProcess(os.Getpid())
		proc.Signal(syscall.SIGTERM)
	}

	db, err := sqlx.Connect("postgres", rdpgURI)
	if err != nil {
		log.Error(fmt.Sprintf("Failed connecting to %s err: %s", rdpgURI, err))
		proc, _ := os.FindProcess(os.Getpid())
		proc.Signal(syscall.SIGTERM)
	}
	err = db.Ping()
	if err != nil {
		db.Close()
		log.Error(fmt.Sprintf("Unable to Ping %s err: %s", rdpgURI, err))
		proc, _ := os.FindProcess(os.Getpid())
		proc.Signal(syscall.SIGTERM)
	}
	db.Close()
}
Example #26
0
func (n *Node) AdminAPI(method, path string) (err error) {
	url := fmt.Sprintf("http://%s:%s/%s", n.Host, os.Getenv("RDPG_ADMIN_PORT"), path)
	req, err := http.NewRequest(method, url, bytes.NewBuffer([]byte(`{}`)))
	// req.Header.Set("Content-Type", "application/json")
	req.SetBasicAuth(os.Getenv("RDPG_ADMIN_USER"), os.Getenv("RDPG_ADMIN_PASS"))
	client := &http.Client{}
	log.Trace(fmt.Sprintf(`Node#AdminAPI(%s,%s) %s`, method, path, url))
	resp, err := client.Do(req)
	if err != nil {
		log.Error(fmt.Sprintf(`Node#AdminAPI(%s,%s) ! %s`, method, url, err))
	}
	resp.Body.Close()

	return
}
Example #27
0
func FindBinding(bindingId string) (binding *Binding, err error) {
	r := rdpg.New()
	b := Binding{}
	sq := `SELECT id,instance_id, binding_id FROM cfsb.bindings WHERE binding_id=lower($1) LIMIT 1;`
	log.Trace(fmt.Sprintf(`cfsb.FindBinding(%s) > %s`, bindingId, sq))
	r.OpenDB("rdpg")
	err = r.DB.Get(&b, sq, bindingId)
	if err != nil {
		// TODO: Change messaging if err is sql.NoRows then say couldn't find binding with bindingId
		log.Error(fmt.Sprintf("cfsb.FindBinding(%s) ! %s", bindingId, err))
	}
	r.DB.Close()
	binding = &b
	return
}
Example #28
0
func Check(check string) (status int) {
	r := rdpg.New()
	err := r.OpenDB("rdpg")
	if err != nil {
		log.Error(fmt.Sprintf("Error opening ! %s", r.URI))
		return http.StatusInternalServerError
	}

	switch check {
	case "ha_pb_pg":
		var numNodes int
		r.DB.Get(&numNodes, "SELECT count(node_name) FROM bdr.bdr_nodes;")
		if numNodes < 3 {
			return http.StatusInternalServerError
		}
	default:
		return http.StatusInternalServerError
	}
	return http.StatusOK
}
Example #29
0
func (r *RDPG) CreateReplicationGroup(dbname string) (err error) {
	nodes := r.Nodes()
	// TODO: Drop Database on all nodes if err != nil for any operation below
	for index, node := range nodes {
		node.Database = dbname
		db, err := node.Connect()
		if err != nil {
			break
		}
		sq := ""
		name := fmt.Sprintf("%s", node.Host)
		if index == 0 {
			sq = fmt.Sprintf(`SELECT bdr.bdr_group_create(
				local_node_name := '%s',
				node_external_dsn := 'host=%s port=%s user=%s dbname=%s'
			); `, name, node.Host, node.Port, node.User, dbname)
		} else {
			sq = fmt.Sprintf(`SELECT bdr.bdr_group_join(
				local_node_name := '%s',
				node_external_dsn := 'host=%s port=%s user=%s dbname=%s',
				join_using_dsn := 'host=%s port=%s user=%s dbname=%s'
			); `,
				name, node.Host, node.Port, node.User, node.Database,
				nodes[0].Host, nodes[0].Port, nodes[0].User, dbname,
			)
		}
		log.Trace(fmt.Sprintf(`RDPG#CreateReplicationGroup(%s) %s > %s`, dbname, node.Host, sq))
		_, err = db.Exec(sq)
		if err == nil {
			sq = `SELECT bdr.bdr_node_join_wait_for_ready();`
			log.Trace(fmt.Sprintf(`RDPG#CreateReplicationGroup(%s) %s > %s`, dbname, node.Host, sq))
			_, err = db.Exec(sq)
		}
		db.Close()
	}
	if err != nil {
		// Cleanup in BDR currently requires droping the database and trying again...
		log.Error(fmt.Sprintf("CreateReplicationGroup(%s) ! %s", dbname, err))
	}
	return err
}
Example #30
0
func (r *RDPG) BackupDatabase(dbname string) (err error) {
	log.Error(fmt.Sprintf("RDPG#BackupDatabase(%s) TODO: IMPLEMENT", dbname))
	return nil
}