Skip to content

Commit

Permalink
Merge branch 'main' into database-request-crd3
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco Cadetg committed May 16, 2024
2 parents 2aa8c09 + dcf07dc commit 7602a9e
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 23 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/test-suite.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: DBaaS controller tests

on: pull_request

jobs:
test-suite:
runs-on: ubuntu-latest
strategy:
fail-fast: false

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: "0"

- name: Configure kind network
run: |
docker network create kind
- name: Create kind cluster
uses: helm/[email protected]
with:
version: v0.22.0
node_image: kindest/node:v1.28.7@sha256:9bc6c451a289cf96ad0bbaf33d416901de6fd632415b076ab05f5fa7e4f65c58
kubectl_version: v1.28.7
cluster_name: kind
config: kind-config.yaml

- name: Run github/test-e2e
run: make github/test-e2e
25 changes: 21 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ else
GOBIN=$(shell go env GOBIN)
endif

KIND_CLUSTER ?= kind

# CONTAINER_TOOL defines the container tool to be used for building images.
# Be aware that the target commands are only tested with Docker which is
# scaffolded by default. However, you might want to replace it to use other
Expand Down Expand Up @@ -64,10 +66,25 @@ vet: ## Run go vet against code.
test: manifests generate fmt vet envtest ## Run tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out

.PHONY: create-kind-cluster
create-kind-cluster:
docker network inspect $(KIND_CLUSTER) >/dev/null || docker network create $(KIND_CLUSTER)
kind create cluster --wait=60s --name=$(KIND_CLUSTER) --config=kind-config.yaml

.PHONY: delete-kind-cluster
delete-kind-cluster:
kind delete cluster --name=$(KIND_CLUSTER) && docker network rm $(KIND_CLUSTER)

# Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors.
.PHONY: test-e2e # Run the e2e tests against a Kind k8s instance that is spun up.
test-e2e:
kind export kubeconfig --name=kind
.PHONY: github/test-e2e # Run the e2e tests against a Kind k8s instance that is spun up inside github action.
github/test-e2e:
go test ./test/e2e/ -v -ginkgo.v

# Create a kind cluster locally and run the test e2e test suite against it
.PHONY: local-kind/test-e2e # Run the e2e tests against a Kind k8s instance that is spun up locally
local-kind/test-e2e: create-kind-cluster
export KIND_CLUSTER=$(KIND_CLUSTER) && \
kind export kubeconfig --name=$(KIND_CLUSTER) && \
go test ./test/e2e/ -v -ginkgo.v

.PHONY: lint
Expand Down Expand Up @@ -201,4 +218,4 @@ echo "Downloading $${package}" ;\
GOBIN=$(LOCALBIN) go install $${package} ;\
mv "$$(echo "$(1)" | sed "s/-$(3)$$//")" $(1) ;\
}
endef
endef
9 changes: 7 additions & 2 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package main

import (
"crypto/tls"
"database/sql"
"flag"
"os"

Expand Down Expand Up @@ -126,18 +127,22 @@ func main() {
os.Exit(1)
}

mysqlClient := &mysql.MySQLImpl{
ConnectionCache: make(map[string]*sql.DB),
}

if err = (&controller.DatabaseRequestReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
MySQLClient: &mysql.MySQLImpl{},
MySQLClient: mysqlClient,
}).SetupWithManager(mgr, maxConcurrentReconciles); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "DatabaseRequest")
os.Exit(1)
}
if err = (&controller.DatabaseMySQLProviderReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
MySQLClient: &mysql.MySQLImpl{},
MySQLClient: mysqlClient,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "DatabaseMySQLProvider")
os.Exit(1)
Expand Down
40 changes: 25 additions & 15 deletions internal/database/mysql/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,35 @@ type MySQLInterface interface {
}

// MySQLImpl is the implementation of the MySQL database
type MySQLImpl struct{}
// Note that we maintain a connection cache to avoid opening a new connection for each operation.
type MySQLImpl struct {
ConnectionCache map[string]*sql.DB
}

// Make sure MySQLImpl implements MySQLInterface
var _ MySQLInterface = (*MySQLImpl)(nil)

// getConnection returns a connection to the MySQL database
func (mi *MySQLImpl) getConnection(ctx context.Context, dsn string) (*sql.DB, error) {
if db, ok := mi.ConnectionCache[dsn]; ok {
return db, nil
}
db, err := sql.Open("mysql", dsn)
if err != nil {
return nil, fmt.Errorf("failed to open MySQL database: %w", err)
}
log.FromContext(ctx).Info("Opening MySQL database connection")
mi.ConnectionCache[dsn] = db
return db, nil
}

// Ping pings the MySQL database
func (mi *MySQLImpl) Ping(ctx context.Context, dsn string) error {
log.FromContext(ctx).Info("Pinging MySQL database")
db, err := sql.Open("mysql", dsn)
db, err := mi.getConnection(ctx, dsn)
if err != nil {
return fmt.Errorf("ping failed to open MySQL database: %w", err)
}
defer db.Close()

if err := db.PingContext(ctx); err != nil {
return fmt.Errorf("failed to ping MySQL database: %w", err)
Expand All @@ -77,11 +93,10 @@ func (mi *MySQLImpl) Ping(ctx context.Context, dsn string) error {
// Version returns the version of the MySQL database
func (mi *MySQLImpl) Version(ctx context.Context, dsn string) (string, error) {
log.FromContext(ctx).Info("Getting MySQL database version")
db, err := sql.Open("mysql", dsn)
db, err := mi.getConnection(ctx, dsn)
if err != nil {
return "", fmt.Errorf("version failed to open MySQL database: %w", err)
}
defer db.Close()

var version string
err = db.QueryRowContext(ctx, "SELECT VERSION()").Scan(&version)
Expand All @@ -96,11 +111,10 @@ func (mi *MySQLImpl) Version(ctx context.Context, dsn string) (string, error) {
// Note it doesn't include CPU or memory usage which could be obtained from other sources.
func (mi *MySQLImpl) Load(ctx context.Context, dsn string) (int, error) {
log.FromContext(ctx).Info("Getting MySQL database load")
db, err := sql.Open("mysql", dsn)
db, err := mi.getConnection(ctx, dsn)
if err != nil {
return 0, fmt.Errorf("load failed to open MySQL database: %w", err)
}
defer db.Close()

query := `
SELECT SUM(data_length + index_length) AS total_size
Expand All @@ -121,11 +135,10 @@ func (mi *MySQLImpl) Initialize(ctx context.Context, dsn string) error {
log.FromContext(ctx).Info("Initializing MySQL database")

// Connect to MySQL server without specifying a database
db, err := sql.Open("mysql", dsn)
db, err := mi.getConnection(ctx, dsn)
if err != nil {
return err
}
defer db.Close()

// Create the database if it doesn't exist
_, err = db.ExecContext(ctx, "CREATE DATABASE IF NOT EXISTS dbaas_controller")
Expand Down Expand Up @@ -182,11 +195,10 @@ func (mi *MySQLImpl) databaseInfo(ctx context.Context, dsn, namespace, name stri
info := DatabaseInfo{}

// Connect to MySQL server and select the dbaas_controller database
db, err := sql.Open("mysql", dsn)
db, err := mi.getConnection(ctx, dsn)
if err != nil {
return info, fmt.Errorf("failed to connect to MySQL server: %w", err)
}
defer db.Close()

_, err = db.ExecContext(ctx, "USE dbaas_controller")
if err != nil {
Expand Down Expand Up @@ -240,11 +252,10 @@ func (mi *MySQLImpl) CreateDatabase(ctx context.Context, dsn, name, namespace st
return info, fmt.Errorf("failed to get database info: %w", err)
}
// Connect to the database server
db, err := sql.Open("mysql", dsn)
db, err := mi.getConnection(ctx, dsn)
if err != nil {
return info, fmt.Errorf("create database error connecting to the database server: %w", err)
}
defer db.Close()

// Ping the database to verify connection establishment.
if err := db.PingContext(ctx); err != nil {
Expand Down Expand Up @@ -294,11 +305,10 @@ func (mi *MySQLImpl) DropDatabase(ctx context.Context, dsn, name, namespace stri
}

// Connect to the database server
db, err := sql.Open("mysql", dsn)
db, err := mi.getConnection(ctx, dsn)
if err != nil {
return fmt.Errorf("drop database error connecting to the database server: %w", err)
}
defer db.Close()

// Ping the database to verify connection establishment.
if err := db.PingContext(ctx); err != nil {
Expand Down
2 changes: 0 additions & 2 deletions kind-config.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: dbaas-controller-cluster
nodes:
- role: control-plane
- role: worker
- role: worker
image: kindest/node:v1.29.2

0 comments on commit 7602a9e

Please sign in to comment.