Skip to content

Commit

Permalink
Merge pull request #7 from uselagoon/feat-postgresql-implementation
Browse files Browse the repository at this point in the history
feat: implement postgres database management
  • Loading branch information
Marco Cadetg authored May 29, 2024
2 parents dcf07dc + 558b488 commit 34ad84a
Show file tree
Hide file tree
Showing 35 changed files with 1,664 additions and 1,257 deletions.
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,12 @@ test: manifests generate fmt vet envtest ## Run tests.

.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
@if ! kind get clusters | grep -q $(KIND_CLUSTER); then \
docker network inspect $(KIND_CLUSTER) >/dev/null 2>&1 || docker network create $(KIND_CLUSTER); \
kind create cluster --wait=60s --name=$(KIND_CLUSTER) --config=kind-config.yaml; \
else \
echo "Cluster $(KIND_CLUSTER) already exists"; \
fi

.PHONY: delete-kind-cluster
delete-kind-cluster:
Expand Down
3 changes: 2 additions & 1 deletion PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ resources:
version: v1alpha1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: lagoon.sh
group: crd
kind: DatabaseMySQLProvider
kind: RelationalDatabaseProvider
path: github.com/uselagoon/dbaas-controller/api/v1alpha1
version: v1alpha1
version: "3"
54 changes: 28 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ It allows for provisiong and deprovisioning of shared MySQL/MariaDB, PostgreSQL,
## Current Status of the Project

WIP - Work in Progress
There is still a lot of work to be done on this project. The current status is that the controller is able to provision and deprovision MySQL databases. But there is still a lot of work to be done to make it production ready.
There is still a some work to be done on this project. The current status is that the controller is able to provision and deprovision MySQL databases. But there is still a lot of work to be done to make it production ready.

- [x] Setup e2e tests
- [x] Provision MySQL databases (basic) - no support for additional users, seeding, etc.
- [x] Deprovision MySQL databases
- [ ] Provision PostgreSQL databases
- [ ] Deprovision PostgreSQL databases
- [x] Provision PostgreSQL databases
- [x] Deprovision PostgreSQL databases
- [ ] Provision MongoDB databases
- [ ] Deprovision MongoDB databases
- [ ] Plan to migrate from old `dbaaas-operator` to `dbaas-controller`
Expand Down Expand Up @@ -58,57 +58,59 @@ Key Features:

To interact with the dbaas-controller, the following CRDs are introduced:

- DatabaseXProvider
- This CRD is used to define a database provider, such as MySQL, PostgreSQL, or MongoDB.
- RelationalDatabaseProvider
- This CRD is used to define a database provider, such as MySQL and PostgreSQL.
- DatabaseRequest
- DatabaseMigration

Basic usage of the CRs in combination with the dbaas-controller is outlined below.

- DatabaseRequest: Lagoon creates a DatabaseRequest CR to request a database instance
- The dbaas-controller processes the request and provisions the database instance based on the request
- The controller uses the relevant DatabaseXProvider CR to determine how it should provision the database
- The controller uses the relevant RelationalDatabaseProvider CR to determine how it should provision the database

## DatabaseMySQLProvider CRD Documentation
## RelationalDatabaseProvider CRD Documentation

The `DatabaseMySQLProvider` CRD defines a Kubernetes-native way to manage MySQL database connections and configurations. This custom resource allows to define MySQL databases.
The `RelationalDatabaseProvider` CRD defines a Kubernetes-native way to manage relational database connections and configurations. This custom resource allows to define MySQL and PostgreSQL databases.

Use the status mysqlConnectionStatus field to check the status of the MySQL connections defined in the spec.
Use the status connectionStatus field to check the status of the MySQL connections defined in the spec.

### DatabaseMySQLProvider Spec Fields
### RelationalDatabaseProvider Spec Fields

- kind (required): The type of database provider, which can be either mysql or postgresql.
- scope (required): Defines the scope of the database request, which influences the environment setup. Valid values are production, development, and custom. Defaults to development if not specified.
- mysqlConnections (required): A list of `MySQLConnection` objects that detail the connection parameters to MySQL databases. At least one connection must be defined.
- connections (required): A list of `connection` objects that detail the connection parameters to MySQL or PostgreSQL databases. At least one connection must be defined.

- MySQLConnection Fields
- name (required): A unique name for the MySQL database connection, used to identify and reference the connection in database requests.
- hostname (required): The hostname of the MySQL database server.
- replicaHostnames (optional): A list of hostnames for the MySQL replica databases.
- connection Fields
- name (required): A unique name for the MySQL or PostgreSQL database connection, used to identify and reference the connection in database requests.
- hostname (required): The hostname of the MySQL or PostgreSQL database server.
- replicaHostnames (optional): A list of hostnames for the MySQLi or PostgreSQL replica databases.
- passwordSecretRef (required): A reference to a Kubernetes Secret containing the password for the database connection.
- port (required): The port on which the MySQL database server is listening. Must be between 1 and 65535.
- username (required): The username for logging into the MySQL database.
- port (required): The port on which the MySQLi or PostgreSQL database server is listening. Must be between 1 and 65535.
- username (required): The username for logging into the MySQLi or PostgreSQL database.
- enabled (required): A flag indicating whether this database connection is enabled. Defaults to true.

### DatabaseMySQLProvider Status Fields
### RelationalDatabaseProvider Status Fields

- conditions: Provides detailed conditions of the MySQLProvider like readiness, errors, etc.
- mysqlConnectionStatus: A list of statuses for the MySQL connections defined in the spec.
- conditions: Provides detailed conditions of the `RelationalDatabaseProvider` like readiness, errors, etc.
- connectionStatus: A list of statuses for the MySQL or PostgreSQL connections defined in the spec.

- MySQLConnectionStatus Fields
- hostname (required): The hostname of the MySQL database server.
- mysqlVersion (required): The version of the MySQL server.
- connectionStatus Fields
- hostname (required): The hostname of the MySQL or PostgreSQL database server.
- mysqlVersion (required): The version of the MySQL or PostgreSQL server.
- enabled (required): Indicates if the database connection is enabled.
- status (required): The current status of the database connection, with valid values being available and unavailable.
- observedGeneration: Reflects the generation of the most recently observed DatabaseMySQLProvider object.
- observedGeneration: Reflects the generation of the most recently observed RelationalDatabaseProvider object.

### DatabaseMySQLProvider Example
### RelationalDatabaseProvider Example

```yaml
apiVersion: v1alpha1
kind: DatabaseMySQLProvider
kind: RelationalDatabaseProvider
metadata:
name: example-mysql-provider
spec:
kind: mysql
scope: development
mysqlConnections:
- name: primary-db
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// MySQLConnection defines the connection to a MySQL database
type MySQLConnection struct {
// Name is the name of the MySQL database connection
// Connection defines the connection to a relational database like MySQL or PostgreSQL
type Connection struct {
// Name is the name of the relational database like MySQL or PostgreSQL connection
// it is used to identify the connection. Please use a unique name
// for each connection. This field will be used in the DatabaseRequest
// to reference the connection. The databasemysqlprovider controller will
// to reference the connection. The relationaldatabaseprovider controller will
// error if the name is not unique.
Name string `json:"name"`

//+kubebuilder:required
// Hostname is the hostname of the MySQL database
// Hostname is the hostname of the relational database
Hostname string `json:"hostname"`

//+kubebuilder:optional
// ReplicaHostnames is the list of hostnames of the MySQL database replicas
// ReplicaHostnames is the list of hostnames of the relational database replicas
ReplicaHostnames []string `json:"replicaHostnames,omitempty"`

//+kubebuilder:required
Expand All @@ -46,21 +46,28 @@ type MySQLConnection struct {
//+kubebuilder:validation:Required
//+kubebuilder:validation:Minimum=1
//+kubebuilder:validation:Maximum=65535
// Port is the port of the MySQL database
// Port is the port of the relational database
Port int `json:"port"`

//+kubebuilder:required
// Username is the username of the MySQL database
// Username is the username of the relational database
Username string `json:"username"`

//+kubebuilder:required
//+kubebuilder:default:=true
// Enabled is a flag to enable or disable the MySQL database
// Enabled is a flag to enable or disable the relational database
Enabled bool `json:"enabled"`
}

// DatabaseMySQLProviderSpec defines the desired state of DatabaseMySQLProvider
type DatabaseMySQLProviderSpec struct {
// RelationalDatabaseProviderSpec defines the desired state of RelationalDatabaseProvider
type RelationalDatabaseProviderSpec struct {
//+kubebuilder:required
//+kubebuilder:validation:Required
//+kubebuilder:validation:Enum=mysql;postgres
// Type is the type of the relational database provider
// it can be either "mysql" or "postgres"
Type string `json:"type"`

//+kubebuilder:required
//+kubebuilder:validation:Required
//+kubebuilder:validation:Enum=production;development;custom
Expand All @@ -70,27 +77,27 @@ type DatabaseMySQLProviderSpec struct {
Scope string `json:"scope"`

//+kubebuilder:validation:MinItems=1
// MySQLConnections defines the connection to a MySQL database
MySQLConnections []MySQLConnection `json:"mysqlConnections"`
// Connections defines the connection to a relational database
Connections []Connection `json:"connections"`
}

// MySQLConnectionStatus defines the status of a MySQL database connection
type MySQLConnectionStatus struct {
// ConnectionStatus defines the status of a relational database connection
type ConnectionStatus struct {
//+kubebuilder:required
// Name is the name of the MySQL database connection
// Name is the name of the relational database connection
// it is used to identify the connection. Please use a unique name
// for each connection. This field will be used in the DatabaseRequest
// to reference the connection. The databasemysqlprovider controller will
// to reference the connection. The relationaldatabaseprovider controller will
// error if the name is not unique.
Name string `json:"name"`

//+kubebuilder:required
// Hostname is the hostname of the MySQL database
// Hostname is the hostname of the relational database
Hostname string `json:"hostname"`

//+kubebuilder:required
// MySQLVersion is the version of the MySQL database
MySQLVersion string `json:"mysqlVersion"`
// DatabaseVersion is the version of the relational database
DatabaseVersion string `json:"databaseVersion"`

//+kubebuilder:required
//+kubebuilder:validation:Required
Expand All @@ -100,17 +107,17 @@ type MySQLConnectionStatus struct {
//+kubebuilder:required
//+kubebuilder:validation:Required
//+kubebuilder:validation:Enum=available;unavailable
// Status is the status of the MySQL database
// Status is the status of the relational database
Status string `json:"status"`
}

// DatabaseMySQLProviderStatus defines the observed state of DatabaseMySQLProvider
type DatabaseMySQLProviderStatus struct {
// RelationalDatabaseProviderStatus defines the observed state of RelationalDatabaseProvider
type RelationalDatabaseProviderStatus struct {
// Conditions defines the status conditions
Conditions []metav1.Condition `json:"conditions,omitempty"`

// MySQLConnectionStatus provides the status of the MySQL database
MySQLConnectionStatus []MySQLConnectionStatus `json:"mysqlConnectionStatus,omitempty"`
// ConnectionStatus provides the status of the relational database
ConnectionStatus []ConnectionStatus `json:"connectionStatus,omitempty"` // nolint:lll

// ObservedGeneration is the last observed generation
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
Expand All @@ -120,24 +127,24 @@ type DatabaseMySQLProviderStatus struct {
//+kubebuilder:subresource:status
//+kubebuilder:resource:scope=Cluster

// DatabaseMySQLProvider is the Schema for the databasemysqlproviders API
type DatabaseMySQLProvider struct {
// RelationalDatabaseProvider is the Schema for the relationaldatabaseprovider API
type RelationalDatabaseProvider struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec DatabaseMySQLProviderSpec `json:"spec,omitempty"`
Status DatabaseMySQLProviderStatus `json:"status,omitempty"`
Spec RelationalDatabaseProviderSpec `json:"spec,omitempty"`
Status RelationalDatabaseProviderStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

// DatabaseMySQLProviderList contains a list of DatabaseMySQLProvider
type DatabaseMySQLProviderList struct {
// RelationalDatabaseProviderList contains a list of RelationalDatabaseProvider
type RelationalDatabaseProviderList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []DatabaseMySQLProvider `json:"items"`
Items []RelationalDatabaseProvider `json:"items"`
}

func init() {
SchemeBuilder.Register(&DatabaseMySQLProvider{}, &DatabaseMySQLProviderList{})
SchemeBuilder.Register(&RelationalDatabaseProvider{}, &RelationalDatabaseProviderList{})
}
Loading

0 comments on commit 34ad84a

Please sign in to comment.