-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for sql databases (#4)
- Loading branch information
Showing
20 changed files
with
713 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
name: Go Test | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
tags: | ||
- '*' | ||
pull_request: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
build: | ||
name: Test on Go ${{ matrix.go-version }} and ${{ matrix.os }} | ||
runs-on: ${{ matrix.os }} | ||
strategy: | ||
matrix: | ||
go-version: [1.18.x] | ||
os: [ubuntu-latest] | ||
steps: | ||
- name: Set up Go ${{ matrix.go-version }} on ${{ matrix.os }} | ||
uses: actions/setup-go@v1 | ||
with: | ||
go-version: ${{ matrix.go-version }} | ||
id: go | ||
|
||
- name: Check out code into the Go module directory | ||
uses: actions/checkout@v2 | ||
|
||
- name: Start containers | ||
run: docker-compose up -d | ||
|
||
- name: Test adapters on ${{ matrix.os }} | ||
env: | ||
GO111MODULE: on | ||
run: | | ||
go test -v -race ./adapters/... | ||
- name: Stop containers | ||
if: always() | ||
run: docker-compose down |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package adapters | ||
|
||
import ( | ||
"context" | ||
"database/sql" | ||
"fmt" | ||
|
||
_ "github.com/denisenkom/go-mssqldb" | ||
) | ||
|
||
type mssqlAdapter struct { | ||
db *sql.DB | ||
} | ||
|
||
func (adapter mssqlAdapter) HasDatabase(ctx context.Context, database string) (bool, error) { | ||
var count int | ||
query := fmt.Sprintf("SELECT COUNT(*) FROM master.sys.databases WHERE name='%s';", database) | ||
err := adapter.db.QueryRowContext(ctx, query).Scan(&count) | ||
if err != nil { | ||
return false, err | ||
} | ||
return count == 1, nil | ||
} | ||
|
||
func (adapter mssqlAdapter) CreateDatabase(ctx context.Context, database string) error { | ||
query := fmt.Sprintf("EXEC ('sp_configure ''contained database authentication'', 1; reconfigure;');") | ||
_, err := adapter.db.ExecContext(ctx, query) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
query = fmt.Sprintf("CREATE DATABASE [%s] CONTAINMENT=PARTIAL;", database) | ||
_, err = adapter.db.ExecContext(ctx, query) | ||
return err | ||
} | ||
|
||
func (adapter mssqlAdapter) DeleteDatabase(ctx context.Context, database string) error { | ||
query := fmt.Sprintf("DROP DATABASE [%s];", database) | ||
_, err := adapter.db.ExecContext(ctx, query) | ||
return err | ||
} | ||
|
||
func (adapter mssqlAdapter) HasDatabaseUserWithAccess(ctx context.Context, database string, username string) (bool, error) { | ||
var count int | ||
query := fmt.Sprintf("USE [%s]; SELECT COUNT(*) FROM sys.database_principals WHERE authentication_type=2 AND name='%s';", database, username) | ||
err := adapter.db.QueryRowContext(ctx, query).Scan(&count) | ||
if err != nil { | ||
return false, err | ||
} | ||
return count == 1, nil | ||
} | ||
|
||
func (adapter mssqlAdapter) CreateDatabaseUser(ctx context.Context, database string, username string, password string) error { | ||
// make password sql safe | ||
quotedPassword := QuoteLiteral(password) | ||
query := fmt.Sprintf("USE [%s]; CREATE USER [%s] WITH PASSWORD=%s", database, username, quotedPassword) | ||
_, err := adapter.db.ExecContext(ctx, query) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
query = fmt.Sprintf("USE [%s]; ALTER ROLE db_owner ADD MEMBER [%s];", database, username) | ||
_, err = adapter.db.ExecContext(ctx, query) | ||
return err | ||
} | ||
|
||
func (adapter mssqlAdapter) DeleteDatabaseUser(ctx context.Context, database string, username string) error { | ||
query := fmt.Sprintf("USE [%s]; DROP USER %s;", database, username) | ||
_, err := adapter.db.ExecContext(ctx, query) | ||
return err | ||
} | ||
|
||
func (adapter mssqlAdapter) Close(ctx context.Context) error { | ||
return adapter.db.Close() | ||
} | ||
|
||
func GetMssqlConnection(ctx context.Context, url string) (*mssqlAdapter, error) { | ||
db, err := sql.Open("sqlserver", url) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
adapter := mssqlAdapter{ | ||
db: db, | ||
} | ||
|
||
if err := adapter.db.PingContext(ctx); err != nil { | ||
return nil, err | ||
} | ||
|
||
return &adapter, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package adapters_test | ||
|
||
import ( | ||
"context" | ||
"database/sql" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/anbraten/k8s-external-database-operator/adapters" | ||
) | ||
|
||
func TestMsSqlDB(t *testing.T) { | ||
databaseHost := "localhost" | ||
databasePort := "1433" | ||
|
||
ctx := context.Background() | ||
url := fmt.Sprintf("sqlserver://%s:%s@%s:%s", "sa", "pA_sw0rd", databaseHost, databasePort) | ||
adapter, err := adapters.GetMssqlConnection(ctx, url) | ||
if err != nil { | ||
t.Fatalf("Error opening database connection: %s", err) | ||
} | ||
|
||
clientConnectTest := func(ctx context.Context, databaseName string, databaseUsername string, databasePassword string) error { | ||
url := fmt.Sprintf("sqlserver://%s:%s@%s:%s?database=%s", databaseUsername, databasePassword, databaseHost, databasePort, databaseName) | ||
client, err := sql.Open("sqlserver", url) | ||
if err != nil { | ||
return err | ||
} | ||
defer client.Close() | ||
|
||
_, err = client.ExecContext(ctx, "CREATE TABLE test (id int);") | ||
return err | ||
} | ||
|
||
testHelper(t, ctx, adapter, clientConnectTest) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package adapters_test | ||
|
||
import ( | ||
"context" | ||
"database/sql" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/anbraten/k8s-external-database-operator/adapters" | ||
) | ||
|
||
func TestMySqlDB(t *testing.T) { | ||
databaseHost := "localhost" | ||
databasePort := "3306" | ||
|
||
ctx := context.Background() | ||
url := fmt.Sprintf("%s:%s@tcp(%s:%s)/", "root", "pA_sw0rd", databaseHost, databasePort) | ||
adapter, err := adapters.GetMysqlConnection(ctx, url) | ||
if err != nil { | ||
t.Fatalf("Error opening database connection: %s", err) | ||
} | ||
|
||
clientConnectTest := func(ctx context.Context, databaseName string, databaseUsername string, databasePassword string) error { | ||
url := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", databaseUsername, databasePassword, databaseHost, databasePort, databaseName) | ||
client, err := sql.Open("mysql", url) | ||
if err != nil { | ||
return err | ||
} | ||
defer client.Close() | ||
|
||
_, err = client.ExecContext(ctx, "CREATE TABLE test (id int);") | ||
return err | ||
} | ||
|
||
testHelper(t, ctx, adapter, clientConnectTest) | ||
} |
Oops, something went wrong.