Skip to content

Help manage users and databases (CRUD + permissions) in a database from Kubernetes

Notifications You must be signed in to change notification settings

cuppett/mysql-dba-operator

Repository files navigation

MySQL DBA Operator

This operator does not provision MySQL database servers. It works against and within existing database servers. It helps user applications by allowing provisioning of individual databases and database users inside an existing MySQL database server.

Types

AdminConnection

Database servers can be provisioned separately and then made available for use with this operator by defining an AdminConnection. AdminConnection resources can be created in any namespace separate from user applications.

Sample:

apiVersion: mysql.apps.cuppett.dev/v1alpha1
kind: AdminConnection
metadata:
  name: db1
  namespace: cuppett
spec:
  host: 172.25.234.155.nip.io
  adminPassword:
    secretKeyRef:
      name: mysql
      key: database-root-password
  allowedNamespaces:
    - tenant1
    - openshift-*
    - blog-*

adminUser can be defined similarly to adminPassword. The default username is 'root' and the default password is an empty string. host is required to be a valid hostname.

allowedNamespaces is there to enable usage of the admin connection for provisioning only where desired. By default, only the namespace containing the AdminConnection is permitted (and does not need specified). Allows specifying prefix by adding a trailing '' character (e.g. blog-).

With each AdminConnection an administrative database is created and updated to track the objects provisioned with this operator. This database helps ensure that unique UID, name and namespace databases are created and that those previously existing or provisioned in other namespaces are not overridden, commandeered or inadvertently removed.

The following tables are created and updated as objects are created/destroyed:

mysql> describe zz_dba_operator.managed_databases;
+---------------+-------------+------+-----+---------+-------+
| Field         | Type        | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| uuid          | varchar(36) | NO   | PRI | NULL    |       |
| namespace     | varchar(64) | YES  |     | NULL    |       |
| name          | varchar(64) | YES  |     | NULL    |       |
| database_name | varchar(64) | YES  |     | NULL    |       |
| created_at    | datetime(3) | YES  |     | NULL    |       |
| updated_at    | datetime(3) | YES  |     | NULL    |       |
+---------------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

mysql> describe zz_dba_operator.managed_users;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| uuid       | varchar(36) | NO   | PRI | NULL    |       |
| namespace  | varchar(64) | YES  |     | NULL    |       |
| name       | varchar(64) | YES  |     | NULL    |       |
| username   | varchar(32) | YES  |     | NULL    |       |
| created_at | datetime(3) | YES  |     | NULL    |       |
| updated_at | datetime(3) | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

Database

Once you have an AdminConnection resource, you can create a Database resource. Creating a new Database resource effectively triggers a CREATE DATABASE against the server to match the specification in your custom resource.

Sample:

apiVersion: mysql.apps.cuppett.dev/v1alpha1
kind: Database
metadata:
  name: mydb
  namespace: customer-ns
spec:
  adminConnection:
    namespace: cuppett /* Optional */
    name: db1
  name: mydb
  characterSet: utf8
  collate: utf8_general_ci

Modifications to either characterSet or collate trigger changes to the database defaults. Updates to name are rejected by a validating webhook.

DatabaseUser

Finally, you can create a DatabaseUser resource to programmatically create users and control a few attributes and permissions for the user. This object used to drive CREATE USER and ALTER USER operations within the database.

Sample:

apiVersion: mysql.apps.cuppett.dev/v1alpha1
kind: DatabaseUser
metadata:
  name: cuppett
  namespace: customer-ns
spec:
  adminConnection:
    namespace: cuppett /* Optional */
    name: db1
  username: cuppett
  identification:
    authPlugin: ''
    clearText: true
    authString:
      secretKeyRef:
        name: db-password
        key: password
  databasePermissions:
  - databaseName: mydb
    grants: /* Optional */
    - SELECT
    - INSERT
    - UPDATE
    - DELETE

databasePermissions is a list of Database object names in the cluster (not names in the database server). This allows for maintaining correct constraints and permission controls via both systems (Kubernetes and MySQL).

NOTE: Optional authString references a v1.Secret created by the user. The v1.Secret will have ownerReferences updated to belong to the operator once consumed. This is to facilitate one-use passwords and automatically clean them up or scrub them when the user is removed/dropped.

Development & Testing

Prerequisites

Testing

Ensure you've installed the prerequisites above.

make test

Lineage

Operator originally built using Operator SDK 1.3.0
Operator currently built using Operator SDK 1.32.0