Skip to content

Commit 981738f

Browse files
authored
Add option to skip unavailable databases. (#17)
* Upgrade baton-sdk to v0.2.35. * Generate capabilities. * Add option to skip unavailable databases.
1 parent af10c3e commit 981738f

File tree

87 files changed

+6508
-1229
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+6508
-1229
lines changed

.github/workflows/capabilities.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ jobs:
1818
token: ${{ secrets.RELENG_GITHUB_TOKEN }}
1919

2020
- name: Run Docker Compose as a Daemon (to start sql server)
21-
run: docker-compose -f ./docker-compose.yml up --detach
21+
run: docker compose -f ./docker-compose.yml up --detach
22+
- name: Create another database
23+
run: docker exec -t baton-sql-server-db-1 /opt/mssql-tools18/bin/sqlcmd -C -S localhost -U SA -P 'devP@ssw0rd' -Q 'create database [space test 1]'
2224

2325
- name: Setup Go
2426
uses: actions/setup-go@v5
@@ -29,6 +31,8 @@ jobs:
2931
run: go build -o connector ./cmd/baton-sql-server
3032

3133
- name: Run and save output
34+
env:
35+
BATON_DSN: server=127.0.0.1;user id=sa;password=devP@ssw0rd;port=1433
3236
run: ./connector capabilities > baton_capabilities.json
3337

3438
- name: Commit changes

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ Flags:
9797
--log-format string The output format for logs: json, console ($BATON_LOG_FORMAT) (default "json")
9898
--log-level string The log level: debug, info, warn, error ($BATON_LOG_LEVEL) (default "info")
9999
-p, --provisioning This must be set in order for provisioning actions to be enabled ($BATON_PROVISIONING)
100+
--skip-unavailable-databases Skip databases that are unavailable (offline, restoring, etc) ($BATON_SKIP_UNAVAILABLE_DATABASES)
100101
--ticketing This must be set to enable ticketing support ($BATON_TICKETING)
101102
-v, --version version for baton-sql-server
102103

cmd/baton-sql-server/config.go

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,17 @@
11
package main
22

33
import (
4-
"context"
5-
"fmt"
6-
74
"github.com/conductorone/baton-sdk/pkg/field"
8-
"github.com/spf13/viper"
95
)
106

117
var (
128
dsn = field.StringField("dsn",
139
field.WithDescription("The connection string for connecting to SQL Server"),
1410
field.WithRequired(true))
11+
skipUnavailableDatabases = field.BoolField("skip-unavailable-databases",
12+
field.WithDescription("Skip databases that are unavailable (offline, restoring, etc)"))
1513
)
1614

1715
var cfg = field.Configuration{
18-
Fields: []field.SchemaField{dsn},
19-
}
20-
21-
// validateConfig is run after the configuration is loaded, and should return an error if it isn't valid.
22-
func validateConfig(_ context.Context, v *viper.Viper) error {
23-
if v.GetString(dsn.FieldName) == "" {
24-
return fmt.Errorf("--dsn is required")
25-
}
26-
27-
return nil
16+
Fields: []field.SchemaField{dsn, skipUnavailableDatabases},
2817
}

cmd/baton-sql-server/main.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,7 @@ func main() {
3636
func getConnector(ctx context.Context, v *viper.Viper) (types.ConnectorServer, error) {
3737
l := ctxzap.Extract(ctx)
3838

39-
if err := validateConfig(ctx, v); err != nil {
40-
return nil, err
41-
}
42-
43-
cb, err := connector.New(ctx, v.GetString(dsn.FieldName))
39+
cb, err := connector.New(ctx, v.GetString(dsn.FieldName), v.GetBool(skipUnavailableDatabases.FieldName))
4440
if err != nil {
4541
l.Error("error creating connector", zap.Error(err))
4642
return nil, err

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/conductorone/baton-sql-server
33
go 1.21
44

55
require (
6-
github.com/conductorone/baton-sdk v0.2.13
6+
github.com/conductorone/baton-sdk v0.2.35
77
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
88
github.com/jmoiron/sqlx v1.3.5
99
github.com/microsoft/go-mssqldb v1.3.0
@@ -15,6 +15,7 @@ require (
1515
require (
1616
filippo.io/age v1.1.1 // indirect
1717
filippo.io/edwards25519 v1.1.0 // indirect
18+
github.com/allegro/bigcache/v3 v3.1.0 // indirect
1819
github.com/aws/aws-sdk-go-v2 v1.26.1 // indirect
1920
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 // indirect
2021
github.com/aws/aws-sdk-go-v2/config v1.27.11 // indirect

go.sum

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDm
1010
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
1111
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
1212
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
13+
github.com/allegro/bigcache/v3 v3.1.0 h1:H2Vp8VOvxcrB91o86fUSVJFqeuz8kpyyB02eH3bSzwk=
14+
github.com/allegro/bigcache/v3 v3.1.0/go.mod h1:aPyh7jEvrog9zAwx5N7+JUQX5dZTSGpxF1LAR4dr35I=
1315
github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA=
1416
github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM=
1517
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 h1:x6xsQXGSmW6frevwDA+vi/wqhp1ct18mVXYN08/93to=
@@ -54,8 +56,8 @@ github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZx
5456
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
5557
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
5658
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
57-
github.com/conductorone/baton-sdk v0.2.13 h1:/9wJGlbiPxDQmjqKOTqyKpJ1Ui2+o7oYHInMqqR1PyQ=
58-
github.com/conductorone/baton-sdk v0.2.13/go.mod h1:cg5FyUcJnD7xK5SPbHe/KNpwUVVlpHJ9rnmd3UwxSkU=
59+
github.com/conductorone/baton-sdk v0.2.35 h1:aSdNvlM5HMti8WdhotrXTHWs+b+BmSqMxtGwsSUFxjY=
60+
github.com/conductorone/baton-sdk v0.2.35/go.mod h1:hmd/Oz3DPIKD+9QmkusZaA18ZoiinnTDdrxh2skcdUc=
5961
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
6062
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6163
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

pkg/connector/connector.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ func (o *Mssqldb) ResourceSyncers(ctx context.Context) []connectorbuilder.Resour
5858
}
5959
}
6060

61-
func New(ctx context.Context, dsn string) (*Mssqldb, error) {
62-
c, err := mssqldb.New(ctx, dsn)
61+
func New(ctx context.Context, dsn string, skipUnavailableDatabases bool) (*Mssqldb, error) {
62+
c, err := mssqldb.New(ctx, dsn, skipUnavailableDatabases)
6363
if err != nil {
6464
return nil, err
6565
}

pkg/connector/internal_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func TestClientListDatabasePermissions(t *testing.T) {
4949
t.Skip()
5050
}
5151

52-
cli, err := mssqldb.New(ctx, dsn)
52+
cli, err := mssqldb.New(ctx, dsn, false)
5353
assert.Nil(t, err)
5454

5555
for _, test := range tests {
@@ -69,7 +69,7 @@ func TestClientListServerPermissions(t *testing.T) {
6969
t.Skip()
7070
}
7171

72-
cli, err := mssqldb.New(ctx, dsn)
72+
cli, err := mssqldb.New(ctx, dsn, false)
7373
assert.Nil(t, err)
7474

7575
for keepingPagination(pager.Token) {
@@ -84,7 +84,7 @@ func TestClientListServerRoles(t *testing.T) {
8484
t.Skip()
8585
}
8686

87-
cli, err := mssqldb.New(ctx, dsn)
87+
cli, err := mssqldb.New(ctx, dsn, false)
8888
assert.Nil(t, err)
8989

9090
for keepingPagination(pager.Token) {
@@ -129,7 +129,7 @@ func TestClientListDatabaseRoles(t *testing.T) {
129129
t.Skip()
130130
}
131131

132-
cli, err := mssqldb.New(ctx, dsn)
132+
cli, err := mssqldb.New(ctx, dsn, false)
133133
assert.Nil(t, err)
134134

135135
for _, test := range tests {
@@ -176,7 +176,7 @@ func TestClientListDatabaseRolePrincipals(t *testing.T) {
176176
t.Skip()
177177
}
178178

179-
cli, err := mssqldb.New(ctx, dsn)
179+
cli, err := mssqldb.New(ctx, dsn, false)
180180
assert.Nil(t, err)
181181

182182
for _, test := range tests {
@@ -197,7 +197,7 @@ func TestClientListServerRolePrincipals(t *testing.T) {
197197
t.Skip()
198198
}
199199

200-
cli, err := mssqldb.New(ctx, dsn)
200+
cli, err := mssqldb.New(ctx, dsn, false)
201201
assert.Nil(t, err)
202202

203203
for keepingPagination(pager.Token) {
@@ -212,7 +212,7 @@ func TestClientListDatabases(t *testing.T) {
212212
t.Skip()
213213
}
214214

215-
cli, err := mssqldb.New(ctx, dsn)
215+
cli, err := mssqldb.New(ctx, dsn, false)
216216
assert.Nil(t, err)
217217

218218
for keepingPagination(pager.Token) {

pkg/mssqldb/client.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import (
99
)
1010

1111
type Client struct {
12-
db *sqlx.DB
12+
db *sqlx.DB
13+
skipUnavailableDatabases bool
1314
}
1415

1516
// List databases
@@ -20,7 +21,7 @@ type Client struct {
2021

2122
// List users
2223

23-
func New(ctx context.Context, dsn string) (*Client, error) {
24+
func New(ctx context.Context, dsn string, skipUnavailableDatabases bool) (*Client, error) {
2425
db, err := sqlx.Connect("sqlserver", dsn)
2526
if err != nil {
2627
return nil, err
@@ -31,7 +32,8 @@ func New(ctx context.Context, dsn string) (*Client, error) {
3132
db.SetMaxIdleConns(1)
3233

3334
c := &Client{
34-
db: db,
35+
db: db,
36+
skipUnavailableDatabases: skipUnavailableDatabases,
3537
}
3638

3739
return c, nil

pkg/mssqldb/databases.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import (
1212
const DatabaseType = "database"
1313

1414
type DbModel struct {
15-
ID int64 `db:"database_id"`
16-
Name string `db:"name"`
15+
ID int64 `db:"database_id"`
16+
Name string `db:"name"`
17+
StateDesc string `db:"state_desc"`
1718
}
1819

1920
func (c *Client) GetDatabase(ctx context.Context, id int64) (*DbModel, error) {
@@ -48,7 +49,7 @@ func (c *Client) ListDatabases(ctx context.Context, pager *Pager) ([]*DbModel, s
4849
args := []interface{}{offset, limit + 1}
4950

5051
var sb strings.Builder
51-
_, _ = sb.WriteString(`SELECT name, database_id FROM sys.databases
52+
_, _ = sb.WriteString(`SELECT name, database_id, state_desc FROM sys.databases
5253
ORDER BY database_id ASC
5354
OFFSET @p1 ROWS
5455
FETCH NEXT @p2 ROWS ONLY`)
@@ -68,6 +69,10 @@ func (c *Client) ListDatabases(ctx context.Context, pager *Pager) ([]*DbModel, s
6869
if err != nil {
6970
return nil, "", err
7071
}
72+
if c.skipUnavailableDatabases && dbModel.StateDesc != "ONLINE" {
73+
l.Info("Skipping sync of unavailable database", zap.String("name", dbModel.Name), zap.String("state", dbModel.StateDesc))
74+
continue
75+
}
7176
ret = append(ret, &dbModel)
7277
}
7378
if rows.Err() != nil {

0 commit comments

Comments
 (0)