Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: EasyMile/postgresql-operator
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2.1.0
Choose a base ref
...
head repository: EasyMile/postgresql-operator
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on Mar 28, 2023

  1. Copy the full SHA
    ffc4fdf View commit details
  2. Copy the full SHA
    5c8e56a View commit details
  3. fix: Fix log messages

    oxyno-zeta committed Mar 28, 2023
    Copy the full SHA
    8ee42e7 View commit details
  4. Copy the full SHA
    bf8143c View commit details
  5. chore: Release 2.1.1

    oxyno-zeta committed Mar 28, 2023
    Copy the full SHA
    d0c58f8 View commit details
  6. fix: Fix RBAC for events

    oxyno-zeta committed Mar 28, 2023
    Copy the full SHA
    a06eadb View commit details

Commits on May 4, 2023

  1. ci: Upgrade workflows

    oxyno-zeta committed May 4, 2023
    Copy the full SHA
    c080bba View commit details

Commits on Jan 25, 2024

  1. fix(postgresql:postgresqldatabase_controller): Fix pgdb deletion not …

    …checking is pgur exists
    
    This is creating dead users in engine
    oxyno-zeta committed Jan 25, 2024
    Copy the full SHA
    34b47cd View commit details
  2. fix(postgresql:postgresqluserrole_controller): Change deletion algori…

    …thm and add some security to avoid status flush
    oxyno-zeta committed Jan 25, 2024
    Copy the full SHA
    1e536e2 View commit details
  3. Copy the full SHA
    97fe634 View commit details
  4. ci: Upgrade actions

    oxyno-zeta committed Jan 25, 2024
    Copy the full SHA
    c841f0d View commit details
  5. Copy the full SHA
    9dc3205 View commit details
  6. chore: Release 2.1.2

    oxyno-zeta committed Jan 25, 2024
    Copy the full SHA
    4c40700 View commit details

Commits on Mar 1, 2024

  1. Copy the full SHA
    a53a5d7 View commit details
  2. Copy the full SHA
    e48d081 View commit details
  3. style: Fix linter errors

    oxyno-zeta committed Mar 1, 2024
    Copy the full SHA
    91f0511 View commit details
  4. Copy the full SHA
    05dfd7f View commit details
  5. Copy the full SHA
    a41fef7 View commit details
  6. Copy the full SHA
    a442efa View commit details
  7. fix(internal:controller:postgresql:postgresqlengineconfiguration): Ch…

    …ange default port for pg bouncer
    oxyno-zeta committed Mar 1, 2024
    Copy the full SHA
    7688282 View commit details
  8. Copy the full SHA
    66e7238 View commit details
  9. Copy the full SHA
    b2ea3c3 View commit details
  10. Copy the full SHA
    c8c9a02 View commit details

Commits on Mar 5, 2024

  1. feat: Remove support for postgresql user

    BREAKING CHANGE: Do not support anymore postgresql user. Switch to postgresqluserrole is now mandatory
    oxyno-zeta committed Mar 5, 2024
    Copy the full SHA
    57dac63 View commit details
  2. Copy the full SHA
    345feed View commit details
  3. Copy the full SHA
    19e369f View commit details
  4. Copy the full SHA
    005ca62 View commit details
  5. feat: Add custom metric to count reconcile errors in a detailed manner

    This is including resource name and namespace in labels where the default provided isn't
    oxyno-zeta committed Mar 5, 2024
    Copy the full SHA
    6de70aa View commit details
  6. Copy the full SHA
    47f6472 View commit details
  7. Copy the full SHA
    4f78343 View commit details
  8. Copy the full SHA
    68029ca View commit details
  9. Copy the full SHA
    4b80c38 View commit details
  10. Copy the full SHA
    ca29001 View commit details
  11. Copy the full SHA
    830b765 View commit details
  12. Copy the full SHA
    14992e8 View commit details
  13. Copy the full SHA
    b489cd1 View commit details
  14. chore: Release 3.0.0

    oxyno-zeta committed Mar 5, 2024
    Copy the full SHA
    d1bb97b View commit details

Commits on Mar 7, 2024

  1. Copy the full SHA
    5467753 View commit details
  2. Copy the full SHA
    7052c93 View commit details

Commits on Apr 15, 2024

  1. Copy the full SHA
    2bf0739 View commit details
  2. Copy the full SHA
    93d708d View commit details
  3. Copy the full SHA
    3eb8654 View commit details
  4. Copy the full SHA
    809a904 View commit details
  5. Copy the full SHA
    6ba1417 View commit details
  6. Copy the full SHA
    5c74088 View commit details
  7. tests: Clean dead code

    oxyno-zeta committed Apr 15, 2024
    Copy the full SHA
    24e06e6 View commit details
  8. Copy the full SHA
    08a8112 View commit details
  9. fix(postgresqldatabase): Fix deletion race by closing database connec…

    …tions before deleting database
    oxyno-zeta committed Apr 15, 2024
    Copy the full SHA
    e382d0a View commit details
  10. Copy the full SHA
    d20dc1d View commit details
  11. chore: Prepare changelog

    oxyno-zeta committed Apr 15, 2024
    Copy the full SHA
    be57b82 View commit details
Showing with 18,705 additions and 6,079 deletions.
  1. +13 −13 .github/workflows/ci.yml
  2. +2 −2 .github/workflows/labeler.yml
  3. +2 −2 .github/workflows/size.yml
  4. +6 −2 .github/workflows/stale.yml
  5. +517 −0 .golangci.yaml
  6. +0 −61 .golangci.yml
  7. +1 −1 .vscode/launch.json
  8. +78 −0 CHANGELOG.md
  9. +11 −5 Dockerfile
  10. +79 −28 Makefile
  11. +9 −4 PROJECT
  12. +15 −1 README.md
  13. 0 {apis → api}/postgresql/common/common.go
  14. 0 {apis → api}/postgresql/v1alpha1/groupversion_info.go
  15. +1 −1 {apis → api}/postgresql/v1alpha1/postgresqldatabase_types.go
  16. +36 −0 {apis → api}/postgresql/v1alpha1/postgresqlengineconfiguration_types.go
  17. +149 −0 api/postgresql/v1alpha1/postgresqlpublication_types.go
  18. +37 −1 {apis → api}/postgresql/v1alpha1/postgresqluserrole_types.go
  19. +225 −42 {apis → api}/postgresql/v1alpha1/zz_generated.deepcopy.go
  20. +0 −135 apis/postgresql/v1alpha1/postgresqluser_types.go
  21. +71 −17 { → cmd}/main.go
  22. +14 −9 config/crd/bases/postgresql.easymile.com_postgresqldatabases.yaml
  23. +97 −8 config/crd/bases/postgresql.easymile.com_postgresqlengineconfigurations.yaml
  24. +179 −0 config/crd/bases/postgresql.easymile.com_postgresqlpublications.yaml
  25. +48 −8 config/crd/bases/postgresql.easymile.com_postgresqluserroles.yaml
  26. +0 −140 config/crd/bases/postgresql.easymile.com_postgresqlusers.yaml
  27. +7 −7 config/crd/kustomization.yaml
  28. +2 −2 ...ction_in_postgresql_postgresqlusers.yaml → cainjection_in_postgresql_postgresqlpublications.yaml}
  29. +1 −1 .../{webhook_in_postgresql_postgresqlusers.yaml → webhook_in_postgresql_postgresqlpublications.yaml}
  30. +104 −34 config/default/kustomization.yaml
  31. +4 −5 config/default/manager_auth_proxy_patch.yaml
  32. +0 −10 config/default/manager_config_patch.yaml
  33. +0 −21 config/manager/controller_manager_config.yaml
  34. +0 −8 config/manager/kustomization.yaml
  35. +35 −4 config/manager/manager.yaml
  36. +2 −1 config/manifests/kustomization.yaml
  37. +6 −0 config/prometheus/monitor.yaml
  38. +7 −0 config/rbac/auth_proxy_client_clusterrole.yaml
  39. +7 −0 config/rbac/auth_proxy_role.yaml
  40. +7 −0 config/rbac/auth_proxy_role_binding.yaml
  41. +6 −0 config/rbac/auth_proxy_service.yaml
  42. +7 −0 config/rbac/leader_election_role.yaml
  43. +7 −0 config/rbac/leader_election_role_binding.yaml
  44. +31 −0 config/rbac/postgresql_postgresqlpublication_editor_role.yaml
  45. +27 −0 config/rbac/postgresql_postgresqlpublication_viewer_role.yaml
  46. +13 −7 config/rbac/role.yaml
  47. +7 −0 config/rbac/role_binding.yaml
  48. +7 −0 config/rbac/service_account.yaml
  49. +33 −0 config/samples/engineconfiguration/full-example.yaml
  50. +1 −0 config/samples/kustomization.yaml
  51. +45 −0 config/samples/postgresql_v1alpha1_postgresqlpublication.yaml
  52. +0 −21 config/samples/postgresql_v1alpha1_postgresqluser.yaml
  53. +14 −1 config/samples/postgresql_v1alpha1_postgresqluserrole.yaml
  54. +0 −21 config/samples/user/full.yaml
  55. +0 −18 config/samples/user/simple.yaml
  56. +7 −1 config/samples/userrole/managed-simple-rotation.yaml
  57. +19 −0 config/samples/userrole/managed-simple.yaml
  58. +26 −7 config/samples/userrole/provided-simple.yaml
  59. +1 −1 config/scorecard/patches/basic.config.yaml
  60. +5 −5 config/scorecard/patches/olm.config.yaml
  61. +0 −192 controllers/postgresql/postgres/database.go
  62. +0 −156 controllers/postgresql/postgres/postgres.go
  63. +0 −584 controllers/postgresql/postgresqluser_controller.go
  64. +0 −705 controllers/postgresql/postgresqluser_controller_test.go
  65. +0 −1,139 controllers/postgresql/suite_test.go
  66. +38 −37 docs/crds/PostgresqlDatabase.md
  67. +56 −22 docs/crds/PostgresqlEngineConfiguration.md
  68. +117 −0 docs/crds/PostgresqlPublication.md
  69. +0 −84 docs/crds/PostgresqlUser.md
  70. +98 −38 docs/crds/PostgresqlUserRole.md
  71. +48 −57 go.mod
  72. +108 −798 go.sum
  73. +306 −0 grafana/controller-resources-metrics.json
  74. +898 −0 grafana/controller-runtime-metrics.json
  75. +19 −0 grafana/custom-metrics/config.yaml
  76. +212 −0 grafana/custom-metrics/custom-metrics-dashboard.json
  77. +2 −2 helm/postgresql-operator/Chart.yaml
  78. +14 −9 helm/postgresql-operator/crds/postgresql.easymile.com_postgresqldatabases.yaml
  79. +97 −8 helm/postgresql-operator/crds/postgresql.easymile.com_postgresqlengineconfigurations.yaml
  80. +179 −0 helm/postgresql-operator/crds/postgresql.easymile.com_postgresqlpublications.yaml
  81. +48 −8 helm/postgresql-operator/crds/postgresql.easymile.com_postgresqluserroles.yaml
  82. +0 −140 helm/postgresql-operator/crds/postgresql.easymile.com_postgresqlusers.yaml
  83. +306 −0 helm/postgresql-operator/files/dashboards/controller-resources-metrics.json
  84. +898 −0 helm/postgresql-operator/files/dashboards/controller-runtime-metrics.json
  85. +212 −0 helm/postgresql-operator/files/dashboards/custom-metrics-dashboard.json
  86. +21 −2 helm/postgresql-operator/templates/deployment.yaml
  87. +20 −0 helm/postgresql-operator/templates/grafana_configmap.yaml
  88. +0 −1 helm/postgresql-operator/templates/leader_election_role.yaml
  89. +13 −0 helm/postgresql-operator/templates/prometheus_rules.yaml
  90. +14 −7 helm/postgresql-operator/templates/role.yaml
  91. +16 −0 helm/postgresql-operator/templates/service.yaml
  92. +2 −1 helm/postgresql-operator/templates/service_account.yaml
  93. +35 −0 helm/postgresql-operator/templates/service_monitor.yaml
  94. +62 −1 helm/postgresql-operator/values.yaml
  95. 0 {controllers → internal/controller}/config/config.go
  96. +22 −17 {controllers → internal/controller}/postgresql/postgres/aws.go
  97. +7 −5 {controllers → internal/controller}/postgresql/postgres/azure.go
  98. +113 −0 internal/controller/postgresql/postgres/create-publication-builder.go
  99. +322 −0 internal/controller/postgresql/postgres/database.go
  100. +8 −8 {controllers → internal/controller}/postgresql/postgres/pool_manager.go
  101. +183 −0 internal/controller/postgresql/postgres/postgres.go
  102. +276 −0 internal/controller/postgresql/postgres/publication.go
  103. +156 −36 {controllers → internal/controller}/postgresql/postgres/role.go
  104. +100 −0 internal/controller/postgresql/postgres/update-publication-builder.go
  105. +284 −96 {controllers → internal/controller}/postgresql/postgresqldatabase_controller.go
  106. +344 −29 {controllers → internal/controller}/postgresql/postgresqldatabase_controller_test.go
  107. +121 −28 {controllers → internal/controller}/postgresql/postgresqlengineconfiguration_controller.go
  108. +259 −3 {controllers → internal/controller}/postgresql/postgresqlengineconfiguration_controller_test.go
  109. +646 −0 internal/controller/postgresql/postgresqlpublication_controller.go
  110. +4,072 −0 internal/controller/postgresql/postgresqlpublication_controller_test.go
  111. +427 −121 {controllers → internal/controller}/postgresql/postgresqluserrole_controller.go
  112. +3,503 −1,064 {controllers → internal/controller}/postgresql/postgresqluserrole_controller_test.go
  113. +1,990 −0 internal/controller/postgresql/suite_test.go
  114. 0 {controllers → internal/controller}/utils/random.go
  115. +5 −26 {controllers → internal/controller}/utils/utils.go
26 changes: 13 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -12,8 +12,8 @@ jobs:
config: ${{ steps.filter.outputs.config }}
docker: ${{ steps.filter.outputs.docker }}
steps:
- uses: actions/checkout@v3
- uses: dorny/paths-filter@v2
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -36,20 +36,20 @@ jobs:
needs:
- changes
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "^1.19.0"
go-version: "1.22.2"
- uses: golangci/golangci-lint-action@v3
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: v1.51.1
version: v1.56.2

# Optional: working directory, useful for monorepos
# working-directory: somedir

# Optional: golangci-lint command line arguments.
# args: --issues-exit-code=0
args: --timeout=3600s

# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true
@@ -71,10 +71,10 @@ jobs:
- changes
- lint
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "^1.19.0"
go-version: "1.22.2"
- run: make build
- run: make docker-build
test:
@@ -88,10 +88,10 @@ jobs:
- lint
- build
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "^1.19.0"
go-version: "1.22.2"
- run: |
if [ -f /usr/local/bin/dockerize ]; then
echo "dockerize found; skipping installation";
4 changes: 2 additions & 2 deletions .github/workflows/labeler.yml
Original file line number Diff line number Diff line change
@@ -4,8 +4,8 @@ on:

jobs:
triage:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v2
- uses: actions/labeler@v4
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
4 changes: 2 additions & 2 deletions .github/workflows/size.yml
Original file line number Diff line number Diff line change
@@ -2,9 +2,9 @@ name: "Add size label"
on: pull_request
jobs:
size-label:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- name: size-label
uses: "pascalgn/size-label-action@df7ad4303b35cbeb20937dbb12d5a050520e469e"
uses: pascalgn/size-label-action@v0.4.3
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
8 changes: 6 additions & 2 deletions .github/workflows/stale.yml
Original file line number Diff line number Diff line change
@@ -5,11 +5,15 @@ on:

jobs:
stale:
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v1
- uses: actions/stale@v8
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: "This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 10 days"
days-before-stale: 30
days-before-close: 10
exempt-issue-labels: "awaiting-approval,work-in-progress,no-stale"
exempt-pr-labels: "awaiting-approval,work-in-progress,no-stale"
stale-issue-label: "no-issue-activity"
stale-pr-label: "no-issue-activity"
517 changes: 517 additions & 0 deletions .golangci.yaml

Large diffs are not rendered by default.

61 changes: 0 additions & 61 deletions .golangci.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}",
"program": "${workspaceFolder}/cmd",
"cwd": "${workspaceFolder}",
"env": {
"WATCH_NAMESPACE": "",
78 changes: 78 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,83 @@
# Changelog

## 3.4.0

### Features

- Add timeout support for reconcile loops
- postgresqluserrole: Add support for extra connection url parameters

### Fixes

- postgresqldatabase: Avoid closing connections multiple time in row and close them when needed
- postgresqldatabase: Avoid alters on tables & types when owner is already the right one
- postgresqldatabase: Improve deletion by checking if roles or database are existing in engine before trying to delete them. This will avoid dead lock scenarios

### Refactor

- Use context on all SQL calls

## 3.3.0

### Features

- Add support for PostgreSQL Publication
- Add support for role attributes in UserRole objects

## 3.2.0

### Features

- Add support for type ownership recover in database management

### Bugs

- Remove duplicated metadata in leader election role in Helm chart

## 3.1.0

### Features

- Add support for grant role with admin option if asked
- Add public schema by default in PostgreSQLDatabase objects if nothing is set
- Add support for replica urls (with bouncer supported)

### Bugs

- Ensure database owner is set correctly
- Ensure all tables under listed schema have the right owner

## 3.0.0

### Breaking change

- Do not support anymore postgresql user. Switch to postgresqluserrole is now mandatory

### Features

- Improve Helm chart with new features and code
- Add support for PGBouncer in PosgtreSQL Engine Configurations and PostgreSQL User Roles
- Add custom metric to count reconcile errors in a detailed manner. This is including resource name and namespace in labels where the default provided isn't

### Bugs

- Fix application port in Helm chart
- Fix unnecessary requeue

## 2.1.2

### Bugs

- Change deletion algorithm and add some security to avoid status flush
- Fix pgdb deletion not checking is pgur exists

## 2.1.1

### Bugs

- Fix to add support for args in helm chart
- Fix to avoid doing requeue on success run and prefer a full resync

## 2.1.0

### Deprecation notice
16 changes: 11 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Build the manager binary
FROM golang:1.18 as builder
FROM golang:1.20 as builder
ARG TARGETOS
ARG TARGETARCH

WORKDIR /workspace
# Copy the Go Modules manifests
@@ -10,12 +12,16 @@ COPY go.sum go.sum
RUN go mod download

# Copy the go source
COPY main.go main.go
COPY apis/ apis/
COPY controllers/ controllers/
COPY cmd/main.go cmd/main.go
COPY api/ api/
COPY internal/controller/ internal/controller/

# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager main.go
# the GOARCH has not a default value to allow the binary be built according to the host where the command
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go

# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
107 changes: 79 additions & 28 deletions Makefile
Original file line number Diff line number Diff line change
@@ -46,10 +46,14 @@ ifeq ($(USE_IMAGE_DIGESTS), true)
BUNDLE_GEN_FLAGS += --use-image-digests
endif

# Set the Operator SDK version to use. By default, what is installed on the system is used.
# This is useful for CI or a project to utilize a specific version of the operator-sdk toolkit.
OPERATOR_SDK_VERSION ?= v1.33.0

# Image URL to use all building/pushing image targets
IMG ?= easymile/postgresql-operator:latest
IMG ?= controller:latest
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.24.1
ENVTEST_K8S_VERSION = 1.27.1

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
@@ -58,8 +62,13 @@ else
GOBIN=$(shell go env GOBIN)
endif

# 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
# tools. (i.e. podman)
CONTAINER_TOOL ?= docker

# Setting SHELL to bash allows bash commands to be executed by recipes.
# This is a requirement for 'setup-envtest.sh' in the test target.
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec
@@ -88,11 +97,11 @@ help: ## Display this help.

.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./apis/..." paths="." paths="./controllers/..." output:crd:artifacts:config=config/crd/bases
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./api/..." paths="./cmd/..." paths="./internal/..." output:crd:artifacts:config=config/crd/bases

.PHONY: generate
generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./apis/..." paths="." paths="./controllers/..."
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./api/..." paths="./cmd/..." paths="./internal/..."

.PHONY: fmt
fmt: ## Run go fmt against code.
@@ -104,25 +113,45 @@ vet: ## Run go vet against code.

.PHONY: test
test: manifests generate fmt vet envtest ## Run tests.
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test ./... -covermode=count -coverprofile cover.out -timeout 1800s
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -covermode=count -coverprofile cover.out -timeout 3600s

##@ Build

.PHONY: build
build: generate fmt vet ## Build manager binary.
go build -o bin/manager main.go
build: manifests generate fmt vet ## Build manager binary.
go build -o bin/manager cmd/main.go

.PHONY: run
run: manifests generate fmt vet ## Run a controller from your host.
go run ./main.go
go run ./cmd/main.go

# If you wish built the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it.
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
.PHONY: docker-build
docker-build: ## Build docker image with the manager.
docker build -t ${IMG} .
$(CONTAINER_TOOL) build -t ${IMG} .

.PHONY: docker-push
docker-push: ## Push docker image with the manager.
docker push ${IMG}
$(CONTAINER_TOOL) push ${IMG}

# PLATFORMS defines the target platforms for the manager image be build to provide support to multiple
# architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to:
# - able to use docker buildx . More info: https://docs.docker.com/build/buildx/
# - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/
# - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=<myregistry/image:<tag>> then the export will fail)
# To properly provided solutions that supports more than one platform you should use this option.
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
.PHONY: docker-buildx
docker-buildx: ## Build and push docker image for the manager for cross-platform support
# copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile
sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
- $(CONTAINER_TOOL) buildx create --name project-v3-builder
$(CONTAINER_TOOL) buildx use project-v3-builder
- $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross .
- $(CONTAINER_TOOL) buildx rm project-v3-builder
rm Dockerfile.cross

##@ Deployment

@@ -132,20 +161,20 @@ endif

.PHONY: install
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | kubectl apply -f -
$(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f -

.PHONY: uninstall
uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
$(KUSTOMIZE) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
$(KUSTOMIZE) build config/crd | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -

.PHONY: deploy
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default | kubectl apply -f -
$(KUSTOMIZE) build config/default | $(KUBECTL) apply -f -

.PHONY: undeploy
undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
$(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f -
$(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -

##@ Build Dependencies

@@ -155,36 +184,58 @@ $(LOCALBIN):
mkdir -p $(LOCALBIN)

## Tool Binaries
KUBECTL ?= kubectl
KUSTOMIZE ?= $(LOCALBIN)/kustomize
CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen
ENVTEST ?= $(LOCALBIN)/setup-envtest

## Tool Versions
KUSTOMIZE_VERSION ?= v3.8.7
CONTROLLER_TOOLS_VERSION ?= v0.9.0
KUSTOMIZE_VERSION ?= v5.0.1
CONTROLLER_TOOLS_VERSION ?= v0.14.0

KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
.PHONY: kustomize
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary.
kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. If wrong version is installed, it will be removed before downloading.
$(KUSTOMIZE): $(LOCALBIN)
curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN)
@if test -x $(LOCALBIN)/kustomize && ! $(LOCALBIN)/kustomize version | grep -q $(KUSTOMIZE_VERSION); then \
echo "$(LOCALBIN)/kustomize version is not expected $(KUSTOMIZE_VERSION). Removing it before installing."; \
rm -rf $(LOCALBIN)/kustomize; \
fi
test -s $(LOCALBIN)/kustomize || GOBIN=$(LOCALBIN) GO111MODULE=on go install sigs.k8s.io/kustomize/kustomize/v5@$(KUSTOMIZE_VERSION)

.PHONY: controller-gen
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary.
controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. If wrong version is installed, it will be overwritten.
$(CONTROLLER_GEN): $(LOCALBIN)
test -s $(LOCALBIN)/controller-gen && $(LOCALBIN)/controller-gen --version | grep -q $(CONTROLLER_TOOLS_VERSION) || \
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION)

.PHONY: envtest
envtest: $(ENVTEST) ## Download envtest-setup locally if necessary.
$(ENVTEST): $(LOCALBIN)
GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest

.PHONY: operator-sdk
OPERATOR_SDK ?= $(LOCALBIN)/operator-sdk
operator-sdk: ## Download operator-sdk locally if necessary.
ifeq (,$(wildcard $(OPERATOR_SDK)))
ifeq (, $(shell which operator-sdk 2>/dev/null))
@{ \
set -e ;\
mkdir -p $(dir $(OPERATOR_SDK)) ;\
OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \
curl -sSLo $(OPERATOR_SDK) https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION)/operator-sdk_$${OS}_$${ARCH} ;\
chmod +x $(OPERATOR_SDK) ;\
}
else
OPERATOR_SDK = $(shell which operator-sdk)
endif
endif

.PHONY: bundle
bundle: manifests kustomize ## Generate bundle manifests and metadata, then validate generated files.
operator-sdk generate kustomize manifests -q
bundle: manifests kustomize operator-sdk ## Generate bundle manifests and metadata, then validate generated files.
$(OPERATOR_SDK) generate kustomize manifests -q
cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
$(KUSTOMIZE) build config/manifests | operator-sdk generate bundle $(BUNDLE_GEN_FLAGS)
operator-sdk bundle validate ./bundle
$(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS)
$(OPERATOR_SDK) bundle validate ./bundle

.PHONY: bundle-build
bundle-build: ## Build the bundle image.
@@ -259,7 +310,7 @@ setup/dev-services:
.PHONY: setup/services
setup/services: down/services
@echo "Setup services"
docker run -d --rm --name postgres -p 5432:5432 -e POSTGRES_PASSWORD=postgres -e PGDATA=/var/lib/postgresql/data/pgdata -v $(CURDIR)/.run/postgres:/var/lib/postgresql/data postgres:12
docker run -d --rm --name postgres -p 5432:5432 -p 5433:5432 -e POSTGRES_PASSWORD=postgres -e PGDATA=/var/lib/postgresql/data/pgdata -v $(CURDIR)/.run/postgres:/var/lib/postgresql/data postgres:16 postgres -c wal_level=logical

.PHONY: code/lint
code/lint: setup/dep/install
@@ -281,6 +332,6 @@ ifndef HAS_GOLANGCI_LINT
ifndef HAS_CURL
$(error You must install curl)
endif
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.51.1
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.56.2
endif

13 changes: 9 additions & 4 deletions PROJECT
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# Code generated by tool. DO NOT EDIT.
# This file is used to track the info used to scaffold your project
# and allow the plugins properly work.
# More info: https://book.kubebuilder.io/reference/project-config.html
domain: easymile.com
layout:
- go.kubebuilder.io/v3
- go.kubebuilder.io/v4
multigroup: true
plugins:
grafana.kubebuilder.io/v1-alpha: {}
manifests.sdk.operatorframework.io/v2: {}
scorecard.sdk.operatorframework.io/v2: {}
projectName: postgresql-operator
@@ -32,7 +37,7 @@ resources:
controller: true
domain: easymile.com
group: postgresql
kind: PostgresqlUser
kind: PostgresqlUserRole
path: github.com/easymile/postgresql-operator/apis/postgresql/v1alpha1
version: v1alpha1
- api:
@@ -41,7 +46,7 @@ resources:
controller: true
domain: easymile.com
group: postgresql
kind: PostgresqlUserRole
path: github.com/easymile/postgresql-operator/apis/postgresql/v1alpha1
kind: PostgresqlPublication
path: github.com/easymile/postgresql-operator/api/postgresql/v1alpha1
version: v1alpha1
version: "3"
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -31,13 +31,27 @@ Moreover, a single User can only have rights to one Database.
| --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| [PostgresqlEngineConfiguration](docs/crds/PostgresqlEngineConfiguration.md) | Represents a PostgreSQL Engine Configuration with all necessary data to connect it |
| [PostgresqlDatabase](docs/crds/PostgresqlDatabase.md) | Represents a PostgreSQL Database |
| DEPRECATED [PostgresqlUser](docs/crds/PostgresqlUser.md) | Represents a PostgreSQL User |
| [PostgresqlUserRole](docs/crds/PostgresqlUserRole.md) | Represents a PostgreSQL User Role |
| [PostgresqlPublication](docs/crds/PostgresqlPublication.md) | Represents a PostgreSQL Publication |

## How to deploy ?

### Using Helm

#### From EasyMile Helm Chart Repository

```bash
helm repo add easymile https://easymile.github.io/helm-charts/
```

And then deploy:

```bash
helm install postgresql-operator easymile/postgresql-operator
```

#### From Git

The project has a Helm 3 chart located in `deploy/helm/postgresql-operator`.

It will deploy the operator running the command:
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ limitations under the License.
package v1alpha1

import (
"github.com/easymile/postgresql-operator/apis/postgresql/common"
"github.com/easymile/postgresql-operator/api/postgresql/common"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Original file line number Diff line number Diff line change
@@ -52,13 +52,49 @@ type PostgresqlEngineConfigurationSpec struct {
DefaultDatabase string `json:"defaultDatabase,omitempty"`
// Duration between two checks for valid engine
CheckInterval string `json:"checkInterval,omitempty"`
// Allow grant admin on every created roles (group or user) for provided PGEC user in order to
// have power to administrate those roles even with a less powered "admin" user.
// Operator will create role and after grant PGEC provided user on those roles with admin option if enabled.
AllowGrantAdminOption bool `json:"allowGrantAdminOption,omitempty"`
// Wait for linked resource to be deleted
WaitLinkedResourcesDeletion bool `json:"waitLinkedResourcesDeletion,omitempty"`
// User and password secret
// +required
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
SecretName string `json:"secretName"`
// User connections used for secret generation
// That will be used to generate secret with primary server as url or
// to use the pg bouncer one.
// Note: Operator won't check those values.
// +optional
UserConnections *UserConnections `json:"userConnections"`
}

type UserConnections struct {
// Primary connection is referring to the primary node connection.
// +optional
PrimaryConnection *GenericUserConnection `json:"primaryConnection,omitempty"`
// Bouncer connection is referring to a pg bouncer node.
// +optional
BouncerConnection *GenericUserConnection `json:"bouncerConnection,omitempty"`
// Replica connections are referring to the replica nodes.
// +optional
ReplicaConnections []*GenericUserConnection `json:"replicaConnections,omitempty"`
// Replica Bouncer connections are referring to pg bouncer nodes.
// +optional
ReplicaBouncerConnections []*GenericUserConnection `json:"replicaBouncerConnections,omitempty"`
}

type GenericUserConnection struct {
// Hostname
// +required
// +kubebuilder:validation:Required
Host string `json:"host"`
// URI args like sslmode, ...
URIArgs string `json:"uriArgs"`
// Port
Port int `json:"port,omitempty"`
}

type EngineStatusPhase string
149 changes: 149 additions & 0 deletions api/postgresql/v1alpha1/postgresqlpublication_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1alpha1

import (
"github.com/easymile/postgresql-operator/api/postgresql/common"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

// PostgresqlPublicationSpec defines the desired state of PostgresqlPublication.
type PostgresqlPublicationSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file

// Postgresql Database
// +required
// +kubebuilder:validation:Required
Database *common.CRLink `json:"database"`
// Postgresql Publication name
// +required
// +kubebuilder:validation:Required
Name string `json:"name"`
// Postgresql replication slot name
// Default value will the publication name
// +optional
ReplicationSlotName string `json:"replicationSlotName,omitempty"`
// Postgresql replication slot plugin
// Default value will be "pgoutput"
// +optional
ReplicationSlotPlugin string `json:"replicationSlotPlugin,omitempty"`
// Should drop database on Custom Resource deletion ?
// +optional
DropOnDelete bool `json:"dropOnDelete,omitempty"`
// Publication for all tables
// Note: This is mutually exclusive with "tablesInSchema" & "tables"
// +optional
AllTables bool `json:"allTables,omitempty"`
// Publication for tables in schema
// Note: This is a list of schema
// +optional
TablesInSchema []string `json:"tablesInSchema,omitempty"`
// Publication for selected tables
// +optional
Tables []*PostgresqlPublicationTable `json:"tables,omitempty"`
// Publication with parameters
// +optional
WithParameters *PostgresqlPublicationWith `json:"withParameters,omitempty"`
}

type PostgresqlPublicationTable struct {
// Table name to use for publication
TableName string `json:"tableName"`
// Columns to export
Columns *[]string `json:"columns,omitempty"`
// Additional WHERE for table
AdditionalWhere *string `json:"additionalWhere,omitempty"`
}

type PostgresqlPublicationWith struct {
// Publish param
// See here: https://www.postgresql.org/docs/current/sql-createpublication.html#SQL-CREATEPUBLICATION-PARAMS-WITH-PUBLISH
Publish string `json:"publish"`
// Publish via partition root param
// See here: https://www.postgresql.org/docs/current/sql-createpublication.html#SQL-CREATEPUBLICATION-PARAMS-WITH-PUBLISH
PublishViaPartitionRoot *bool `json:"publishViaPartitionRoot,omitempty"`
}

type PublicationStatusPhase string

const PublicationNoPhase PublicationStatusPhase = ""
const PublicationFailedPhase PublicationStatusPhase = "Failed"
const PublicationCreatedPhase PublicationStatusPhase = "Created"

// PostgresqlPublicationStatus defines the observed state of PostgresqlPublication.
type PostgresqlPublicationStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file

// Current phase of the operator
Phase PublicationStatusPhase `json:"phase"`
// Human-readable message indicating details about current operator phase or error.
// +optional
Message string `json:"message"`
// True if all resources are in a ready state and all work is done.
// +optional
Ready bool `json:"ready"`
// Created publication name
// +optional
Name string `json:"name,omitempty"`
// Created replication slot name
// +optional
ReplicationSlotName string `json:"replicationSlotName,omitempty"`
// Created replication slot plugin
// +optional
ReplicationSlotPlugin string `json:"replicationSlotPlugin,omitempty"`
// Marker for save
// +optional
AllTables *bool `json:"allTables,omitempty"`
// Resource Spec hash
// +optional
Hash string `json:"hash,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:path=postgresqlpublications,scope=Namespaced,shortName=pgpublication;pgpub
//+kubebuilder:printcolumn:name="Publication",type=string,description="Publication",JSONPath=".status.name"
//+kubebuilder:printcolumn:name="Replication slot name",type=string,description="Status phase",JSONPath=".status.replicationSlotName"
//+kubebuilder:printcolumn:name="Replication slot plugin",type=string,description="Status phase",JSONPath=".status.replicationSlotPlugin"
//+kubebuilder:printcolumn:name="Phase",type=string,description="Status phase",JSONPath=".status.phase"

// PostgresqlPublication is the Schema for the postgresqlpublications API.
type PostgresqlPublication struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec PostgresqlPublicationSpec `json:"spec,omitempty"`
Status PostgresqlPublicationStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

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

func init() {
SchemeBuilder.Register(&PostgresqlPublication{}, &PostgresqlPublicationList{})
}
Original file line number Diff line number Diff line change
@@ -17,14 +17,31 @@ limitations under the License.
package v1alpha1

import (
"github.com/easymile/postgresql-operator/apis/postgresql/common"
"github.com/easymile/postgresql-operator/api/postgresql/common"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

type PrivilegesSpecEnum string

const OwnerPrivilege PrivilegesSpecEnum = "OWNER"
const ReaderPrivilege PrivilegesSpecEnum = "READER"
const WriterPrivilege PrivilegesSpecEnum = "WRITER"

type ConnectionTypesSpecEnum string

const PrimaryConnectionType ConnectionTypesSpecEnum = "PRIMARY"
const BouncerConnectionType ConnectionTypesSpecEnum = "BOUNCER"

type PostgresqlUserRolePrivilege struct {
// User Connection type.
// This is referring to the user connection type needed for this user.
// +optional
// +kubebuilder:default=PRIMARY
// +kubebuilder:validation:Enum=PRIMARY;BOUNCER
ConnectionType ConnectionTypesSpecEnum `json:"connectionType,omitempty"`
// User privileges
// +required
// +kubebuilder:validation:Required
@@ -39,6 +56,21 @@ type PostgresqlUserRolePrivilege struct {
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinLength=1
GeneratedSecretName string `json:"generatedSecretName"`
// Extra connection URL Parameters
ExtraConnectionURLParameters map[string]string `json:"extraConnectionUrlParameters,omitempty"`
}

type PostgresqlUserRoleAttributes struct {
// REPLICATION attribute
// Note: This can be either true, false or null (to ignore this parameter)
Replication *bool `json:"replication,omitempty"`
// BYPASSRLS attribute
// Note: This can be either true, false or null (to ignore this parameter)
BypassRLS *bool `json:"bypassRLS,omitempty"` //nolint:tagliatelle
// CONNECTION LIMIT connlimit attribute
// Note: This can be either -1, a number or null (to ignore this parameter)
// Note: Increase your number by one because operator is using the created user to perform some operations.
ConnectionLimit *int `json:"connectionLimit,omitempty"`
}

type ModeEnum string
@@ -73,6 +105,10 @@ type PostgresqlUserRoleSpec struct {
// Import secret name
// +optional
ImportSecretName string `json:"importSecretName,omitempty"`
// Role attributes
// Note: Only attributes that aren't conflicting with operator are supported.
// +optional
RoleAttributes *PostgresqlUserRoleAttributes `json:"roleAttributes,omitempty"`
}

type UserRoleStatusPhase string
135 changes: 0 additions & 135 deletions apis/postgresql/v1alpha1/postgresqluser_types.go

This file was deleted.

88 changes: 71 additions & 17 deletions main.go → cmd/main.go
Original file line number Diff line number Diff line change
@@ -18,7 +18,9 @@ package main

import (
"flag"
"fmt"
"os"
"time"

// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
@@ -30,33 +32,50 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/metrics"

postgresqlv1alpha1 "github.com/easymile/postgresql-operator/apis/postgresql/v1alpha1"
postgresqlcontrollers "github.com/easymile/postgresql-operator/controllers/postgresql"
"github.com/prometheus/client_golang/prometheus"

postgresqlv1alpha1 "github.com/easymile/postgresql-operator/api/postgresql/v1alpha1"
postgresqlcontrollers "github.com/easymile/postgresql-operator/internal/controller/postgresql"
//+kubebuilder:scaffold:imports
)

var (
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
controllerRuntimeDetailedErrorTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "controller_runtime_reconcile_detailed_errors_total",
Help: "Total number of reconciliation errors per controller detailed with resource namespace and name.",
},
[]string{"controller", "namespace", "name"},
)
)

func init() {
// Register custom metrics with the global prometheus registry
metrics.Registry.MustRegister(controllerRuntimeDetailedErrorTotal)

utilruntime.Must(clientgoscheme.AddToScheme(scheme))

utilruntime.Must(postgresqlv1alpha1.AddToScheme(scheme))
//+kubebuilder:scaffold:scheme
}
} //nolint: wsl // Needed by operator

func main() {
var metricsAddr string
var metricsAddr, probeAddr, resyncPeriodStr, reconcileTimeoutStr string

var enableLeaderElection bool
var probeAddr string

flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.StringVar(&resyncPeriodStr, "resync-period", "30s", "The resync period to reload all resources for auto-heal procedures.")
flag.StringVar(&reconcileTimeoutStr, "reconcile-timeout", "5s", "The reconcile max timeout.")
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")

opts := zap.Options{
Development: false,
}
@@ -65,11 +84,29 @@ func main() {

ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))

// Parse duration
resyncPeriod, err := time.ParseDuration(resyncPeriodStr)
// Check error
if err != nil {
setupLog.Error(err, "unable to parse resync period")
os.Exit(1)
}
// Parse duration
reconcileTimeout, err := time.ParseDuration(reconcileTimeoutStr)
// Check error
if err != nil {
setupLog.Error(err, "unable to parse reconcile timeout")
os.Exit(1)
}
// Log
setupLog.Info(fmt.Sprintf("Starting manager with %s resync period", resyncPeriodStr))

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
Port: 9443, //nolint: gomnd // Because generated
HealthProbeBindAddress: probeAddr,
SyncPeriod: &resyncPeriod,
LeaderElection: enableLeaderElection,
LeaderElectionID: "07c031df.easymile.com",
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
@@ -101,10 +138,14 @@ func main() {
"controllerGroup",
"postgresql.easymile.com",
),
ControllerRuntimeDetailedErrorTotal: controllerRuntimeDetailedErrorTotal,
ControllerName: "postgresqlengineconfiguration",
ReconcileTimeout: reconcileTimeout,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "PostgresqlEngineConfiguration")
os.Exit(1)
}

if err = (&postgresqlcontrollers.PostgresqlDatabaseReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
@@ -117,40 +158,51 @@ func main() {
"controllerGroup",
"postgresql.easymile.com",
),
ControllerRuntimeDetailedErrorTotal: controllerRuntimeDetailedErrorTotal,
ControllerName: "postgresqldatabase",
ReconcileTimeout: reconcileTimeout,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "PostgresqlDatabase")
os.Exit(1)
}
if err = (&postgresqlcontrollers.PostgresqlUserReconciler{

if err = (&postgresqlcontrollers.PostgresqlUserRoleReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Recorder: mgr.GetEventRecorderFor("postgresqluser-controller"),
Recorder: mgr.GetEventRecorderFor("postgresqluserrole-controller"),
Log: ctrl.Log.WithValues(
"controller",
"postgresqluser",
"postgresqluserrole",
"controllerKind",
"PostgresqlUser",
"PostgresqlUserRole",
"controllerGroup",
"postgresql.easymile.com",
),
ControllerRuntimeDetailedErrorTotal: controllerRuntimeDetailedErrorTotal,
ControllerName: "postgresqluserrole",
ReconcileTimeout: reconcileTimeout,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "PostgresqlUser")
setupLog.Error(err, "unable to create controller", "controller", "PostgresqlUserRole")
os.Exit(1)
}
if err = (&postgresqlcontrollers.PostgresqlUserRoleReconciler{

if err = (&postgresqlcontrollers.PostgresqlPublicationReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Recorder: mgr.GetEventRecorderFor("postgresqluserrole-controller"),
Recorder: mgr.GetEventRecorderFor("postgresqlpublication-controller"),
Log: ctrl.Log.WithValues(
"controller",
"postgresqluserrole",
"postgresqlpublication",
"controllerKind",
"PostgresqlUser",
"PostgresqlPublication",
"controllerGroup",
"postgresql.easymile.com",
),
ControllerRuntimeDetailedErrorTotal: controllerRuntimeDetailedErrorTotal,
ControllerName: "postgresqlpublication",
ReconcileTimeout: reconcileTimeout,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "PostgresqlUserRole")
setupLog.Error(err, "unable to create controller", "controller", "PostgresqlPublication")
os.Exit(1)
}
//+kubebuilder:scaffold:builder
@@ -159,12 +211,14 @@ func main() {
setupLog.Error(err, "unable to set up health check")
os.Exit(1)
}

if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up ready check")
os.Exit(1)
}

setupLog.Info("starting manager")

if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
23 changes: 14 additions & 9 deletions config/crd/bases/postgresql.easymile.com_postgresqldatabases.yaml
Original file line number Diff line number Diff line change
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.0
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: postgresqldatabases.postgresql.easymile.com
spec:
group: postgresql.easymile.com
@@ -44,14 +43,19 @@ spec:
API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -94,7 +98,8 @@ spec:
x-kubernetes-list-type: set
type: object
masterRole:
description: Master role name will be used to create top group role.
description: |-
Master role name will be used to create top group role.
Database owner and users will be in this group role.
type: string
schemas:
Original file line number Diff line number Diff line change
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.0
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: postgresqlengineconfigurations.postgresql.easymile.com
spec:
group: postgresql.easymile.com
@@ -37,21 +36,32 @@ spec:
API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: PostgresqlEngineConfigurationSpec defines the desired state
of PostgresqlEngineConfiguration.
properties:
allowGrantAdminOption:
description: |-
Allow grant admin on every created roles (group or user) for provided PGEC user in order to
have power to administrate those roles even with a less powered "admin" user.
Operator will create role and after grant PGEC provided user on those roles with admin option if enabled.
type: boolean
checkInterval:
description: Duration between two checks for valid engine
type: string
@@ -79,6 +89,85 @@ spec:
uriArgs:
description: URI args like sslmode, ...
type: string
userConnections:
description: |-
User connections used for secret generation
That will be used to generate secret with primary server as url or
to use the pg bouncer one.
Note: Operator won't check those values.
properties:
bouncerConnection:
description: Bouncer connection is referring to a pg bouncer node.
properties:
host:
description: Hostname
type: string
port:
description: Port
type: integer
uriArgs:
description: URI args like sslmode, ...
type: string
required:
- host
- uriArgs
type: object
primaryConnection:
description: Primary connection is referring to the primary node
connection.
properties:
host:
description: Hostname
type: string
port:
description: Port
type: integer
uriArgs:
description: URI args like sslmode, ...
type: string
required:
- host
- uriArgs
type: object
replicaBouncerConnections:
description: Replica Bouncer connections are referring to pg bouncer
nodes.
items:
properties:
host:
description: Hostname
type: string
port:
description: Port
type: integer
uriArgs:
description: URI args like sslmode, ...
type: string
required:
- host
- uriArgs
type: object
type: array
replicaConnections:
description: Replica connections are referring to the replica
nodes.
items:
properties:
host:
description: Hostname
type: string
port:
description: Port
type: integer
uriArgs:
description: URI args like sslmode, ...
type: string
required:
- host
- uriArgs
type: object
type: array
type: object
waitLinkedResourcesDeletion:
description: Wait for linked resource to be deleted
type: boolean
179 changes: 179 additions & 0 deletions config/crd/bases/postgresql.easymile.com_postgresqlpublications.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.14.0
name: postgresqlpublications.postgresql.easymile.com
spec:
group: postgresql.easymile.com
names:
kind: PostgresqlPublication
listKind: PostgresqlPublicationList
plural: postgresqlpublications
shortNames:
- pgpublication
- pgpub
singular: postgresqlpublication
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Publication
jsonPath: .status.name
name: Publication
type: string
- description: Status phase
jsonPath: .status.replicationSlotName
name: Replication slot name
type: string
- description: Status phase
jsonPath: .status.replicationSlotPlugin
name: Replication slot plugin
type: string
- description: Status phase
jsonPath: .status.phase
name: Phase
type: string
name: v1alpha1
schema:
openAPIV3Schema:
description: PostgresqlPublication is the Schema for the postgresqlpublications
API.
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: PostgresqlPublicationSpec defines the desired state of PostgresqlPublication.
properties:
allTables:
description: |-
Publication for all tables
Note: This is mutually exclusive with "tablesInSchema" & "tables"
type: boolean
database:
description: Postgresql Database
properties:
name:
description: Custom resource name
type: string
namespace:
description: Custom resource namespace
type: string
required:
- name
type: object
dropOnDelete:
description: Should drop database on Custom Resource deletion ?
type: boolean
name:
description: Postgresql Publication name
type: string
replicationSlotName:
description: |-
Postgresql replication slot name
Default value will the publication name
type: string
replicationSlotPlugin:
description: |-
Postgresql replication slot plugin
Default value will be "pgoutput"
type: string
tables:
description: Publication for selected tables
items:
properties:
additionalWhere:
description: Additional WHERE for table
type: string
columns:
description: Columns to export
items:
type: string
type: array
tableName:
description: Table name to use for publication
type: string
required:
- tableName
type: object
type: array
tablesInSchema:
description: |-
Publication for tables in schema
Note: This is a list of schema
items:
type: string
type: array
withParameters:
description: Publication with parameters
properties:
publish:
description: |-
Publish param
See here: https://www.postgresql.org/docs/current/sql-createpublication.html#SQL-CREATEPUBLICATION-PARAMS-WITH-PUBLISH
type: string
publishViaPartitionRoot:
description: |-
Publish via partition root param
See here: https://www.postgresql.org/docs/current/sql-createpublication.html#SQL-CREATEPUBLICATION-PARAMS-WITH-PUBLISH
type: boolean
required:
- publish
type: object
required:
- database
- name
type: object
status:
description: PostgresqlPublicationStatus defines the observed state of
PostgresqlPublication.
properties:
allTables:
description: Marker for save
type: boolean
hash:
description: Resource Spec hash
type: string
message:
description: Human-readable message indicating details about current
operator phase or error.
type: string
name:
description: Created publication name
type: string
phase:
description: Current phase of the operator
type: string
ready:
description: True if all resources are in a ready state and all work
is done.
type: boolean
replicationSlotName:
description: Created replication slot name
type: string
replicationSlotPlugin:
description: Created replication slot plugin
type: string
required:
- phase
type: object
type: object
served: true
storage: true
subresources:
status: {}
56 changes: 48 additions & 8 deletions config/crd/bases/postgresql.easymile.com_postgresqluserroles.yaml
Original file line number Diff line number Diff line change
@@ -3,8 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.0
creationTimestamp: null
controller-gen.kubebuilder.io/version: v0.14.0
name: postgresqluserroles.postgresql.easymile.com
spec:
group: postgresql.easymile.com
@@ -41,14 +40,19 @@ spec:
API.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
@@ -68,6 +72,15 @@ spec:
description: Privileges
items:
properties:
connectionType:
default: PRIMARY
description: |-
User Connection type.
This is referring to the user connection type needed for this user.
enum:
- PRIMARY
- BOUNCER
type: string
database:
description: Postgresql Database
properties:
@@ -80,6 +93,11 @@ spec:
required:
- name
type: object
extraConnectionUrlParameters:
additionalProperties:
type: string
description: Extra connection URL Parameters
type: object
generatedSecretName:
description: Generated secret name prefix
minLength: 1
@@ -97,6 +115,28 @@ spec:
- privilege
type: object
type: array
roleAttributes:
description: |-
Role attributes
Note: Only attributes that aren't conflicting with operator are supported.
properties:
bypassRLS:
description: |-
BYPASSRLS attribute
Note: This can be either true, false or null (to ignore this parameter)
type: boolean
connectionLimit:
description: |-
CONNECTION LIMIT connlimit attribute
Note: This can be either -1, a number or null (to ignore this parameter)
Note: Increase your number by one because operator is using the created user to perform some operations.
type: integer
replication:
description: |-
REPLICATION attribute
Note: This can be either true, false or null (to ignore this parameter)
type: boolean
type: object
rolePrefix:
description: User role prefix
type: string
140 changes: 0 additions & 140 deletions config/crd/bases/postgresql.easymile.com_postgresqlusers.yaml

This file was deleted.

14 changes: 7 additions & 7 deletions config/crd/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -2,29 +2,29 @@
# since it depends on service name and namespace that are out of this kustomize package.
# It should be run by config/default
resources:
- bases/postgresql.easymile.com_postgresqlengineconfigurations.yaml
- bases/postgresql.easymile.com_postgresqldatabases.yaml
- bases/postgresql.easymile.com_postgresqlusers.yaml
- bases/postgresql.easymile.com_postgresqluserroles.yaml
- bases/postgresql.easymile.com_postgresqlengineconfigurations.yaml
- bases/postgresql.easymile.com_postgresqldatabases.yaml
- bases/postgresql.easymile.com_postgresqluserroles.yaml
- bases/postgresql.easymile.com_postgresqlpublications.yaml
#+kubebuilder:scaffold:crdkustomizeresource

patchesStrategicMerge:
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
# patches here are for enabling the conversion webhook for each CRD
#- patches/webhook_in_postgresqlengineconfigurations.yaml
#- patches/webhook_in_postgresqldatabases.yaml
#- patches/webhook_in_postgresqlusers.yaml
#- patches/webhook_in_postgresqluserroles.yaml
#- path: patches/webhook_in_postgresqlpublications.yaml
#+kubebuilder:scaffold:crdkustomizewebhookpatch

# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD
#- patches/cainjection_in_postgresqlengineconfigurations.yaml
#- patches/cainjection_in_postgresqldatabases.yaml
#- patches/cainjection_in_postgresqlusers.yaml
#- patches/cainjection_in_postgresqluserroles.yaml
#- path: patches/cainjection_in_postgresqlpublications.yaml
#+kubebuilder:scaffold:crdkustomizecainjectionpatch

# the following config is for teaching kustomize how to do kustomization for CRDs.
configurations:
- kustomizeconfig.yaml
- kustomizeconfig.yaml
Original file line number Diff line number Diff line change
@@ -3,5 +3,5 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
name: postgresqlusers.postgresql.easymile.com
cert-manager.io/inject-ca-from: CERTIFICATE_NAMESPACE/CERTIFICATE_NAME
name: postgresqlpublications.postgresql.easymile.com
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: postgresqlusers.postgresql.easymile.com
name: postgresqlpublications.postgresql.easymile.com
spec:
conversion:
strategy: Webhook
138 changes: 104 additions & 34 deletions config/default/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -9,10 +9,12 @@ namespace: postgresql-operator-system
namePrefix: postgresql-operator-

# Labels to add to all resources and selectors.
#commonLabels:
# someName: someValue
#labels:
#- includeSelectors: true
# pairs:
# someName: someValue

bases:
resources:
- ../crd
- ../rbac
- ../manager
@@ -30,9 +32,7 @@ patchesStrategicMerge:
# endpoint w/o any authn/z, please comment the following line.
- manager_auth_proxy_patch.yaml

# Mount the controller config file for loading manager configurations
# through a ComponentConfig type
#- manager_config_patch.yaml


# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in
# crd/kustomization.yaml
@@ -43,32 +43,102 @@ patchesStrategicMerge:
# 'CERTMANAGER' needs to be enabled to use ca injection
#- webhookcainjection_patch.yaml

# the following config is for teaching kustomize how to do var substitution
vars:
# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix.
#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR
# objref:
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # this name should match the one in certificate.yaml
# fieldref:
# fieldpath: metadata.namespace
#- name: CERTIFICATE_NAME
# objref:
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # this name should match the one in certificate.yaml
#- name: SERVICE_NAMESPACE # namespace of the service
# objref:
# kind: Service
# version: v1
# name: webhook-service
# fieldref:
# fieldpath: metadata.namespace
#- name: SERVICE_NAME
# objref:
# kind: Service
# version: v1
# name: webhook-service
# Uncomment the following replacements to add the cert-manager CA injection annotations
#replacements:
# - source: # Add cert-manager annotation to ValidatingWebhookConfiguration, MutatingWebhookConfiguration and CRDs
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # this name should match the one in certificate.yaml
# fieldPath: .metadata.namespace # namespace of the certificate CR
# targets:
# - select:
# kind: ValidatingWebhookConfiguration
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 0
# create: true
# - select:
# kind: MutatingWebhookConfiguration
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 0
# create: true
# - select:
# kind: CustomResourceDefinition
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 0
# create: true
# - source:
# kind: Certificate
# group: cert-manager.io
# version: v1
# name: serving-cert # this name should match the one in certificate.yaml
# fieldPath: .metadata.name
# targets:
# - select:
# kind: ValidatingWebhookConfiguration
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 1
# create: true
# - select:
# kind: MutatingWebhookConfiguration
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 1
# create: true
# - select:
# kind: CustomResourceDefinition
# fieldPaths:
# - .metadata.annotations.[cert-manager.io/inject-ca-from]
# options:
# delimiter: '/'
# index: 1
# create: true
# - source: # Add cert-manager annotation to the webhook Service
# kind: Service
# version: v1
# name: webhook-service
# fieldPath: .metadata.name # namespace of the service
# targets:
# - select:
# kind: Certificate
# group: cert-manager.io
# version: v1
# fieldPaths:
# - .spec.dnsNames.0
# - .spec.dnsNames.1
# options:
# delimiter: '.'
# index: 0
# create: true
# - source:
# kind: Service
# version: v1
# name: webhook-service
# fieldPath: .metadata.namespace # namespace of the service
# targets:
# - select:
# kind: Certificate
# group: cert-manager.io
# version: v1
# fieldPaths:
# - .spec.dnsNames.0
# - .spec.dnsNames.1
# options:
# delimiter: '.'
# index: 1
# create: true
9 changes: 4 additions & 5 deletions config/default/manager_auth_proxy_patch.yaml
Original file line number Diff line number Diff line change
@@ -12,11 +12,10 @@ spec:
- name: kube-rbac-proxy
securityContext:
allowPrivilegeEscalation: false
# TODO(user): uncomment for common cases that do not require escalating privileges
# capabilities:
# drop:
# - "ALL"
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.11.0
capabilities:
drop:
- "ALL"
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.14.1
args:
- "--secure-listen-address=0.0.0.0:8443"
- "--upstream=http://127.0.0.1:8080/"
10 changes: 0 additions & 10 deletions config/default/manager_config_patch.yaml
Original file line number Diff line number Diff line change
@@ -8,13 +8,3 @@ spec:
spec:
containers:
- name: manager
args:
- "--config=controller_manager_config.yaml"
volumeMounts:
- name: manager-config
mountPath: /controller_manager_config.yaml
subPath: controller_manager_config.yaml
volumes:
- name: manager-config
configMap:
name: manager-config
21 changes: 0 additions & 21 deletions config/manager/controller_manager_config.yaml

This file was deleted.

8 changes: 0 additions & 8 deletions config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
resources:
- manager.yaml

generatorOptions:
disableNameSuffixHash: true

configMapGenerator:
- name: manager-config
files:
- controller_manager_config.yaml
39 changes: 35 additions & 4 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
@@ -3,6 +3,12 @@ kind: Namespace
metadata:
labels:
control-plane: controller-manager
app.kubernetes.io/name: namespace
app.kubernetes.io/instance: system
app.kubernetes.io/component: manager
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
name: system
---
apiVersion: apps/v1
@@ -12,6 +18,12 @@ metadata:
namespace: system
labels:
control-plane: controller-manager
app.kubernetes.io/name: deployment
app.kubernetes.io/instance: controller-manager
app.kubernetes.io/component: manager
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
spec:
selector:
matchLabels:
@@ -24,6 +36,26 @@ spec:
labels:
control-plane: controller-manager
spec:
# TODO(user): Uncomment the following code to configure the nodeAffinity expression
# according to the platforms which are supported by your solution.
# It is considered best practice to support multiple architectures. You can
# build your manager image using the makefile target docker-buildx.
# affinity:
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: kubernetes.io/arch
# operator: In
# values:
# - amd64
# - arm64
# - ppc64le
# - s390x
# - key: kubernetes.io/os
# operator: In
# values:
# - linux
securityContext:
runAsNonRoot: true
# TODO(user): For common cases that do not require escalating privileges
@@ -42,10 +74,9 @@ spec:
name: manager
securityContext:
allowPrivilegeEscalation: false
# TODO(user): uncomment for common cases that do not require escalating privileges
# capabilities:
# drop:
# - "ALL"
capabilities:
drop:
- "ALL"
livenessProbe:
httpGet:
path: /healthz
3 changes: 2 additions & 1 deletion config/manifests/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -20,7 +20,8 @@ resources:
# # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs.
# # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment.
# - op: remove
# path: /spec/template/spec/containers/1/volumeMounts/0

# path: /spec/template/spec/containers/0/volumeMounts/0
# # Remove the "cert" volume, since OLM will create and mount a set of certs.
# # Update the indices in this path if adding or removing volumes in the manager's Deployment.
# - op: remove
6 changes: 6 additions & 0 deletions config/prometheus/monitor.yaml
Original file line number Diff line number Diff line change
@@ -5,6 +5,12 @@ kind: ServiceMonitor
metadata:
labels:
control-plane: controller-manager
app.kubernetes.io/name: servicemonitor
app.kubernetes.io/instance: controller-manager-metrics-monitor
app.kubernetes.io/component: metrics
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
name: controller-manager-metrics-monitor
namespace: system
spec:
7 changes: 7 additions & 0 deletions config/rbac/auth_proxy_client_clusterrole.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/name: clusterrole
app.kubernetes.io/instance: metrics-reader
app.kubernetes.io/component: kube-rbac-proxy
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
name: metrics-reader
rules:
- nonResourceURLs:
7 changes: 7 additions & 0 deletions config/rbac/auth_proxy_role.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/name: clusterrole
app.kubernetes.io/instance: proxy-role
app.kubernetes.io/component: kube-rbac-proxy
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
name: proxy-role
rules:
- apiGroups:
7 changes: 7 additions & 0 deletions config/rbac/auth_proxy_role_binding.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app.kubernetes.io/name: clusterrolebinding
app.kubernetes.io/instance: proxy-rolebinding
app.kubernetes.io/component: kube-rbac-proxy
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
name: proxy-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
6 changes: 6 additions & 0 deletions config/rbac/auth_proxy_service.yaml
Original file line number Diff line number Diff line change
@@ -3,6 +3,12 @@ kind: Service
metadata:
labels:
control-plane: controller-manager
app.kubernetes.io/name: service
app.kubernetes.io/instance: controller-manager-metrics-service
app.kubernetes.io/component: kube-rbac-proxy
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
name: controller-manager-metrics-service
namespace: system
spec:
7 changes: 7 additions & 0 deletions config/rbac/leader_election_role.yaml
Original file line number Diff line number Diff line change
@@ -2,6 +2,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app.kubernetes.io/name: role
app.kubernetes.io/instance: leader-election-role
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
name: leader-election-role
rules:
- apiGroups:
7 changes: 7 additions & 0 deletions config/rbac/leader_election_role_binding.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app.kubernetes.io/name: rolebinding
app.kubernetes.io/instance: leader-election-rolebinding
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
name: leader-election-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
31 changes: 31 additions & 0 deletions config/rbac/postgresql_postgresqlpublication_editor_role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# permissions for end users to edit postgresqlpublications.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/name: clusterrole
app.kubernetes.io/instance: postgresqlpublication-editor-role
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
name: postgresqlpublication-editor-role
rules:
- apiGroups:
- postgresql.easymile.com
resources:
- postgresqlpublications
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- postgresql.easymile.com
resources:
- postgresqlpublications/status
verbs:
- get
27 changes: 27 additions & 0 deletions config/rbac/postgresql_postgresqlpublication_viewer_role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# permissions for end users to view postgresqlpublications.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/name: clusterrole
app.kubernetes.io/instance: postgresqlpublication-viewer-role
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
name: postgresqlpublication-viewer-role
rules:
- apiGroups:
- postgresql.easymile.com
resources:
- postgresqlpublications
verbs:
- get
- list
- watch
- apiGroups:
- postgresql.easymile.com
resources:
- postgresqlpublications/status
verbs:
- get
20 changes: 13 additions & 7 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
@@ -2,9 +2,15 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: manager-role
rules:
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- ""
resources:
@@ -72,7 +78,7 @@ rules:
- apiGroups:
- postgresql.easymile.com
resources:
- postgresqluserroles
- postgresqlpublications
verbs:
- create
- delete
@@ -84,21 +90,21 @@ rules:
- apiGroups:
- postgresql.easymile.com
resources:
- postgresqluserroles/finalizers
- postgresqlpublications/finalizers
verbs:
- update
- apiGroups:
- postgresql.easymile.com
resources:
- postgresqluserroles/status
- postgresqlpublications/status
verbs:
- get
- patch
- update
- apiGroups:
- postgresql.easymile.com
resources:
- postgresqlusers
- postgresqluserroles
verbs:
- create
- delete
@@ -110,13 +116,13 @@ rules:
- apiGroups:
- postgresql.easymile.com
resources:
- postgresqlusers/finalizers
- postgresqluserroles/finalizers
verbs:
- update
- apiGroups:
- postgresql.easymile.com
resources:
- postgresqlusers/status
- postgresqluserroles/status
verbs:
- get
- patch
7 changes: 7 additions & 0 deletions config/rbac/role_binding.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app.kubernetes.io/name: clusterrolebinding
app.kubernetes.io/instance: manager-rolebinding
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
name: manager-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
7 changes: 7 additions & 0 deletions config/rbac/service_account.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/name: serviceaccount
app.kubernetes.io/instance: controller-manager-sa
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: postgresql-operator
app.kubernetes.io/part-of: postgresql-operator
app.kubernetes.io/managed-by: kustomize
name: controller-manager
namespace: system
33 changes: 33 additions & 0 deletions config/samples/engineconfiguration/full-example.yaml
Original file line number Diff line number Diff line change
@@ -22,6 +22,39 @@ spec:
# Check interval
# Default to 30s
checkInterval: 30s
# Allow grant admin on every created roles (group or user) for provided PGEC user in order to
# have power to administrate those roles even with a less powered "admin" user.
# Operator will create role and after grant PGEC provided user on those roles with admin option if enabled.
allowGrantAdminOption: true
# Wait for linked resource to be deleted
# Default to false
waitLinkedResourcesDeletion: true
# User connections used for secret generation
# That will be used to generate secret with primary server as url or
# to use the pg bouncer one.
# Note: Operator won't check those values.
userConnections:
# Primary connection is referring to the primary node connection.
# If not being set, all values will be set from spec (host, port, uriArgs)
primaryConnection:
host: localhost
uriArgs: sslmode=disable
port: 5432
# Bouncer connection is referring to a pg bouncer node.
# bouncerConnection:
# host: localhost
# uriArgs: sslmode=disable
# port: 6432
# Replica connections are referring to the replica nodes.
# replicaConnections:
# - host: localhost
# uriArgs: sslmode=disable
# port: 5433
# - host: localhost
# uriArgs: sslmode=disable
# port: 5434
# Replica Bouncer connections are referring to pg bouncer nodes.
# replicaBouncerConnections:
# - host: localhost
# uriArgs: sslmode=disable
# port: 6432
1 change: 1 addition & 0 deletions config/samples/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -5,4 +5,5 @@ resources:
- postgresql_v1alpha1_postgresqluser.yaml
- postgresql_v1alpha2_postgresqluser.yaml
- postgresql_v1alpha1_postgresqluserrole.yaml
- postgresql_v1alpha1_postgresqlpublication.yaml
#+kubebuilder:scaffold:manifestskustomizesamples
Loading