Example #1
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 #2
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 #3
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 #4
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 #5
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 #6
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 #7
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 #8
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 #9
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 #10
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 #11
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 #12
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 #13
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 #14
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
}
Example #15
0
// TODO: This should only be run on one node...
func (r *RDPG) InitSchema() (err error) {
	// TODO: if 'rdpg' database DNE,
	// For each node connect to pgbdr and:
	//   CreatDatabase('rdpg','postgres')
	//   "ALTER USER postgres SUPERUSER CREATEDB CREATEROLE INHERIT"
	//   CreateReplicationGroup('rdpg')

	log.Trace(fmt.Sprintf("RDPG#initSchema() CONNECT > %s", rdpgURI))
	var name string
	r.OpenDB("rdpg")
	db := r.DB

	_, err = db.Exec(`SELECT bdr.bdr_node_join_wait_for_ready();`)
	if err != nil {
		log.Error(fmt.Sprintf("RDPG#initSchema() bdr.bdr_node_join_wait_for_ready ! %s", err))
	}

	keys := []string{
		"rdpg_extensions",
		"rdpg_schemas",
	}
	for _, key := range keys {
		log.Trace(fmt.Sprintf("RDPG#initSchema() SQL[%s]", key))
		_, err = db.Exec(SQL[key])
		if err != nil {
			log.Error(fmt.Sprintf("RDPG#initSchema() ! %s", err))
		}
	}

	keys = []string{
		"create_table_cfsb_services",
		"create_table_cfsb_plans",
		"create_table_cfsb_instances",
		"create_table_cfsb_bindings",
		"create_table_cfsb_credentials",
		"create_table_rdpg_consul_watch_notifications",
		"create_table_rdpg_events",
	}
	for _, key := range keys {
		k := strings.Split(strings.Replace(strings.Replace(key, "create_table_", "", 1), "_", ".", 1), ".")
		sq := fmt.Sprintf(`SELECT table_name FROM information_schema.tables where table_schema='%s' AND table_name='%s';`, k[0], k[1])

		log.Trace(fmt.Sprintf("RDPG#initSchema() %s", sq))
		if err := db.QueryRow(sq).Scan(&name); err != nil {
			if err == sql.ErrNoRows {
				log.Trace(fmt.Sprintf("RDPG#initSchema() SQL[%s]", key))
				_, err = db.Exec(SQL[key])
				if err != nil {
					log.Error(fmt.Sprintf("RDPG#initSchema() ! %s", err))
				}
			} else {
				log.Error(fmt.Sprintf("rdpg.initSchema() ! %s", err))
				return err
			}
		}
	}

	// TODO: Move initial population of services out of rdpg-agent to Admin API.
	if err := db.QueryRow("SELECT name FROM cfsb.services WHERE name='rdpg' LIMIT 1;").Scan(&name); err != nil {
		if err == sql.ErrNoRows {
			if _, err = db.Exec(SQL["insert_default_cfsb_services"]); err != nil {
				log.Error(fmt.Sprintf("rdpg.initSchema(insert_default_cfsb_services) %s", err))
				return err
			}
		} else {
			log.Error(fmt.Sprintf("rdpg.initSchema() ! %s", err))
			return err
		}
	}

	// TODO: Move initial population of services out of rdpg-agent to Admin API.
	if err = db.QueryRow("SELECT name FROM cfsb.plans WHERE name='shared' LIMIT 1;").Scan(&name); err != nil {
		if err == sql.ErrNoRows {
			if _, err = db.Exec(SQL["insert_default_cfsb_plans"]); err != nil {
				log.Error(fmt.Sprintf("rdpg.initSchema(insert_default_cfsb_plans) %s", err))
				return err
			}
		} else {
			log.Error(fmt.Sprintf("rdpg.initSchema() ! %s", err))
			return err
		}
	}
	db.Close()

	for _, node := range r.Nodes() {
		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
		}
		log.Trace(fmt.Sprintf("RDPG#initSchema() SQL[%s]", "postgres_schemas"))
		_, err = db.Exec(SQL["postgres_schemas"])
		if err != nil {
			log.Error(fmt.Sprintf("RDPG#initSchema() ! %s", err))
		}

		keys = []string{ // These are for the postgres database only
			"create_function_rdpg_disable_database",
		}
		for _, key := range keys {
			k := strings.Split(strings.Replace(strings.Replace(key, "create_function_", "", 1), "_", ".", 1), ".")
			sq := fmt.Sprintf(`SELECT routine_name FROM information_schema.routines WHERE routine_type='FUNCTION' AND routine_schema='%s' AND routine_name='%s';`, k[0], k[1])

			log.Trace(fmt.Sprintf("RDPG#initSchema() %s", sq))
			if err := db.QueryRow(sq).Scan(&name); err != nil {
				if err == sql.ErrNoRows {
					log.Trace(fmt.Sprintf("RDPG#initSchema() SQL[%s]", key))
					_, err = db.Exec(SQL[key])
					if err != nil {
						log.Error(fmt.Sprintf("RDPG#initSchema() %s", err))
					}
				} else {
					log.Error(fmt.Sprintf("rdpg.initSchema() %s", err))
					return err
				}
			}
		}
		db.Close()
	}
	return nil
}
Example #16
0
/*
(PI) PUT /v2/service_instances/:id
(RI) DELETE /v2/service_instances/:id
*/
func InstanceHandler(w http.ResponseWriter, request *http.Request) {
	vars := mux.Vars(request)
	log.Trace(fmt.Sprintf("%s /v2/service_instances/:instance_id :: %+v", request.Method, vars))
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")

	switch request.Method {
	case "PUT":
		type instanceRequest struct {
			ServiceId      string `json:"service_id"`
			Plan           string `json:"plan_id"`
			OrganizationId string `json:"organization_guid"`
			SpaceId        string `json:"space_guid"`
		}
		ir := instanceRequest{}
		body, err := ioutil.ReadAll(request.Body)
		if err != nil {
			log.Error(fmt.Sprintf("%s /v2/service_instances/:instance_id %s", request.Method, err))
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, `{"status": %d,"description": %s}`, http.StatusInternalServerError, err)
			return
		}
		err = json.Unmarshal(body, &ir)
		if err != nil {
			log.Error(fmt.Sprintf("%s /v2/service_instances/:instance_id %s", request.Method, err))
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, `{"status": %d,"description": %s}`, http.StatusInternalServerError, err)
			return
		}

		instance, err := NewInstance(
			vars["instance_id"],
			ir.ServiceId,
			ir.Plan,
			ir.OrganizationId,
			ir.SpaceId,
		)
		if err != nil {
			log.Error(fmt.Sprintf("%s /v2/service_instances/:instance_id %s", request.Method, err))
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, `{"status": %d,"description": %s}`, http.StatusInternalServerError, err)
			return
		}

		err = instance.Provision()
		if err != nil {
			log.Error(fmt.Sprintf("%s /v2/service_instances/:instance_id %s", request.Method, err))
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, `{"status": %d,"description": %s}`, http.StatusInternalServerError, err)
			return
		}
		w.WriteHeader(http.StatusOK)
		fmt.Fprintf(w, `{"status": %d,"description": "Instance Provisioned Successfully"}`, http.StatusOK)
		return
	case "DELETE":
		instance, err := FindInstance(vars["instance_id"])
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, `{"status": %d,"description": %s}`, http.StatusInternalServerError, err)
			return
		}

		err = instance.Remove()
		if err != nil {
			log.Error(fmt.Sprintf("%s /v2/service_instances/:instance_id %s", request.Method, err))
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, `{"status": %d,"description": %s}`, http.StatusInternalServerError, err)
			return
		}
		w.WriteHeader(http.StatusOK)
		fmt.Fprintf(w, `{"status": %d,"description": "Successfully Deprovisioned %s"}`, http.StatusOK, instance.InstanceId)
	default:
		w.WriteHeader(http.StatusMethodNotAllowed)
		fmt.Fprintf(w, `{"status": %d,"description": "Allowed Methods: PUT, DELETE"}`, http.StatusMethodNotAllowed)
		return
	}
}