Beispiel #1
0
func (i *Instance) ExternalDNS() (dns string) {
	// TODO: Figure out where we'll store and retrieve the external DNS information
	r := rdpg.New()
	nodes := r.Nodes()
	// TODO: Import the external DNS host via env variable configuration.
	return nodes[0].Host + ":5432"
}
Beispiel #2
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
}
Beispiel #3
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
}
Beispiel #4
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
}
Beispiel #5
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
}
Beispiel #6
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
}
Beispiel #7
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
}
Beispiel #8
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
}
Beispiel #9
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
}
Beispiel #10
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
}
Beispiel #11
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
}
Beispiel #12
0
func (s *Service) Configure() (err error) {
	log.Trace(fmt.Sprintf(`Service#Configure(%s)`, s.Name))

	switch s.Name {
	case "consul":
		return errors.New(`Service#Configure("consul") is not yet implemented`)
	case "haproxy":
		header, err := ioutil.ReadFile(`/var/vcap/jobs/rdpg-agent/config/haproxy/haproxy.cfg.header`)
		if err != nil {
			log.Error(fmt.Sprintf("cfsb#Service.Configure(%s) ! %s", s.Name, err))
			return err
		}

		r := rdpg.New()
		nodes := r.Nodes()
		// TODO: 5432 & 6432 from environmental configuration.
		// TODO: Should this list come from active Consul registered nodes instead?
		footer := fmt.Sprintf(`
frontend pgbdr_write_port
bind 0.0.0.0:5432
  mode tcp
  default_backend pgbdr_write_master
 
backend pgbdr_write_master
  mode tcp
	server master %s:6432 check
	`, nodes[0].Host)

		hc := []string{string(header), footer}
		err = ioutil.WriteFile(`/var/vcap/jobs/haproxy/config/haproxy.cfg`, []byte(strings.Join(hc, "\n")), 0640)
		if err != nil {
			log.Error(fmt.Sprintf("cfsb#Service.Configure(%s) ! %s", s.Name, err))
			return err
		}

		cmd := exec.Command("/var/vcap/jobs/haproxy/bin/control", "reload")
		err = cmd.Run()
		if err != nil {
			log.Error(fmt.Sprintf("cfsb#Service.Configure(%s) ! %s", s.Name, err))
			return err
		}

		return errors.New(`Service#Configure("haproxy") is not yet implemented`)
	case "pgbouncer":
		instances, err := cfsb.Instances()
		if err != nil {
			log.Error(fmt.Sprintf("cfsb#Service.Configure(%s) ! %s", s.Name, err))
			return err
		}

		pgbConf, err := ioutil.ReadFile(`/var/vcap/jobs/rdpg-agent/config/pgbouncer/pgbouncer.ini`)
		if err != nil {
			log.Error(fmt.Sprintf("cfsb#Service.Configure(%s) ! %s", s.Name, err))
			return err
		}

		pgbUsers, err := ioutil.ReadFile(`/var/vcap/jobs/rdpg-agent/config/pgbouncer/users`)
		if err != nil {
			log.Error(fmt.Sprintf("cfsb#Service.Configure(%s) ! %s", s.Name, err))
			return err
		}
		pc := []string{string(pgbConf)}
		pu := []string{string(pgbUsers)}
		for _, i := range instances {
			// TODO: Fetch port from something like os.Getenv("PG_PORT") instead of hardcoding here.
			c := fmt.Sprintf(`%s = host=%s port=%s dbname=%s`, i.Database, "127.0.0.1", "7432", i.Database)
			pc = append(pc, c)
			u := fmt.Sprintf(`"%s" "%s"`, i.User, i.Pass)
			pu = append(pu, u)
		}
		pc = append(pc, "")
		pu = append(pu, "")

		err = ioutil.WriteFile(`/var/vcap/store/pgbouncer/config/pgbouncer.ini`, []byte(strings.Join(pc, "\n")), 0640)
		if err != nil {
			log.Error(fmt.Sprintf("cfsb#Service.Configure(%s) ! %s", s.Name, err))
			return err
		}

		err = ioutil.WriteFile(`/var/vcap/store/pgbouncer/config/users`, []byte(strings.Join(pu, "\n")), 0640)
		if err != nil {
			log.Error(fmt.Sprintf("cfsb#Service.Configure(%s) ! %s", s.Name, err))
			return err
		}

		cmd := exec.Command("/var/vcap/jobs/pgbouncer/bin/control", "reload")
		err = cmd.Run()
		if err != nil {
			log.Error(fmt.Sprintf("cfsb#Service.Configure(%s) ! %s", s.Name, err))
			return err
		}
	case "pgbdr":
		return errors.New(`Service#Configure("pgbdr") is not yet implemented`)
	default:
		return errors.New(fmt.Sprintf(`Service#Configure("%s") is unknown.`, s.Name))
	}
	return
}