Skip to content

Commit 67aeb05

Browse files
committed
Add mssql AD login functionality. Bump mssql package to v0.12.3
Signed-off-by: Mikel Landa <[email protected]>
1 parent 4988633 commit 67aeb05

File tree

10 files changed

+94
-31
lines changed

10 files changed

+94
-31
lines changed

apis/mssql/v1alpha1/user_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ type UserParameters struct {
4848
// for this user. If no reference is given, a password will be auto-generated.
4949
// +optional
5050
PasswordSecretRef *xpv1.SecretKeySelector `json:"passwordSecretRef,omitempty"`
51+
Type *string `json:"type,omitempty"`
5152
}
5253

5354
// A UserObservation represents the observed state of a MSSQL user.

cmd/provider/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"path/filepath"
2222

2323
_ "github.com/denisenkom/go-mssqldb"
24+
_ "github.com/denisenkom/go-mssqldb/azuread"
2425
_ "github.com/go-sql-driver/mysql"
2526
_ "github.com/lib/pq"
2627

Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
apiVersion: mssql.sql.crossplane.io/v1alpha1
22
kind: Database
33
metadata:
4-
name: example-db
4+
name: example-db-ad
55
spec: {}

examples/mssql/ad/grant.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: mssql.sql.crossplane.io/v1alpha1
2+
kind: Grant
3+
metadata:
4+
name: example-grant
5+
spec:
6+
forProvider:
7+
permissions:
8+
# CONNECT permission is added by default when user created. So, make sure
9+
# to include it unless you are sure that you don't need it.
10+
- CONNECT
11+
- CREATE TABLE
12+
- INSERT
13+
- SELECT
14+
userRef:
15+
name: example-user-ad
16+
databaseRef:
17+
name: example-db-ad

examples/mssql/ad/user.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: mssql.sql.crossplane.io/v1alpha1
2+
kind: User
3+
metadata:
4+
name: example-user-ad
5+
annotations:
6+
crossplane.io/external-name: "[email protected]"
7+
spec:
8+
forProvider:
9+
type: AD
10+
databaseRef:
11+
name: example-db-ad

examples/mssql/config.yaml

Lines changed: 0 additions & 11 deletions
This file was deleted.

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ require (
4444
github.com/gobuffalo/flect v1.0.2 // indirect
4545
github.com/gogo/protobuf v1.3.2 // indirect
4646
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
47+
github.com/golang-sql/sqlexp v0.1.0 // indirect
4748
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
4849
github.com/golang/protobuf v1.5.3 // indirect
4950
github.com/google/gnostic-models v0.6.8 // indirect

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
110110
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
111111
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
112112
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
113+
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
113114
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
114115
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
115116
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=

pkg/clients/mssql/mssql.go

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,26 @@ import (
3232
)
3333

3434
const (
35-
driverName = "sqlserver"
35+
schema = "sqlserver"
36+
stdDriverName = "sqlserver"
37+
azDriverName = "azuresql"
3638

3739
errNotSupported = "%s not supported by MSSQL client"
40+
fedauth = "fedauth"
3841
)
3942

4043
type mssqlDB struct {
4144
dsn string
4245
endpoint string
4346
port string
47+
driver string
4448
}
4549

4650
// New returns a new mssql database client.
4751
func New(creds map[string][]byte, database string) xsql.DB {
4852
endpoint := string(creds[xpv1.ResourceCredentialsSecretEndpointKey])
4953
port := string(creds[xpv1.ResourceCredentialsSecretPortKey])
50-
54+
driver := stdDriverName
5155
host := endpoint
5256
if port != "" {
5357
host = fmt.Sprintf("%s:%s", endpoint, port)
@@ -57,16 +61,36 @@ func New(creds map[string][]byte, database string) xsql.DB {
5761
if database != "" {
5862
query.Add("database", database)
5963
}
60-
u := &url.URL{
61-
Scheme: driverName,
62-
User: url.UserPassword(string(creds[xpv1.ResourceCredentialsSecretUserKey]), string(creds[xpv1.ResourceCredentialsSecretPasswordKey])),
63-
Host: host,
64-
RawQuery: query.Encode(),
64+
var u *url.URL
65+
if val, ok := creds[fedauth]; ok {
66+
authType := string(val)
67+
query.Add(fedauth, authType)
68+
if authType == "ActiveDirectoryServicePrincipal" || authType == "ActiveDirectoryApplication" || authType == "ActiveDirectoryPassword" {
69+
query.Add("password", string(creds[xpv1.ResourceCredentialsSecretPasswordKey]))
70+
}
71+
if val, ok := creds[xpv1.ResourceCredentialsSecretUserKey]; ok {
72+
query.Add("user id", string(val))
73+
}
74+
u = &url.URL{
75+
Scheme: schema,
76+
Host: host,
77+
RawQuery: query.Encode(),
78+
}
79+
driver = azDriverName
80+
} else {
81+
82+
u = &url.URL{
83+
Scheme: schema,
84+
User: url.UserPassword(string(creds[xpv1.ResourceCredentialsSecretUserKey]), string(creds[xpv1.ResourceCredentialsSecretPasswordKey])),
85+
Host: host,
86+
RawQuery: query.Encode(),
87+
}
6588
}
6689
return mssqlDB{
6790
dsn: u.String(),
6891
endpoint: endpoint,
6992
port: port,
93+
driver: driver,
7094
}
7195
}
7296

@@ -77,7 +101,7 @@ func (c mssqlDB) ExecTx(_ context.Context, _ []xsql.Query) error {
77101

78102
// Exec the supplied query.
79103
func (c mssqlDB) Exec(ctx context.Context, q xsql.Query) error {
80-
d, err := sql.Open(driverName, c.dsn)
104+
d, err := sql.Open(c.driver, c.dsn)
81105
if err != nil {
82106
return err
83107
}
@@ -89,7 +113,7 @@ func (c mssqlDB) Exec(ctx context.Context, q xsql.Query) error {
89113

90114
// Query the supplied query.
91115
func (c mssqlDB) Query(ctx context.Context, q xsql.Query) (*sql.Rows, error) {
92-
d, err := sql.Open(driverName, c.dsn)
116+
d, err := sql.Open(c.driver, c.dsn)
93117
if err != nil {
94118
return nil, err
95119
}
@@ -100,7 +124,7 @@ func (c mssqlDB) Query(ctx context.Context, q xsql.Query) (*sql.Rows, error) {
100124

101125
// Scan the results of the supplied query into the supplied destination.
102126
func (c mssqlDB) Scan(ctx context.Context, q xsql.Query, dest ...interface{}) error {
103-
db, err := sql.Open(driverName, c.dsn)
127+
db, err := sql.Open(c.driver, c.dsn)
104128
if err != nil {
105129
return err
106130
}

pkg/controller/mssql/user/reconciler.go

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,25 @@ func (c *external) Create(ctx context.Context, mg resource.Managed) (managed.Ext
169169
if !ok {
170170
return managed.ExternalCreation{}, errors.New(errNotUser)
171171
}
172+
var query string
173+
var pw string
174+
if t := cr.Spec.ForProvider.Type; t == nil || *t != "AD" {
172175

173-
pw, _, err := c.getPassword(ctx, cr)
174-
if err != nil {
175-
return managed.ExternalCreation{}, err
176-
}
177-
if pw == "" {
178-
pw, err = password.Generate()
176+
pw, _, err := c.getPassword(ctx, cr)
179177
if err != nil {
180178
return managed.ExternalCreation{}, err
181179
}
180+
if pw == "" {
181+
pw, err = password.Generate()
182+
if err != nil {
183+
return managed.ExternalCreation{}, err
184+
}
185+
}
186+
187+
query = fmt.Sprintf("CREATE USER %s WITH PASSWORD=%s", mssql.QuoteIdentifier(meta.GetExternalName(cr)), mssql.QuoteValue(pw))
188+
} else {
189+
query = fmt.Sprintf("CREATE USER %s", mssql.QuoteIdentifier(meta.GetExternalName(cr)))
190+
182191
}
183192

184193
loginQuery := fmt.Sprintf("CREATE LOGIN %s WITH PASSWORD=%s", mssql.QuoteIdentifier(meta.GetExternalName(cr)), mssql.QuoteValue(pw))
@@ -219,9 +228,18 @@ func (c *external) Update(ctx context.Context, mg resource.Managed) (managed.Ext
219228
return managed.ExternalUpdate{}, errors.Wrap(err, errUpdateUser)
220229
}
221230

222-
return managed.ExternalUpdate{
223-
ConnectionDetails: c.db.GetConnectionDetails(meta.GetExternalName(cr), pw),
224-
}, nil
231+
if changed {
232+
query := fmt.Sprintf("ALTER USER %s WITH PASSWORD=%s", mssql.QuoteIdentifier(meta.GetExternalName(cr)), mssql.QuoteValue(pw))
233+
if err := c.db.Exec(ctx, xsql.Query{
234+
String: query,
235+
}); err != nil {
236+
return managed.ExternalUpdate{}, errors.Wrap(err, errUpdateUser)
237+
}
238+
239+
return managed.ExternalUpdate{
240+
ConnectionDetails: c.db.GetConnectionDetails(meta.GetExternalName(cr), pw),
241+
}, nil
242+
}
225243
}
226244
return managed.ExternalUpdate{}, nil
227245
}

0 commit comments

Comments
 (0)