forked from cloudfoundry-attic/cf-mssql-broker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mssql_service_broker.go
163 lines (125 loc) · 4.32 KB
/
mssql_service_broker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package main
import (
"crypto/rand"
"encoding/base64"
"github.com/pivotal-cf/brokerapi"
"github.com/pivotal-golang/lager"
)
// This is a suffix added to the password that will prevent the default
// sql password policy to reject high entory passwords from a base64 char set.
// The purpose of this is to prenvent the admin from disableing the policy,
// thus it will simplify the inital setup, and it will NOT in any way reduce
// the final password strength.
// Policy descrpition:
// https://msdn.microsoft.com/en-us/library/ms161959.aspx
// http://xkcd.com/936/
const happySqlPasswordPolicySuffix = "Aa_0"
func secureRandomString(bytesOfEntpry int) string {
rb := make([]byte, bytesOfEntpry)
_, err := rand.Read(rb)
if err != nil {
logger.Fatal("rng-failure", err)
}
return base64.URLEncoding.EncodeToString(rb)
}
type mssqlServiceBroker struct{}
func (*mssqlServiceBroker) Services() []brokerapi.Service {
// Return a []brokerapi.Service here, describing your service(s) and plan(s)
logger.Info("catalog-called")
return brokerConfig.ServiceCatalog
}
func (*mssqlServiceBroker) Provision(instanceID string, serviceDetails brokerapi.ServiceDetails) error {
// Provision a new instance here
logger.Info("provision-called", lager.Data{"instanceId": instanceID, "serviceDetails": serviceDetails})
databaseName := brokerConfig.DbIdentifierPrefix + instanceID
exist, err := mssqlProv.IsDatabaseCreated(databaseName)
if err != nil {
logger.Fatal("provisioner-error", err)
}
if exist {
return brokerapi.ErrInstanceAlreadyExists
}
err = mssqlProv.CreateDatabase(databaseName)
if err != nil {
logger.Fatal("provisioner-error", err)
}
return nil
}
func (*mssqlServiceBroker) Deprovision(instanceID string) error {
// Deprovision instances here
logger.Info("deprovision-called", lager.Data{"instanceId": instanceID})
databaseName := brokerConfig.DbIdentifierPrefix + instanceID
exist, err := mssqlProv.IsDatabaseCreated(databaseName)
if err != nil {
logger.Fatal("provisioner-error", err)
}
if !exist {
return brokerapi.ErrInstanceDoesNotExist
}
err = mssqlProv.DeleteDatabase(databaseName)
if err != nil {
logger.Fatal("provisioner-error", err)
}
return nil
}
func (*mssqlServiceBroker) Bind(instanceID, bindingID string) (interface{}, error) {
// Bind to instances here
// Return credentials which will be marshalled to JSON
logger.Info("bind-called", lager.Data{"instanceId": instanceID, "bindingId": bindingID})
databaseName := brokerConfig.DbIdentifierPrefix + instanceID
username := databaseName + "-" + bindingID
password := secureRandomString(32) + happySqlPasswordPolicySuffix
exist, err := mssqlProv.IsDatabaseCreated(databaseName)
if err != nil {
logger.Fatal("provisioner-error", err)
}
if !exist {
return nil, brokerapi.ErrInstanceDoesNotExist
}
exist, err = mssqlProv.IsUserCreated(databaseName, username)
if err != nil {
logger.Fatal("provisioner-error", err)
}
if exist {
return nil, brokerapi.ErrBindingAlreadyExists
}
err = mssqlProv.CreateUser(databaseName, username, password)
if err != nil {
logger.Fatal("provisioner-error", err)
}
bindingInfo := MssqlBindingCredentials{
Hostname: brokerConfig.ServedBindingHostname,
Host: brokerConfig.ServedBindingHostname,
Port: brokerConfig.ServedBindingPort,
Name: databaseName,
Username: username,
Password: password,
ConnectionString: generateConnectionString(brokerConfig.ServedBindingHostname, brokerConfig.ServedBindingPort, databaseName, username, password),
}
return bindingInfo, nil
}
func (*mssqlServiceBroker) Unbind(instanceID, bindingID string) error {
// Unbind from instances here
logger.Info("unbind-called", lager.Data{"instanceId": instanceID, "bindingId": bindingID})
databaseName := brokerConfig.DbIdentifierPrefix + instanceID
username := databaseName + "-" + bindingID
exist, err := mssqlProv.IsDatabaseCreated(databaseName)
if err != nil {
logger.Fatal("provisioner-error", err)
}
if !exist {
return brokerapi.ErrInstanceDoesNotExist
}
exist, err = mssqlProv.IsUserCreated(databaseName, username)
if err != nil {
logger.Fatal("provisioner-error", err)
}
if !exist {
return brokerapi.ErrBindingAlreadyExists
}
err = mssqlProv.DeleteUser(databaseName, username)
if err != nil {
logger.Fatal("provisioner-error", err)
}
return nil
}