Skip to content

Commit

Permalink
admin_service+, repository, instance_binder, instance_creator
Browse files Browse the repository at this point in the history
  • Loading branch information
ultragtx committed Mar 22, 2017
1 parent f9f3b28 commit 743634e
Show file tree
Hide file tree
Showing 8 changed files with 512 additions and 7 deletions.
33 changes: 32 additions & 1 deletion broker/broker.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,28 @@ import (
"github.com/pivotal-cf/brokerapi"
)

type MongoServiceBroker struct{}
type InstanceCredentials struct {
Host string
Port int
Password string
}

type InstanceCreator interface {
Create(instanceID string, serviceDetails brokerapi.ProvisionDetails) error
Destroy(instanceID string, details brokerapi.DeprovisionDetails) error
//InstanceExists(instanceID string) (bool, error)
}

type InstanceBinder interface {
Bind(instanceID string, bindingID string, details brokerapi.BindDetails) error
Unbind(instanceID string, bindingID string, details brokerapi.UnbindDetails) error
//InstanceExists(instanceID string) (bool, error)
}

type MongoServiceBroker struct {
InstanceCreators map[string]InstanceCreator
InstanceBinders map[string]InstanceBinder
}

func (mongoServiceBroker *MongoServiceBroker) Services(context context.Context) []brokerapi.Service {
// TODO: read config
Expand Down Expand Up @@ -79,6 +100,16 @@ func (mongoServiceBroker *MongoServiceBroker) Unbind(context context.Context, in
return nil
}

//func (mongoServiceBroker *MongoServiceBroker) instanceExists(instanceID string) bool {
// for _, instanceCreator := range mongoServiceBroker.InstanceCreators {
// instanceExists, _ := instanceCreator.InstanceExists(instanceID)
// if instanceExists {
// return true
// }
// }
// return false
//}

// LastOperation ...
// If the broker provisions asynchronously, the Cloud Controller will poll this endpoint
// for the status of the provisioning operation.
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import (
"net/http"
"os"

"github.com/FoOTOo/mongo-service-broker-golang-ultragtx/broker"
"github.com/pivotal-cf/brokerapi"

"code.cloudfoundry.org/lager"
"github.com/ultragtx/mongo-broker/broker"
)

const (
Expand Down
151 changes: 151 additions & 0 deletions mongo/admin_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type AdminService struct {
password string
authSource string

addresses []string

session *mgo.Session
}

Expand Down Expand Up @@ -56,6 +58,7 @@ func NewAdminService(hosts, username, password, authSource string) (*AdminServic
username: username,
password: password,
authSource: authSource,
addresses: addresses,
session: session,
}

Expand Down Expand Up @@ -122,6 +125,11 @@ func (adminService *AdminService) CreateDatabase(databaseName string) (*mgo.Data
return nil, error
}

error = session.Fsync(false)
if error != nil {
return nil, error
}

return database, nil
}

Expand Down Expand Up @@ -155,6 +163,149 @@ func (adminService *AdminService) addDBOwnerRole(databaseName string) error {
return nil
}

func (adminService *AdminService) CreateUser(databaseName, username, password string) error {
session := adminService.session
database := session.DB(databaseName)

// TODO: ??? Not sure if it's correct
roles := bson.D{{"role", "readWrite"}, {"db", databaseName}}
cmd := &bson.D{{"createUser", username}, {"pwd", password}, {"roles", roles}}

result := &bson.D{}
error := database.Run(cmd, result)

if error != nil {
return error
}

ok := result.Map()["ok"]

if ok != 1.0 {
jsonStr, error := json.MarshalIndent(result.Map(), "", " ")
if error != nil {
return error
}

return errors.New(string(jsonStr))
}

return nil
}

func (adminService *AdminService) DeleteUser(databaseName, username string) error {
session := adminService.session
database := session.DB(databaseName)

cmd := &bson.D{{"dropUser", username}}

result := &bson.D{}
error := database.Run(cmd, result)

if error != nil {
return error
}

ok := result.Map()["ok"]

if ok != 1.0 {
jsonStr, error := json.MarshalIndent(result.Map(), "", " ")
if error != nil {
return error
}

return errors.New(string(jsonStr))
}

return nil
}

func (adminService *AdminService) GetConnectionString(databaseName, username, password string) string {
parts := []string{"mongodb://", username, ":", password, "@", adminService.GetServerAddresses(), "/", databaseName}
return strings.Join(parts, "")
}

func (adminService *AdminService) GetServerAddresses() string {
return strings.Join(adminService.addresses, ",")
}

func (adminService *AdminService) SaveDoc(doc interface{}, databaseName string, collectionName string) error {
//databaseExists, error := adminService.DatabaseExists(databaseName)
//
//var database *mgo.Database
//
//if error != nil {
// return error
//}
//
//if !databaseExists {
// database, error = adminService.CreateDatabase(databaseName)
//
// if error != nil {
// return error
// }
//}

session := adminService.session

database := session.DB(databaseName)
collection := database.C(collectionName)
error := collection.Insert(doc)

if error != nil {
return error
}

error = session.Fsync(false)
if error != nil {
return nil
}

return nil
}

func (adminService *AdminService) RemoveDoc(selector interface{}, databaseName string, collectionName string) error {
//databaseExists, error := adminService.DatabaseExists(databaseName)
//
//var database *mgo.Database
//
//if error != nil {
// return error
//}
//
//if !databaseExists {
// return errors.New("Database not exists")
//}

session := adminService.session

database := session.DB(databaseName)
collection := database.C(collectionName)

error := collection.Remove(selector)

if error != nil {
return error
}

return nil
}

func (adminService *AdminService) DocExists(query *bson.M, databaseName string, collectionName string) (bool, error) {
session := adminService.session

database := session.DB(databaseName)
collection := database.C(collectionName)

result := &bson.D{}
error := collection.Find(query).One(result)

if error != nil {
return false, error
}

return result != nil, nil
}

func splitHosts(hosts string, defaultPort string) ([]string, error) {
var addresses []string
for _, hostWithPort := range strings.Split(hosts, ",") {
Expand Down
8 changes: 3 additions & 5 deletions mongo/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,16 @@ func NewClient(hosts, username, password, authSource string) (Client, error) {
mgo.SetDebug(true)
mgo.SetLogger(logger)

addresses, error := splitHosts(hosts)
addresses, error := splitHosts(hosts, "27017")

if error != nil {
return nil, error
}

dialInfo := mgo.DialInfo{
Addrs: addresses,
Direct: false,
Addrs: addresses,
Direct: false,
Timeout: 30,


}

return Client{}, nil
Expand Down
90 changes: 90 additions & 0 deletions mongo/instance_binder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package mongo

import (
"errors"

"github.com/FoOTOo/mongo-service-broker-golang-ultragtx/utils"
"github.com/pivotal-cf/brokerapi"
)

type InstanceBinder struct {
adminService *AdminService
repository *Repository
}

func NewInstanceBinder(adminService *AdminService, repository *Repository) *InstanceBinder {
return &InstanceBinder{
adminService,
repository,
}
}

func (instanceBinder *InstanceBinder) Bind(instanceID string, bindingID string, details brokerapi.BindDetails) error {
// TODO: ATOM
instanceBindingExists, error := instanceBinder.repository.InstanceBindingExists(instanceID, bindingID)

if error != nil {
return error
}

if instanceBindingExists {
return instanceBindingExistsError(instanceID, bindingID, details)
}

// TODO check if user already exists in the DB

databaseName := instanceID
username := bindingID
password := utiils.GenerateRandomString(25)

error = instanceBinder.adminService.CreateUser(databaseName, username, password)

if error != nil {
return error
}

error = instanceBinder.repository.SaveInstanceBinding(instanceID, bindingID, details)

if error != nil {
return error
}

return nil
}

func (instanceBinder *InstanceBinder) Unbind(instanceID string, bindingID string, details brokerapi.UnbindDetails) error {
// TODO: ATOM
instanceBindingExists, error := instanceBinder.repository.InstanceBindingExists(instanceID, bindingID)

if error != nil {
return error
}

if instanceBindingExists {
return instanceBindingDoesNotExistError(instanceID, bindingID, details)
}

databaseName := instanceID
username := bindingID
error = instanceBinder.adminService.DeleteUser(databaseName, username)

if error != nil {
return error
}

error = instanceBinder.repository.DeleteInstanceBinding(instanceID, bindingID, details)

if error != nil {
return error
}

return nil
}

func instanceBindingExistsError(instanceID, bindingID string, details brokerapi.BindDetails) error {
return errors.New("Instance binding exists, incetanceID: " + instanceID + ", bindingID: " + bindingID)
}

func instanceBindingDoesNotExistError(instanceID, bindingID string, details brokerapi.UnbindDetails) error {
return errors.New("Instance binding doesn't exist, incetanceID: " + instanceID + ", bindingID: " + bindingID)
}
Loading

0 comments on commit 743634e

Please sign in to comment.