diff --git a/CHANGELOG.md b/CHANGELOG.md index 524a6c9..1e60dd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Added + +- `PostgresDatabase` Resource - Add database naming strategy [#38](https://github.com/mruoss/kompost/pull/38), [#42](https://github.com/mruoss/kompost/pull/42) + ## [0.3.0] - 2023-07-13 ### Changed diff --git a/docs/postgres/postgres_database.md b/docs/postgres/postgres_database.md index 7bf0041..36c5876 100644 --- a/docs/postgres/postgres_database.md +++ b/docs/postgres/postgres_database.md @@ -10,22 +10,6 @@ Once your [`PostgresInstance`](postgres_instance.md) or [`PostgresClusterInstance`](postgres_cluster_instance.md) is set up and connected, you can declare your database resources. -```yaml -apiVersion: kompost.chuge.li/v1alpha1 -kind: PostgresDatabase -metadata: - name: some-database - namespace: default -spec: - instanceRef: - name: staging-server -``` - -Based on the CRD definition above, it will create a database called `default_some_database`, -where the appended prefix `default_` is the previously informed namespaced. -To avoid the use of the namespace you can set the `usingPrefixNamingStrategy` -attribute to false. See example bellow: - ```yaml apiVersion: kompost.chuge.li/v1alpha1 kind: PostgresDatabase @@ -35,11 +19,8 @@ metadata: spec: instanceRef: name: staging-server - usingPrefixNamingStrategy: false ``` -In this case the final name of the database will be `some_database`. - ## Connection Details Once applied to the cluster, Kompost creates a database and **two users**. One @@ -85,6 +66,44 @@ data: DB_USER: ZGVmYXVsdF9zb21lX2RhdGFiYXNlX2FwcA== ``` +## Database Naming Strategy + +The field `databaseNamingStrategy` controls how the database name is derived +from the resource name. Possible values are `resource_name` and +`prefix_namespace`. The default strategy is `prefix_namespace`. + +### Strategies + +- `resource_name`: Use the resource name as database name +- `prefix_namespace`: Prefix the resource name with the namespace to get a + cluster-wide unique name. + +### Example + +Taking the [basic usage example](#basic-usage) from above, the resulting +database on the server is named `default_some_database`. + +```yaml +apiVersion: kompost.chuge.li/v1alpha1 +kind: PostgresDatabase +metadata: + name: some-database + namespace: default +spec: + instanceRef: + name: staging-server + databaseNamingStrategy: resource_name +``` + +The resulting database on the server is named `some_database`. + +!!! warning Strategy resource_name can lead to conflicts + + Using the `resource_name` strategy can lead to conflicts. If you define + `PostgresDatabase` resources with the same name in different namespaces, + both resources would control the same database on the server. Therefore the + default strategy is `prefix_namespace` + ## Deletion Policy - Abandoning Underlying Resources When using Kompost on a live environment, you might want to protect the @@ -103,7 +122,7 @@ metadata: kompost.chuge.li/deletion-policy: abandon # <-- underlying resources are abandoned (not deleted) when this resource gets deleted spec: instanceRef: - name: staging-server + name: staging-server ``` ## Database Creation Parameters @@ -113,7 +132,7 @@ parameters](https://www.postgresql.org/docs/current/sql-createdatabase.html) when creating a database. Some of these parameters are supported by Kompost and can be passed in `spec.params`. -!!! note Creation params cannot be changed +!!! note Creation params cannot be changed These parameters are only used when the database is created. Kompost therefore denies requests to change them on an existing resource. diff --git a/lib/kompost/kompo/postgres/controller/database_controller.ex b/lib/kompost/kompo/postgres/controller/database_controller.ex index 0241979..df9a8be 100644 --- a/lib/kompost/kompo/postgres/controller/database_controller.ex +++ b/lib/kompost/kompo/postgres/controller/database_controller.ex @@ -37,10 +37,7 @@ defmodule Kompost.Kompo.Postgres.Controller.DatabaseController do resource = axn.resource namespace = resource["metadata"]["namespace"] - using_prefix_strategy? = - resource["spec"]["usingPrefixNamingStrategy"] != "true" - - db_name = Database.name(resource, prefix_namespace: using_prefix_strategy?) + db_name = Database.name(resource, strategy: resource["spec"]["databaseNamingStrategy"]) db_params = Params.new!(resource["spec"]["params"] || %{}) instance = resource |> instance_id() |> Instance.lookup() @@ -136,8 +133,7 @@ defmodule Kompost.Kompo.Postgres.Controller.DatabaseController do @spec delete_resources(Bonny.Axn.t()) :: {:ok, Bonny.Axn.t()} | {:error, Bonny.Axn.t()} def delete_resources(axn) do resource = axn.resource - using_prefix_strategy? = resource["spec"]["usingPrefixNamingStrategy"] != "true" - db_name = Database.name(resource, prefix_namespace: using_prefix_strategy?) + db_name = Database.name(resource, strategy: resource["spec"]["databaseNamingStrategy"]) users = resource["status"]["users"] instance = resource |> instance_id() |> Instance.lookup() diff --git a/lib/kompost/kompo/postgres/database.ex b/lib/kompost/kompo/postgres/database.ex index 46da137..248f3b8 100644 --- a/lib/kompost/kompo/postgres/database.ex +++ b/lib/kompost/kompo/postgres/database.ex @@ -15,23 +15,21 @@ defmodule Kompost.Kompo.Postgres.Database do "default_foo_bar" iex> resource = %{"metadata" => %{"namespace" => "default", "name" => "foo-bar"}} - ...> Kompost.Kompo.Postgres.Database.name(resource, prefix_namespace: false) + ...> Kompost.Kompo.Postgres.Database.name(resource, strategy: "resource_name") "foo_bar" """ @spec name(map(), Keyword.t()) :: binary() def name(resource, opts \\ []) def name(resource, opts) do - prefix_namespace = Keyword.get(opts, :prefix_namespace, true) - - case prefix_namespace do - true -> + case Keyword.get(opts, :strategy, "prefix_namespace") do + "prefix_namespace" -> Slugger.slugify_downcase( "#{resource["metadata"]["namespace"]}_#{resource["metadata"]["name"]}", ?_ ) - _ -> + "resource_name" -> Slugger.slugify_downcase( "#{resource["metadata"]["name"]}", ?_ diff --git a/lib/kompost/kompo/postgres/v1alpha1/postgres_database.ex b/lib/kompost/kompo/postgres/v1alpha1/postgres_database.ex index 00fa1a5..5d601c9 100644 --- a/lib/kompost/kompo/postgres/v1alpha1/postgres_database.ex +++ b/lib/kompost/kompo/postgres/v1alpha1/postgres_database.ex @@ -24,8 +24,6 @@ defmodule Kompost.Kompo.Postgres.V1Alpha1.PostgresDatabase do - required: ["instanceRef"] - required: ["clusterInstanceRef"] properties: - usingPrefixNamingStrategy: - type: boolean instanceRef: type: object properties: @@ -36,6 +34,10 @@ defmodule Kompost.Kompo.Postgres.V1Alpha1.PostgresDatabase do properties: name: type: string + databaseNamingStrategy: + type: string + enum: ["resource_name", "prefix_namespace"] + description: "(Optional) Strategy to derive the name of the `database` on the server. resource_name uses the resource name as DB name. `prefix_namespace` prefixes the resource name with the namespace. Defaults to `prefix_namespace`" params: description: "Parameters passed to CREATE TEMPLATE." type: object diff --git a/priv/manifest/postgresdatabase.crd.yaml b/priv/manifest/postgresdatabase.crd.yaml index 53c8ead..ba7cd2e 100644 --- a/priv/manifest/postgresdatabase.crd.yaml +++ b/priv/manifest/postgresdatabase.crd.yaml @@ -40,6 +40,10 @@ spec: name: type: string type: object + databaseNamingStrategy: + type: string + enum: ["resource_name", "prefix_namespace"] + description: "(Optional) Strategy to derive the name of the `database` on the server. resource_name uses the resource name as DB name. `prefix_namespace` prefixes the resource name with the namespace. Defaults to `prefix_namespace`" params: description: Parameters passed to CREATE TEMPLATE. properties: @@ -84,8 +88,8 @@ spec: type: string status: enum: - - 'True' - - 'False' + - "True" + - "False" type: string type: type: string