The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .flake8
├── .github
    ├── ISSUE_TEMPLATE
    │   └── postgres-operator-issue-template.md
    ├── PULL_REQUEST_TEMPLATE
    │   └── postgres-operator-pull-request-template.md
    └── workflows
    │   ├── publish_ghcr_image.yaml
    │   ├── run_e2e.yaml
    │   └── run_tests.yaml
├── .gitignore
├── .golangci.yml
├── .zappr.yaml
├── CODEOWNERS
├── CONTRIBUTING.md
├── LICENSE
├── MAINTAINERS
├── Makefile
├── README.md
├── SECURITY.md
├── build-ci.sh
├── charts
    ├── postgres-operator-ui
    │   ├── .helmignore
    │   ├── Chart.yaml
    │   ├── index.yaml
    │   ├── postgres-operator-ui-1.10.1.tgz
    │   ├── postgres-operator-ui-1.11.0.tgz
    │   ├── postgres-operator-ui-1.12.2.tgz
    │   ├── postgres-operator-ui-1.13.0.tgz
    │   ├── postgres-operator-ui-1.14.0.tgz
    │   ├── postgres-operator-ui-1.9.0.tgz
    │   ├── templates
    │   │   ├── NOTES.txt
    │   │   ├── _helpers.tpl
    │   │   ├── clusterrole.yaml
    │   │   ├── clusterrolebinding.yaml
    │   │   ├── deployment.yaml
    │   │   ├── ingress.yaml
    │   │   ├── service.yaml
    │   │   └── serviceaccount.yaml
    │   └── values.yaml
    └── postgres-operator
    │   ├── .helmignore
    │   ├── Chart.yaml
    │   ├── crds
    │       ├── operatorconfigurations.yaml
    │       ├── postgresqls.yaml
    │       └── postgresteams.yaml
    │   ├── index.yaml
    │   ├── postgres-operator-1.10.1.tgz
    │   ├── postgres-operator-1.11.0.tgz
    │   ├── postgres-operator-1.12.2.tgz
    │   ├── postgres-operator-1.13.0.tgz
    │   ├── postgres-operator-1.14.0.tgz
    │   ├── postgres-operator-1.9.0.tgz
    │   ├── templates
    │       ├── NOTES.txt
    │       ├── _helpers.tpl
    │       ├── clusterrole-postgres-pod.yaml
    │       ├── clusterrole.yaml
    │       ├── clusterrolebinding.yaml
    │       ├── configmap.yaml
    │       ├── deployment.yaml
    │       ├── operatorconfiguration.yaml
    │       ├── postgres-pod-priority-class.yaml
    │       ├── service.yaml
    │       ├── serviceaccount.yaml
    │       └── user-facing-clusterroles.yaml
    │   └── values.yaml
├── cmd
    └── main.go
├── delivery.yaml
├── docker
    ├── DebugDockerfile
    ├── Dockerfile
    └── build_operator.sh
├── docs
    ├── administrator.md
    ├── developer.md
    ├── diagrams
    │   ├── Makefile
    │   ├── logo.png
    │   ├── neutral_operator.excalidraw
    │   ├── neutral_operator.png
    │   ├── neutral_operator_dark.png
    │   ├── neutral_operator_light.png
    │   ├── operator.png
    │   ├── operator.tex
    │   ├── pgui-cluster-list.png
    │   ├── pgui-cluster-startup.png
    │   ├── pgui-delete-cluster.png
    │   ├── pgui-finished-setup.png
    │   ├── pgui-new-cluster.png
    │   ├── pgui-operator-logs.png
    │   ├── pgui-waiting-for-master.png
    │   ├── pod.png
    │   └── pod.tex
    ├── index.md
    ├── operator-ui.md
    ├── quickstart.md
    ├── reference
    │   ├── cluster_manifest.md
    │   ├── command_line_and_environment.md
    │   └── operator_parameters.md
    └── user.md
├── e2e
    ├── Dockerfile
    ├── Makefile
    ├── README.md
    ├── exec.sh
    ├── exec_into_env.sh
    ├── kind-cluster-postgres-operator-e2e-tests.yaml
    ├── requirements.txt
    ├── run.sh
    ├── scripts
    │   ├── cleanup.sh
    │   ├── get_logs.sh
    │   └── watch_objects.sh
    └── tests
    │   ├── __init__.py
    │   ├── k8s_api.py
    │   └── test_e2e.py
├── go.mod
├── go.sum
├── hack
    ├── custom-boilerplate.go.txt
    ├── tools.go
    ├── update-codegen.sh
    └── verify-codegen.sh
├── kubectl-pg
    ├── README.md
    ├── build.sh
    ├── cmd
    │   ├── addDb.go
    │   ├── addUser.go
    │   ├── check.go
    │   ├── connect.go
    │   ├── create.go
    │   ├── delete.go
    │   ├── extVolume.go
    │   ├── list.go
    │   ├── logs.go
    │   ├── root.go
    │   ├── scale.go
    │   ├── update.go
    │   ├── util.go
    │   └── version.go
    ├── go.mod
    ├── go.sum
    └── main.go
├── logical-backup
    ├── Dockerfile
    └── dump.sh
├── manifests
    ├── api-service.yaml
    ├── complete-postgres-manifest.yaml
    ├── configmap.yaml
    ├── custom-team-membership.yaml
    ├── e2e-storage-class.yaml
    ├── fake-teams-api.yaml
    ├── fes.crd.yaml
    ├── infrastructure-roles-configmap.yaml
    ├── infrastructure-roles-new.yaml
    ├── infrastructure-roles.yaml
    ├── kustomization.yaml
    ├── minimal-fake-pooler-deployment.yaml
    ├── minimal-master-replica-svcmonitor.yaml
    ├── minimal-postgres-lowest-version-manifest.yaml
    ├── minimal-postgres-manifest.yaml
    ├── operator-service-account-rbac-openshift.yaml
    ├── operator-service-account-rbac.yaml
    ├── operatorconfiguration.crd.yaml
    ├── platform-credentials.yaml
    ├── postgres-operator.yaml
    ├── postgres-pod-priority-class.yaml
    ├── postgresql-operator-default-configuration.yaml
    ├── postgresql.crd.yaml
    ├── postgresteam.crd.yaml
    ├── standby-manifest.yaml
    └── user-facing-clusterroles.yaml
├── mkdocs.yml
├── mocks
    └── mocks.go
├── pkg
    ├── apis
    │   ├── acid.zalan.do
    │   │   ├── register.go
    │   │   └── v1
    │   │   │   ├── const.go
    │   │   │   ├── crds.go
    │   │   │   ├── doc.go
    │   │   │   ├── marshal.go
    │   │   │   ├── operator_configuration_type.go
    │   │   │   ├── postgres_team_type.go
    │   │   │   ├── postgresql_type.go
    │   │   │   ├── register.go
    │   │   │   ├── util.go
    │   │   │   ├── util_test.go
    │   │   │   └── zz_generated.deepcopy.go
    │   └── zalando.org
    │   │   ├── register.go
    │   │   └── v1
    │   │       ├── fabriceventstream.go
    │   │       ├── register.go
    │   │       └── zz_generated.deepcopy.go
    ├── apiserver
    │   ├── apiserver.go
    │   └── apiserver_test.go
    ├── cluster
    │   ├── cluster.go
    │   ├── cluster_test.go
    │   ├── connection_pooler.go
    │   ├── connection_pooler_new_test.go
    │   ├── connection_pooler_test.go
    │   ├── database.go
    │   ├── exec.go
    │   ├── filesystems.go
    │   ├── k8sres.go
    │   ├── k8sres_test.go
    │   ├── majorversionupgrade.go
    │   ├── pod.go
    │   ├── pod_test.go
    │   ├── resources.go
    │   ├── streams.go
    │   ├── streams_test.go
    │   ├── sync.go
    │   ├── sync_test.go
    │   ├── types.go
    │   ├── util.go
    │   ├── util_test.go
    │   ├── volumes.go
    │   └── volumes_test.go
    ├── controller
    │   ├── controller.go
    │   ├── logs_and_api.go
    │   ├── node.go
    │   ├── node_test.go
    │   ├── operator_config.go
    │   ├── pod.go
    │   ├── postgresql.go
    │   ├── postgresql_test.go
    │   ├── types.go
    │   ├── util.go
    │   └── util_test.go
    ├── generated
    │   ├── clientset
    │   │   └── versioned
    │   │   │   ├── clientset.go
    │   │   │   ├── doc.go
    │   │   │   ├── fake
    │   │   │       ├── clientset_generated.go
    │   │   │       ├── doc.go
    │   │   │       └── register.go
    │   │   │   ├── scheme
    │   │   │       ├── doc.go
    │   │   │       └── register.go
    │   │   │   └── typed
    │   │   │       ├── acid.zalan.do
    │   │   │           └── v1
    │   │   │           │   ├── acid.zalan.do_client.go
    │   │   │           │   ├── doc.go
    │   │   │           │   ├── fake
    │   │   │           │       ├── doc.go
    │   │   │           │       ├── fake_acid.zalan.do_client.go
    │   │   │           │       ├── fake_operatorconfiguration.go
    │   │   │           │       ├── fake_postgresql.go
    │   │   │           │       └── fake_postgresteam.go
    │   │   │           │   ├── generated_expansion.go
    │   │   │           │   ├── operatorconfiguration.go
    │   │   │           │   ├── postgresql.go
    │   │   │           │   └── postgresteam.go
    │   │   │       └── zalando.org
    │   │   │           └── v1
    │   │   │               ├── doc.go
    │   │   │               ├── fabriceventstream.go
    │   │   │               ├── fake
    │   │   │                   ├── doc.go
    │   │   │                   ├── fake_fabriceventstream.go
    │   │   │                   └── fake_zalando.org_client.go
    │   │   │               ├── generated_expansion.go
    │   │   │               └── zalando.org_client.go
    │   ├── informers
    │   │   └── externalversions
    │   │   │   ├── acid.zalan.do
    │   │   │       ├── interface.go
    │   │   │       └── v1
    │   │   │       │   ├── interface.go
    │   │   │       │   ├── postgresql.go
    │   │   │       │   └── postgresteam.go
    │   │   │   ├── factory.go
    │   │   │   ├── generic.go
    │   │   │   ├── internalinterfaces
    │   │   │       └── factory_interfaces.go
    │   │   │   └── zalando.org
    │   │   │       ├── interface.go
    │   │   │       └── v1
    │   │   │           ├── fabriceventstream.go
    │   │   │           └── interface.go
    │   └── listers
    │   │   ├── acid.zalan.do
    │   │       └── v1
    │   │       │   ├── expansion_generated.go
    │   │       │   ├── postgresql.go
    │   │       │   └── postgresteam.go
    │   │   └── zalando.org
    │   │       └── v1
    │   │           ├── expansion_generated.go
    │   │           └── fabriceventstream.go
    ├── spec
    │   ├── types.go
    │   └── types_test.go
    ├── teams
    │   ├── postgres_team.go
    │   └── postgres_team_test.go
    └── util
    │   ├── config
    │       ├── config.go
    │       ├── config_test.go
    │       └── util.go
    │   ├── constants
    │       ├── annotations.go
    │       ├── aws.go
    │       ├── kubernetes.go
    │       ├── pooler.go
    │       ├── postgresql.go
    │       ├── roles.go
    │       ├── streams.go
    │       └── units.go
    │   ├── filesystems
    │       ├── ext234.go
    │       └── filesystems.go
    │   ├── httpclient
    │       └── httpclient.go
    │   ├── k8sutil
    │       └── k8sutil.go
    │   ├── nicediff
    │       └── diff.go
    │   ├── patroni
    │       ├── patroni.go
    │       └── patroni_test.go
    │   ├── retryutil
    │       ├── retry_util.go
    │       └── retry_util_test.go
    │   ├── ringlog
    │       └── ringlog.go
    │   ├── teams
    │       ├── teams.go
    │       └── teams_test.go
    │   ├── users
    │       └── users.go
    │   ├── util.go
    │   ├── util_test.go
    │   └── volumes
    │       ├── ebs.go
    │       ├── ebs_test.go
    │       ├── volumes.go
    │       └── volumes_test.go
├── run_operator_locally.sh
└── ui
    ├── .dockerignore
    ├── Dockerfile
    ├── MANIFEST.in
    ├── Makefile
    ├── app
        ├── .eslintignore
        ├── .eslintrc.yml
        ├── README.rst
        ├── package.json
        ├── src
        │   ├── app.js
        │   ├── app.tag.pug
        │   ├── edit.tag.pug
        │   ├── help-edit.tag.pug
        │   ├── help-general.tag.pug
        │   ├── logs.tag.pug
        │   ├── new.tag.pug
        │   ├── postgresql.tag.pug
        │   ├── postgresqls.tag.pug
        │   ├── prism.js
        │   ├── restore.tag.pug
        │   └── status.tag.pug
        └── webpack.config.js
    ├── manifests
        ├── deployment.yaml
        ├── ingress.yaml
        ├── kustomization.yaml
        ├── service.yaml
        └── ui-service-account-rbac.yaml
    ├── operator_ui
        ├── __init__.py
        ├── __main__.py
        ├── adapters
        │   ├── __init__.py
        │   └── logger.py
        ├── backoff.py
        ├── cluster_discovery.py
        ├── main.py
        ├── mock.py
        ├── spiloutils.py
        ├── static
        │   ├── favicon-96x96.png
        │   ├── prism.css
        │   ├── prism.js
        │   └── styles.css
        ├── templates
        │   └── index.html
        ├── update.py
        └── utils.py
    ├── requirements.txt
    ├── run_local.sh
    ├── setup.py
    ├── start_server.sh
    └── tox.ini


/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | exclude=.git,__pycache__
3 | max-line-length=120
4 | 


--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/postgres-operator-issue-template.md:
--------------------------------------------------------------------------------
 1 | ---
 2 | name: Postgres Operator issue template
 3 | about: How are you using the operator?
 4 | title: ''
 5 | labels: ''
 6 | assignees: ''
 7 | 
 8 | ---
 9 | 
10 | Please, answer some short questions which should help us to understand your problem / question better?
11 | 
12 | - **Which image of the operator are you using?** e.g. ghcr.io/zalando/postgres-operator:v1.13.0
13 | - **Where do you run it - cloud or metal? Kubernetes or OpenShift?** [AWS K8s | GCP ... | Bare Metal K8s]
14 | - **Are you running Postgres Operator in production?** [yes | no]
15 | - **Type of issue?** [Bug report, question, feature request, etc.]
16 | 
17 | Some general remarks when posting a bug report:
18 | - Please, check the operator, pod (Patroni) and postgresql logs first. When copy-pasting many log lines please do it in a separate GitHub gist together with your Postgres CRD and configuration manifest.
19 | - If you feel this issue might be more related to the [Spilo](https://github.com/zalando/spilo/issues) docker image or [Patroni](https://github.com/zalando/patroni/issues), consider opening issues in the respective repos.
20 | 


--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE/postgres-operator-pull-request-template.md:
--------------------------------------------------------------------------------
 1 | ## Problem description
 2 | 
 3 | 
 4 | 
 5 | ## Linked issues
 6 | 
 7 | 
 8 | 
 9 | ## Checklist
10 | 
11 | Thanks for submitting a pull request to the Postgres Operator project.
12 | Please, ensure your contribution matches the following items:
13 | 
14 | - [ ] Your go code is [formatted](https://blog.golang.org/gofmt). Your IDE should do it automatically for you.
15 | - [ ] You have updated [generated code](https://github.com/zalando/postgres-operator/blob/master/docs/developer.md#code-generation) when introducing new fields to the `acid.zalan.do` api package.
16 | - [ ] New [configuration options](https://github.com/zalando/postgres-operator/blob/master/docs/developer.md#introduce-additional-configuration-parameters) are reflected in CRD validation, helm charts and sample manifests.
17 | - [ ] New functionality is covered by [unit](https://github.com/zalando/postgres-operator/blob/master/docs/developer.md#unit-tests) and/or [e2e](https://github.com/zalando/postgres-operator/blob/master/docs/developer.md#end-to-end-tests) tests.
18 | - [ ] You have checked existing open PRs for possible overlay and referenced them.
19 | 


--------------------------------------------------------------------------------
/.github/workflows/publish_ghcr_image.yaml:
--------------------------------------------------------------------------------
 1 | name: Publish multiarch postgres-operator images on ghcr.io
 2 | 
 3 | env:
 4 |   REGISTRY: ghcr.io
 5 |   IMAGE_NAME: ${{ github.repository }}
 6 |   IMAGE_NAME_UI: ${{ github.repository }}-ui
 7 | 
 8 | on:
 9 |   push:
10 |     tags:
11 |       - '*'
12 | 
13 | jobs:
14 |   publish:
15 |     name: Build, test and push image
16 |     runs-on: ubuntu-latest
17 |     permissions:
18 |       contents: read
19 |       packages: write
20 |     steps:
21 |       - name: Checkout repository
22 |         uses: actions/checkout@v3
23 | 
24 |       - uses: actions/setup-go@v2
25 |         with:
26 |           go-version: "^1.23.4"
27 | 
28 |       - name: Run unit tests
29 |         run: make deps mocks test
30 | 
31 |       - name: Define image name
32 |         id: image
33 |         run: |
34 |             OPERATOR_IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${GITHUB_REF/refs\/tags\//}"
35 |             echo "OPERATOR_IMAGE=$OPERATOR_IMAGE" >> $GITHUB_OUTPUT
36 | 
37 |       - name: Define UI image name
38 |         id: image_ui
39 |         run: |
40 |             UI_IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME_UI }}:${GITHUB_REF/refs\/tags\//}"
41 |             echo "UI_IMAGE=$UI_IMAGE" >> $GITHUB_OUTPUT
42 | 
43 |       - name: Define logical backup image name
44 |         id: image_lb
45 |         run: |
46 |             BACKUP_IMAGE="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/logical-backup:${GITHUB_REF_NAME}"
47 |             echo "BACKUP_IMAGE=$BACKUP_IMAGE" >> $GITHUB_OUTPUT
48 | 
49 |       - name: Set up QEMU
50 |         uses: docker/setup-qemu-action@v2
51 | 
52 |       - name: Set up Docker Buildx
53 |         uses: docker/setup-buildx-action@v2
54 | 
55 |       - name: Login to GHCR
56 |         uses: docker/login-action@v2
57 |         with:
58 |           registry: ${{ env.REGISTRY }}
59 |           username: ${{ github.actor }}
60 |           password: ${{ secrets.GITHUB_TOKEN }}
61 | 
62 |       - name: Build and push multiarch operator image to ghcr
63 |         uses: docker/build-push-action@v3
64 |         with:
65 |           context: .
66 |           file: docker/Dockerfile
67 |           push: true
68 |           build-args: BASE_IMAGE=alpine:3
69 |           tags: "${{ steps.image.outputs.OPERATOR_IMAGE }}"
70 |           platforms: linux/amd64,linux/arm64
71 | 
72 |       - name: Build and push multiarch ui image to ghcr
73 |         uses: docker/build-push-action@v3
74 |         with:
75 |           context: ui
76 |           push: true
77 |           build-args: BASE_IMAGE=python:3.11-slim
78 |           tags: "${{ steps.image_ui.outputs.UI_IMAGE }}"
79 |           platforms: linux/amd64,linux/arm64
80 | 
81 |       - name: Build and push multiarch logical-backup image to ghcr
82 |         uses: docker/build-push-action@v3
83 |         with:
84 |           context: logical-backup
85 |           push: true
86 |           build-args: BASE_IMAGE=ubuntu:22.04
87 |           tags: "${{ steps.image_lb.outputs.BACKUP_IMAGE }}"
88 |           platforms: linux/amd64,linux/arm64
89 | 


--------------------------------------------------------------------------------
/.github/workflows/run_e2e.yaml:
--------------------------------------------------------------------------------
 1 | name: operator-e2e-tests
 2 | 
 3 | on: 
 4 |   pull_request:
 5 |   push:
 6 |     branches:
 7 |     - master
 8 | 
 9 | jobs:
10 |   tests:
11 |     name: End-2-End tests
12 |     runs-on: ubuntu-latest
13 |     steps:
14 |     - uses: actions/checkout@v1
15 |     - uses: actions/setup-go@v2
16 |       with:
17 |           go-version: "^1.23.4"
18 |     - name: Make dependencies
19 |       run: make deps mocks
20 |     - name: Code generation
21 |       run: make codegen
22 |     - name: Run unit tests
23 |       run: make test
24 |     - name: Run end-2-end tests
25 |       run: make e2e
26 | 


--------------------------------------------------------------------------------
/.github/workflows/run_tests.yaml:
--------------------------------------------------------------------------------
 1 | name: operator-tests
 2 | 
 3 | on: 
 4 |   pull_request:
 5 |   push:
 6 |     branches:
 7 |     - master
 8 | 
 9 | jobs:
10 |   tests:
11 |     name: Unit tests and coverage
12 |     runs-on: ubuntu-latest
13 |     steps:
14 |     - uses: actions/checkout@v2
15 |     - uses: actions/setup-go@v2
16 |       with:
17 |           go-version: "^1.23.4"
18 |     - name: Make dependencies
19 |       run: make deps mocks
20 |     - name: Compile
21 |       run: make linux
22 |     - name: Run unit tests
23 |       run: go test -race -covermode atomic -coverprofile=coverage.out ./...
24 |     - name: Convert coverage to lcov
25 |       uses: jandelgado/gcov2lcov-action@v1.1.1
26 |     - name: Coveralls
27 |       uses: coverallsapp/github-action@master
28 |       with:
29 |         github-token: ${{ secrets.GITHUB_TOKEN }}
30 |         path-to-lcov: coverage.lcov
31 | 


--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
  1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
  2 | *.o
  3 | *.a
  4 | *.so
  5 | 
  6 | # Folders
  7 | _obj
  8 | _test
  9 | _manifests
 10 | _tmp
 11 | github.com
 12 | 
 13 | # Architecture specific extensions/prefixes
 14 | *.[568vq]
 15 | [568vq].out
 16 | 
 17 | *.cgo1.go
 18 | *.cgo2.c
 19 | _cgo_defun.c
 20 | _cgo_gotypes.go
 21 | _cgo_export.*
 22 | 
 23 | _testmain.go
 24 | 
 25 | *.exe
 26 | *.test
 27 | *.prof
 28 | /vendor/
 29 | /kubectl-pg/vendor/
 30 | /build/
 31 | /docker/build/
 32 | /github.com/
 33 | .idea
 34 | .vscode
 35 | 
 36 | scm-source.json
 37 | 
 38 | # diagrams
 39 | *.aux
 40 | *.log
 41 | 
 42 | # Python
 43 | # Adapted from https://github.com/github/gitignore/blob/master/Python.gitignore
 44 | 
 45 | # Byte-compiled / optimized / DLL files
 46 | __pycache__/
 47 | *.py[cod]
 48 | *$py.class
 49 | 
 50 | # Distribution / packaging
 51 | .Python
 52 | ui/app/node_modules
 53 | ui/operator_ui/static/build
 54 | build/
 55 | develop-eggs/
 56 | dist/
 57 | downloads/
 58 | eggs/
 59 | .eggs/
 60 | lib/
 61 | lib64/
 62 | parts/
 63 | sdist/
 64 | var/
 65 | wheels/
 66 | pip-wheel-metadata/
 67 | share/python-wheels/
 68 | *.egg-info/
 69 | .installed.cfg
 70 | *.egg
 71 | MANIFEST
 72 | 
 73 | # PyInstaller
 74 | #  Usually these files are written by a python script from a template
 75 | #  before PyInstaller builds the exe, so as to inject date/other infos into it.
 76 | *.manifest
 77 | *.spec
 78 | 
 79 | # Installer logs
 80 | pip-log.txt
 81 | pip-delete-this-directory.txt
 82 | 
 83 | # Unit test / coverage reports
 84 | htmlcov/
 85 | .tox/
 86 | .nox/
 87 | .coverage
 88 | .coverage.*
 89 | .cache
 90 | nosetests.xml
 91 | coverage.xml
 92 | *.cover
 93 | .hypothesis/
 94 | .pytest_cache/
 95 | 
 96 | # e2e tests
 97 | e2e/manifests
 98 | e2e/tls
 99 | 
100 | # Translations
101 | *.mo
102 | *.pot
103 | 
104 | mocks
105 | 
106 | ui/.npm/
107 | 
108 | .DS_Store
109 | 


--------------------------------------------------------------------------------
/.golangci.yml:
--------------------------------------------------------------------------------
1 | # https://github.com/golangci/golangci/wiki/Configuration
2 | 
3 | service:
4 |   prepare:
5 |     - make deps
6 | 


--------------------------------------------------------------------------------
/.zappr.yaml:
--------------------------------------------------------------------------------
 1 | # for github.com
 2 | X-Zalando-Team: "acid"
 3 | # type should be one of [code, doc, config, tools, secrets]
 4 | # code will be the default value, if X-Zalando-Type is not found in .zappr.yml
 5 | X-Zalando-Type: code
 6 | 
 7 | approvals:
 8 |   groups:
 9 |     zalando:
10 |       minimum: 2
11 |       from:
12 |         orgs:
13 |           - zalando


--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # global owners
2 | *        @sdudoladov @Jan-M @FxKu @jopadi @idanovinda @hughcapet @macedigital
3 | 


--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
 1 | # Contributing guidelines
 2 | 
 3 | Wanna contribute to the Postgres Operator? Yay - here is how!
 4 | 
 5 | ## Reporting issues
 6 | 
 7 | Before filing an issue, if you have a question about Postgres Operator or have
 8 | a problem using it, please read the [concepts](docs/index.md) page or use the
 9 | different guides that we provide for [users](docs/user.md),
10 | [developers](docs/developer.md) or [admins](docs/administrator). Also double
11 | check with the current issues on our [Issues Tracker](https://github.com/zalando/postgres-operator/issues).
12 | 
13 | ## Contributing a pull request
14 | 
15 | 1. Submit a comment to the relevant issue or create a new issue describing your
16 |    proposed change.
17 | 2. Do a fork, develop and test your code changes.
18 | 3. Include documentation
19 | 4. Submit a pull request.
20 | 
21 | You'll get feedback about your pull request as soon as possible.
22 | 
23 | Happy Operator hacking ;-)
24 | 


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | The MIT License (MIT)
 2 | 
 3 | Copyright (c) 2024 Zalando SE
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | 


--------------------------------------------------------------------------------
/MAINTAINERS:
--------------------------------------------------------------------------------
1 | Sergey Dudoladov <sergey.dudoladov@zalando.de>
2 | Felix Kunde <felix.kunde@zalando.de>
3 | Jan Mussler <jan.mussler@zalando.de>
4 | Jociele Padilha <jociele.padilha@zalando.de>
5 | Ida Novindasari <ida.novindasari@zalando.de>
6 | Polina Bungina <polina.bungina@zalando.de>
7 | Matthias Adler <matthias.adler@zalando.de>
8 | 


--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
  1 | .PHONY: clean local test linux macos mocks docker push e2e
  2 | 
  3 | BINARY ?= postgres-operator
  4 | BUILD_FLAGS ?= -v
  5 | CGO_ENABLED ?= 0
  6 | ifeq ($(RACE),1)
  7 | 	BUILD_FLAGS += -race -a
  8 |     CGO_ENABLED=1
  9 | endif
 10 | 
 11 | LOCAL_BUILD_FLAGS ?= $(BUILD_FLAGS)
 12 | LDFLAGS ?= -X=main.version=$(VERSION)
 13 | DOCKERDIR = docker
 14 | 
 15 | IMAGE ?= registry.opensource.zalan.do/acid/$(BINARY)
 16 | TAG ?= $(VERSION)
 17 | GITHEAD = $(shell git rev-parse --short HEAD)
 18 | GITURL = $(shell git config --get remote.origin.url)
 19 | GITSTATUS = $(shell git status --porcelain || echo "no changes")
 20 | SOURCES = cmd/main.go
 21 | VERSION ?= $(shell git describe --tags --always --dirty)
 22 | DIRS := cmd pkg
 23 | PKG := `go list ./... | grep -v /vendor/`
 24 | 
 25 | ifeq ($(DEBUG),1)
 26 | 	DOCKERFILE = DebugDockerfile
 27 | 	DEBUG_POSTFIX := -debug-$(shell date hhmmss)
 28 | 	BUILD_FLAGS += -gcflags "-N -l"
 29 | else
 30 | 	DOCKERFILE = Dockerfile
 31 | endif
 32 | 
 33 | ifeq ($(FRESH),1)
 34 |   DEBUG_FRESH=$(shell date +"%H-%M-%S")
 35 | endif
 36 | 
 37 | ifdef CDP_PULL_REQUEST_NUMBER
 38 | 	CDP_TAG := -${CDP_BUILD_VERSION}
 39 | endif
 40 | 
 41 | ifndef GOPATH
 42 | 	GOPATH := $(HOME)/go
 43 | endif
 44 | 
 45 | PATH := $(GOPATH)/bin:$(PATH)
 46 | SHELL := env PATH=$(PATH) $(SHELL)
 47 | 
 48 | default: local
 49 | 
 50 | clean:
 51 | 	rm -rf build
 52 | 
 53 | local: ${SOURCES}
 54 | 	hack/verify-codegen.sh
 55 | 	CGO_ENABLED=${CGO_ENABLED} go build -o build/${BINARY} $(LOCAL_BUILD_FLAGS) -ldflags "$(LDFLAGS)" $^
 56 | 
 57 | linux: ${SOURCES}
 58 | 	GOOS=linux GOARCH=amd64 CGO_ENABLED=${CGO_ENABLED} go build -o build/linux/${BINARY} ${BUILD_FLAGS} -ldflags "$(LDFLAGS)" $^
 59 | 
 60 | macos: ${SOURCES}
 61 | 	GOOS=darwin GOARCH=amd64 CGO_ENABLED=${CGO_ENABLED} go build -o build/macos/${BINARY} ${BUILD_FLAGS} -ldflags "$(LDFLAGS)" $^
 62 | 
 63 | docker: ${DOCKERDIR}/${DOCKERFILE}
 64 | 	echo `(env)`
 65 | 	echo "Tag ${TAG}"
 66 | 	echo "Version ${VERSION}"
 67 | 	echo "CDP tag ${CDP_TAG}"
 68 | 	echo "git describe $(shell git describe --tags --always --dirty)"
 69 | 	docker build --rm -t "$(IMAGE):$(TAG)$(CDP_TAG)$(DEBUG_FRESH)$(DEBUG_POSTFIX)" -f "${DOCKERDIR}/${DOCKERFILE}" --build-arg VERSION="${VERSION}" .
 70 | 
 71 | indocker-race:
 72 | 	docker run --rm -v "${GOPATH}":"${GOPATH}" -e GOPATH="${GOPATH}" -e RACE=1 -w ${PWD} golang:1.23.4 bash -c "make linux"
 73 | 
 74 | push:
 75 | 	docker push "$(IMAGE):$(TAG)$(CDP_TAG)"
 76 | 
 77 | mocks:
 78 | 	GO111MODULE=on go generate ./...
 79 | 
 80 | tools:
 81 | 	GO111MODULE=on go get k8s.io/client-go@kubernetes-1.30.4
 82 | 	GO111MODULE=on go install github.com/golang/mock/mockgen@v1.6.0
 83 | 	GO111MODULE=on go mod tidy
 84 | 
 85 | fmt:
 86 | 	@gofmt -l -w -s $(DIRS)
 87 | 
 88 | vet:
 89 | 	@go vet $(PKG)
 90 | 	@staticcheck $(PKG)
 91 | 
 92 | deps: tools
 93 | 	GO111MODULE=on go mod vendor
 94 | 
 95 | test:
 96 | 	hack/verify-codegen.sh
 97 | 	GO111MODULE=on go test ./...
 98 | 
 99 | codegen:
100 | 	hack/update-codegen.sh
101 | 
102 | e2e: docker # build operator image to be tested
103 | 	cd e2e; make e2etest
104 | 


--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security
2 | 
3 | If you have discovered a security vulnerability, please email tech-security@zalando.de.
4 | 


--------------------------------------------------------------------------------
/build-ci.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/sh
 2 | set -e -x
 3 | 
 4 | team_repo="$GOPATH/src/github.com/zalando/"
 5 | project_dir="$team_repo/postgres-operator"
 6 | 
 7 | mkdir -p "$team_repo"
 8 | 
 9 | ln -s "$PWD" "$project_dir"
10 | cd "$project_dir"
11 | 
12 | make deps clean docker push
13 | 


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/.helmignore:
--------------------------------------------------------------------------------
 1 | # Patterns to ignore when building packages.
 2 | # This supports shell glob matching, relative path matching, and
 3 | # negation (prefixed with !). Only one pattern per line.
 4 | .DS_Store
 5 | # Common VCS dirs
 6 | .git/
 7 | .gitignore
 8 | .bzr/
 9 | .bzrignore
10 | .hg/
11 | .hgignore
12 | .svn/
13 | # Common backup files
14 | *.swp
15 | *.bak
16 | *.tmp
17 | *~
18 | # Various IDEs
19 | .project
20 | .idea/
21 | *.tmproj
22 | .vscode/
23 | 


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/Chart.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: v2
 2 | name: postgres-operator-ui
 3 | version: 1.14.0
 4 | appVersion: 1.14.0
 5 | home: https://github.com/zalando/postgres-operator
 6 | description: Postgres Operator UI provides a graphical interface for a convenient database-as-a-service user experience
 7 | keywords:
 8 | - postgres
 9 | - operator
10 | - ui
11 | - cloud-native
12 | - patroni
13 | - spilo
14 | maintainers:
15 | - name: Zalando
16 |   email: opensource@zalando.de
17 | sources:
18 | - https://github.com/zalando/postgres-operator
19 | engine: gotpl
20 | 


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/postgres-operator-ui-1.10.1.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/charts/postgres-operator-ui/postgres-operator-ui-1.10.1.tgz


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/postgres-operator-ui-1.11.0.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/charts/postgres-operator-ui/postgres-operator-ui-1.11.0.tgz


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/postgres-operator-ui-1.12.2.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/charts/postgres-operator-ui/postgres-operator-ui-1.12.2.tgz


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/postgres-operator-ui-1.13.0.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/charts/postgres-operator-ui/postgres-operator-ui-1.13.0.tgz


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/postgres-operator-ui-1.14.0.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/charts/postgres-operator-ui/postgres-operator-ui-1.14.0.tgz


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/postgres-operator-ui-1.9.0.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/charts/postgres-operator-ui/postgres-operator-ui-1.9.0.tgz


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/templates/NOTES.txt:
--------------------------------------------------------------------------------
1 | To verify that postgres-operator has started, run:
2 | 
3 |   kubectl --namespace={{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ template "postgres-operator-ui.name" . }}"


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/templates/_helpers.tpl:
--------------------------------------------------------------------------------
 1 | {{/* vim: set filetype=mustache: */}}
 2 | {{/*
 3 | Expand the name of the chart.
 4 | */}}
 5 | {{- define "postgres-operator-ui.name" -}}
 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
 7 | {{- end -}}
 8 | 
 9 | {{/*
10 | Create a default fully qualified app name.
11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
12 | If release name contains chart name it will be used as a full name.
13 | */}}
14 | {{- define "postgres-operator-ui.fullname" -}}
15 | {{- if .Values.fullnameOverride -}}
16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
17 | {{- else -}}
18 | {{- $name := default .Chart.Name .Values.nameOverride -}}
19 | {{- if contains $name .Release.Name -}}
20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}}
21 | {{- else -}}
22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
23 | {{- end -}}
24 | {{- end -}}
25 | {{- end -}}
26 | 
27 | {{/*
28 | Create a service account name.
29 | */}}
30 | {{- define "postgres-operator-ui.serviceAccountName" -}}
31 | {{ default (include "postgres-operator-ui.fullname" .) .Values.serviceAccount.name }}
32 | {{- end -}}
33 | 
34 | {{/*
35 | Create chart name and version as used by the chart label.
36 | */}}
37 | {{- define "postgres-operator-ui.chart" -}}
38 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
39 | {{- end -}}
40 | 


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/templates/clusterrole.yaml:
--------------------------------------------------------------------------------
 1 | {{ if .Values.rbac.create }}
 2 | apiVersion: rbac.authorization.k8s.io/v1
 3 | kind: ClusterRole
 4 | metadata:
 5 |   name: {{ include "postgres-operator-ui.serviceAccountName" . }}
 6 |   labels:
 7 |     app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }}
 8 |     helm.sh/chart: {{ template "postgres-operator-ui.chart" . }}
 9 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
10 |     app.kubernetes.io/instance: {{ .Release.Name }}
11 | rules:
12 | - apiGroups:
13 |   - acid.zalan.do
14 |   resources:
15 |   - postgresqls
16 |   verbs:
17 |   - create
18 |   - delete
19 |   - get
20 |   - list
21 |   - patch
22 |   - update
23 | - apiGroups:
24 |   - ""
25 |   resources:
26 |   - pods
27 |   verbs:
28 |   - get
29 |   - list
30 |   - watch
31 | - apiGroups:
32 |   - ""
33 |   resources:
34 |   - services
35 |   verbs:
36 |   - get
37 |   - list
38 | - apiGroups:
39 |   - apps
40 |   resources:
41 |   - deployments
42 |   - statefulsets
43 |   verbs:
44 |   - get
45 |   - list
46 | - apiGroups:
47 |   - ""
48 |   resources:
49 |   - namespaces
50 |   verbs:
51 |   - get
52 |   - list
53 | {{ end }}
54 | 


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/templates/clusterrolebinding.yaml:
--------------------------------------------------------------------------------
 1 | {{ if .Values.rbac.create }}
 2 | apiVersion: rbac.authorization.k8s.io/v1
 3 | kind: ClusterRoleBinding
 4 | metadata:
 5 |   name: {{ include "postgres-operator-ui.serviceAccountName" . }}
 6 |   labels:
 7 |     app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }}
 8 |     helm.sh/chart: {{ template "postgres-operator-ui.chart" . }}
 9 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
10 |     app.kubernetes.io/instance: {{ .Release.Name }}
11 | roleRef:
12 |   apiGroup: rbac.authorization.k8s.io
13 |   kind: ClusterRole
14 |   name: {{ include "postgres-operator-ui.serviceAccountName" . }}
15 | subjects:
16 | - kind: ServiceAccount
17 |   name: {{ include "postgres-operator-ui.serviceAccountName" . }}
18 |   namespace: {{ .Release.Namespace }}
19 | {{ end }}
20 | 


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/templates/ingress.yaml:
--------------------------------------------------------------------------------
 1 | {{- if .Values.ingress.enabled -}}
 2 | {{- $fullName := include "postgres-operator-ui.fullname" . -}}
 3 | {{- $svcPort := .Values.service.port -}}
 4 | 
 5 | {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
 6 | apiVersion: networking.k8s.io/v1
 7 | {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
 8 | apiVersion: networking.k8s.io/v1beta1
 9 | {{- else -}}
10 | apiVersion: extensions/v1beta1
11 | {{- end }}
12 | kind: Ingress
13 | metadata:
14 |   name: {{ $fullName }}
15 |   namespace: {{ .Release.Namespace }}
16 |   labels:
17 |     app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }}
18 |     helm.sh/chart: {{ template "postgres-operator-ui.chart" . }}
19 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
20 |     app.kubernetes.io/instance: {{ .Release.Name }}
21 |   {{- with .Values.ingress.annotations }}
22 |   annotations:
23 |     {{- toYaml . | nindent 4 }}
24 |   {{- end }}
25 | spec:
26 | {{- if .Values.ingress.ingressClassName }}
27 |   ingressClassName: {{ .Values.ingress.ingressClassName }}
28 | {{- end }}
29 | {{- if .Values.ingress.tls }}
30 |   tls:
31 |   {{- range .Values.ingress.tls }}
32 |     - hosts:
33 |       {{- range .hosts }}
34 |         - {{ . | quote }}
35 |       {{- end }}
36 |       secretName: {{ .secretName }}
37 |   {{- end }}
38 | {{- end }}
39 |   rules:
40 |   {{- range .Values.ingress.hosts }}
41 |     - host: {{ .host | quote }}
42 |       http:
43 |         paths:
44 |         {{- range .paths }}
45 |           - path: {{ . }}
46 |             {{ if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion -}}
47 |             pathType: Prefix
48 |             backend:
49 |               service:
50 |                 name: {{ $fullName }}
51 |                 port:
52 |                   number: {{ $svcPort }}
53 |             {{- else -}}
54 |             backend:
55 |               serviceName: {{ $fullName }}
56 |               servicePort: {{ $svcPort }}
57 |             {{- end -}}
58 |         {{- end }}
59 |   {{- end }}
60 | {{- end }}
61 | 


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/templates/service.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: v1
 2 | kind: Service
 3 | metadata:
 4 |   labels:
 5 |     app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }}
 6 |     helm.sh/chart: {{ template "postgres-operator-ui.chart" . }}
 7 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
 8 |     app.kubernetes.io/instance: {{ .Release.Name }}
 9 |   {{- with .Values.service.annotations }}
10 |   annotations:
11 |     {{- toYaml . | nindent 4 }}
12 |   {{- end }}
13 |   name: {{ template "postgres-operator-ui.fullname" . }}
14 |   namespace: {{ .Release.Namespace }}
15 | spec:
16 |   ports:
17 |     - port: {{ .Values.service.port }}
18 |       targetPort: 8081
19 |       {{- if and (eq .Values.service.type "NodePort") .Values.service.nodePort }}
20 |       nodePort: {{ .Values.service.nodePort }}
21 |       {{- end }}
22 |       protocol: TCP
23 |   selector:
24 |     app.kubernetes.io/instance: {{ .Release.Name }}
25 |     app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }}
26 |   type: {{ .Values.service.type }}
27 | 
28 | 
29 | 


--------------------------------------------------------------------------------
/charts/postgres-operator-ui/templates/serviceaccount.yaml:
--------------------------------------------------------------------------------
 1 | {{ if .Values.serviceAccount.create }}
 2 | apiVersion: v1
 3 | kind: ServiceAccount
 4 | metadata:
 5 |   name: {{ include "postgres-operator-ui.serviceAccountName" . }}
 6 |   namespace: {{ .Release.Namespace }}
 7 |   labels:
 8 |     app.kubernetes.io/name: {{ template "postgres-operator-ui.name" . }}
 9 |     helm.sh/chart: {{ template "postgres-operator-ui.chart" . }}
10 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
11 |     app.kubernetes.io/instance: {{ .Release.Name }}
12 | {{ end }}
13 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/.helmignore:
--------------------------------------------------------------------------------
 1 | # Patterns to ignore when building packages.
 2 | # This supports shell glob matching, relative path matching, and
 3 | # negation (prefixed with !). Only one pattern per line.
 4 | .DS_Store
 5 | # Common VCS dirs
 6 | .git/
 7 | .gitignore
 8 | .bzr/
 9 | .bzrignore
10 | .hg/
11 | .hgignore
12 | .svn/
13 | # Common backup files
14 | *.swp
15 | *.bak
16 | *.tmp
17 | *~
18 | # Various IDEs
19 | .project
20 | .idea/
21 | *.tmproj
22 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/Chart.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: v2
 2 | name: postgres-operator
 3 | version: 1.14.0
 4 | appVersion: 1.14.0
 5 | home: https://github.com/zalando/postgres-operator
 6 | description: Postgres Operator creates and manages PostgreSQL clusters running in Kubernetes
 7 | keywords:
 8 | - postgres
 9 | - operator
10 | - cloud-native
11 | - patroni
12 | - spilo
13 | maintainers:
14 | - name: Zalando
15 |   email: opensource@zalando.de
16 | sources:
17 | - https://github.com/zalando/postgres-operator
18 | engine: gotpl
19 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/crds/postgresteams.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: apiextensions.k8s.io/v1
 2 | kind: CustomResourceDefinition
 3 | metadata:
 4 |   name: postgresteams.acid.zalan.do
 5 |   labels:
 6 |     app.kubernetes.io/name: postgres-operator
 7 | spec:
 8 |   group: acid.zalan.do
 9 |   names:
10 |     kind: PostgresTeam
11 |     listKind: PostgresTeamList
12 |     plural: postgresteams
13 |     singular: postgresteam
14 |     shortNames:
15 |     - pgteam
16 |     categories:
17 |     - all
18 |   scope: Namespaced
19 |   versions:
20 |   - name: v1
21 |     served: true
22 |     storage: true
23 |     subresources:
24 |       status: {}
25 |     schema:
26 |       openAPIV3Schema:
27 |         type: object
28 |         required:
29 |           - kind
30 |           - apiVersion
31 |           - spec
32 |         properties:
33 |           kind:
34 |             type: string
35 |             enum:
36 |               - PostgresTeam
37 |           apiVersion:
38 |             type: string
39 |             enum:
40 |               - acid.zalan.do/v1
41 |           spec:
42 |             type: object
43 |             properties:
44 |               additionalSuperuserTeams:
45 |                 type: object
46 |                 description: "Map for teamId and associated additional superuser teams"
47 |                 additionalProperties:
48 |                   type: array
49 |                   nullable: true
50 |                   description: "List of teams to become Postgres superusers"
51 |                   items:
52 |                     type: string
53 |               additionalTeams:
54 |                 type: object
55 |                 description: "Map for teamId and associated additional teams"
56 |                 additionalProperties:
57 |                   type: array
58 |                   nullable: true
59 |                   description: "List of teams whose members will also be added to the Postgres cluster"
60 |                   items:
61 |                     type: string
62 |               additionalMembers:
63 |                 type: object
64 |                 description: "Map for teamId and associated additional users"
65 |                 additionalProperties:
66 |                   type: array
67 |                   nullable: true
68 |                   description: "List of users who will also be added to the Postgres cluster"
69 |                   items:
70 |                     type: string
71 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/postgres-operator-1.10.1.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/charts/postgres-operator/postgres-operator-1.10.1.tgz


--------------------------------------------------------------------------------
/charts/postgres-operator/postgres-operator-1.11.0.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/charts/postgres-operator/postgres-operator-1.11.0.tgz


--------------------------------------------------------------------------------
/charts/postgres-operator/postgres-operator-1.12.2.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/charts/postgres-operator/postgres-operator-1.12.2.tgz


--------------------------------------------------------------------------------
/charts/postgres-operator/postgres-operator-1.13.0.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/charts/postgres-operator/postgres-operator-1.13.0.tgz


--------------------------------------------------------------------------------
/charts/postgres-operator/postgres-operator-1.14.0.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/charts/postgres-operator/postgres-operator-1.14.0.tgz


--------------------------------------------------------------------------------
/charts/postgres-operator/postgres-operator-1.9.0.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/charts/postgres-operator/postgres-operator-1.9.0.tgz


--------------------------------------------------------------------------------
/charts/postgres-operator/templates/NOTES.txt:
--------------------------------------------------------------------------------
1 | To verify that postgres-operator has started, run:
2 | 
3 |   kubectl --namespace={{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ template "postgres-operator.name" . }}"
4 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/templates/_helpers.tpl:
--------------------------------------------------------------------------------
 1 | {{/* vim: set filetype=mustache: */}}
 2 | {{/*
 3 | Expand the name of the chart.
 4 | */}}
 5 | {{- define "postgres-operator.name" -}}
 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
 7 | {{- end -}}
 8 | 
 9 | {{/*
10 | Create a default fully qualified app name.
11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
12 | If release name contains chart name it will be used as a full name.
13 | */}}
14 | {{- define "postgres-operator.fullname" -}}
15 | {{- if .Values.fullnameOverride -}}
16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
17 | {{- else -}}
18 | {{- $name := default .Chart.Name .Values.nameOverride -}}
19 | {{- if contains $name .Release.Name -}}
20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}}
21 | {{- else -}}
22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
23 | {{- end -}}
24 | {{- end -}}
25 | {{- end -}}
26 | 
27 | {{/*
28 | Create a service account name.
29 | */}}
30 | {{- define "postgres-operator.serviceAccountName" -}}
31 | {{ default (include "postgres-operator.fullname" .) .Values.serviceAccount.name }}
32 | {{- end -}}
33 | 
34 | {{/*
35 | Create a pod service account name.
36 | */}}
37 | {{- define "postgres-pod.serviceAccountName" -}}
38 | {{ default (printf "%s-%v" (include "postgres-operator.fullname" .) "pod") .Values.podServiceAccount.name }}
39 | {{- end -}}
40 | 
41 | {{/*
42 | Create a pod priority class name.
43 | */}}
44 | {{- define "postgres-pod.priorityClassName" -}}
45 | {{ default (printf "%s-%v" (include "postgres-operator.fullname" .) "pod") .Values.podPriorityClassName.name }}
46 | {{- end -}}
47 | 
48 | {{/*
49 | Create a controller ID.
50 | */}}
51 | {{- define "postgres-operator.controllerID" -}}
52 | {{ default (include "postgres-operator.fullname" .) .Values.controllerID.name }}
53 | {{- end -}}
54 | 
55 | {{/*
56 | Create chart name and version as used by the chart label.
57 | */}}
58 | {{- define "postgres-operator.chart" -}}
59 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
60 | {{- end -}}
61 | 
62 | {{/*
63 | Flatten nested config options when ConfigMap is used as ConfigTarget
64 | */}}
65 | {{- define "flattenValuesForConfigMap" }}
66 | {{- range $key, $value := . }}
67 |     {{- if kindIs "slice" $value }}
68 | {{ $key }}: {{ join "," $value | quote }}
69 |     {{- else if kindIs "map" $value }}
70 |         {{- $list := list }}
71 |         {{- range $subKey, $subValue := $value }}
72 |             {{- $list = append $list (printf "%s:%s" $subKey $subValue) }}
73 |         {{- end }}
74 | {{ $key }}: {{ join "," $list | quote }}
75 |     {{- else }}
76 | {{ $key }}: {{ $value | quote }}
77 |     {{- end }}
78 | {{- end }}
79 | {{- end }}
80 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/templates/clusterrole-postgres-pod.yaml:
--------------------------------------------------------------------------------
 1 | {{ if .Values.rbac.create }}
 2 | apiVersion: rbac.authorization.k8s.io/v1
 3 | kind: ClusterRole
 4 | metadata:
 5 |   name: {{ include "postgres-pod.serviceAccountName" . }}
 6 |   labels:
 7 |     app.kubernetes.io/name: {{ template "postgres-operator.name" . }}
 8 |     helm.sh/chart: {{ template "postgres-operator.chart" . }}
 9 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
10 |     app.kubernetes.io/instance: {{ .Release.Name }}
11 | rules:
12 | # Patroni needs to watch and manage config maps or endpoints
13 | {{- if toString .Values.configGeneral.kubernetes_use_configmaps | eq "true" }}
14 | - apiGroups:
15 |   - ""
16 |   resources:
17 |   - configmaps
18 |   verbs:
19 |   - create
20 |   - delete
21 |   - deletecollection
22 |   - get
23 |   - list
24 |   - patch
25 |   - update
26 |   - watch
27 | {{- else }}
28 | - apiGroups:
29 |   - ""
30 |   resources:
31 |   - endpoints
32 |   verbs:
33 |   - create
34 |   - delete
35 |   - deletecollection
36 |   - get
37 |   - list
38 |   - patch
39 |   - update
40 |   - watch
41 | {{- end }}
42 | # Patroni needs to watch pods
43 | - apiGroups:
44 |   - ""
45 |   resources:
46 |   - pods
47 |   verbs:
48 |   - get
49 |   - list
50 |   - patch
51 |   - update
52 |   - watch
53 | # to let Patroni create a headless service
54 | - apiGroups:
55 |   - ""
56 |   resources:
57 |   - services
58 |   verbs:
59 |   - create
60 | {{- if toString .Values.configKubernetes.spilo_privileged | eq "true" }}
61 | # to run privileged pods
62 | - apiGroups:
63 |   - extensions
64 |   resources:
65 |   - podsecuritypolicies
66 |   resourceNames:
67 |   - privileged
68 |   verbs:
69 |   - use
70 | {{- end }}
71 | {{ end }}
72 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/templates/clusterrolebinding.yaml:
--------------------------------------------------------------------------------
 1 | {{ if .Values.rbac.create }}
 2 | apiVersion: rbac.authorization.k8s.io/v1
 3 | kind: ClusterRoleBinding
 4 | metadata:
 5 |   name: {{ include "postgres-operator.serviceAccountName" . }}
 6 |   labels:
 7 |     app.kubernetes.io/name: {{ template "postgres-operator.name" . }}
 8 |     helm.sh/chart: {{ template "postgres-operator.chart" . }}
 9 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
10 |     app.kubernetes.io/instance: {{ .Release.Name }}
11 | roleRef:
12 |   apiGroup: rbac.authorization.k8s.io
13 |   kind: ClusterRole
14 |   name: {{ include "postgres-operator.serviceAccountName" . }}
15 | subjects:
16 | - kind: ServiceAccount
17 |   name: {{ include "postgres-operator.serviceAccountName" . }}
18 |   namespace: {{ .Release.Namespace }}
19 | {{ end }}
20 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/templates/configmap.yaml:
--------------------------------------------------------------------------------
 1 | {{- if eq .Values.configTarget "ConfigMap" }}
 2 | apiVersion: v1
 3 | kind: ConfigMap
 4 | metadata:
 5 |   name: {{ template "postgres-operator.fullname" . }}
 6 |   namespace: {{ .Release.Namespace }}
 7 |   labels:
 8 |     app.kubernetes.io/name: {{ template "postgres-operator.name" . }}
 9 |     helm.sh/chart: {{ template "postgres-operator.chart" . }}
10 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
11 |     app.kubernetes.io/instance: {{ .Release.Name }}
12 | data:
13 | {{- if or .Values.podPriorityClassName.create .Values.podPriorityClassName.name }}
14 |   pod_priority_class_name: {{ include "postgres-pod.priorityClassName" . }}
15 | {{- end }}
16 |   pod_service_account_name: {{ include "postgres-pod.serviceAccountName" . }}
17 | {{- include "flattenValuesForConfigMap" .Values.configGeneral | indent 2 }}
18 | {{- include "flattenValuesForConfigMap" .Values.configUsers | indent 2 }}
19 | {{- include "flattenValuesForConfigMap" .Values.configMajorVersionUpgrade | indent 2 }}
20 | {{- include "flattenValuesForConfigMap" .Values.configKubernetes | indent 2 }}
21 | {{- include "flattenValuesForConfigMap" .Values.configTimeouts | indent 2 }}
22 | {{- include "flattenValuesForConfigMap" .Values.configLoadBalancer | indent 2 }}
23 | {{- include "flattenValuesForConfigMap" .Values.configAwsOrGcp | indent 2 }}
24 | {{- include "flattenValuesForConfigMap" .Values.configLogicalBackup | indent 2 }}
25 | {{- include "flattenValuesForConfigMap" .Values.configDebug | indent 2 }}
26 | {{- include "flattenValuesForConfigMap" .Values.configLoggingRestApi | indent 2 }}
27 | {{- include "flattenValuesForConfigMap" .Values.configTeamsApi | indent 2 }}
28 | {{- include "flattenValuesForConfigMap" .Values.configConnectionPooler | indent 2 }}
29 | {{- include "flattenValuesForConfigMap" .Values.configPatroni | indent 2 }}
30 | {{- end }}
31 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/templates/operatorconfiguration.yaml:
--------------------------------------------------------------------------------
 1 | {{- if eq .Values.configTarget "OperatorConfigurationCRD" }}
 2 | apiVersion: "acid.zalan.do/v1"
 3 | kind: OperatorConfiguration
 4 | metadata:
 5 |   name: {{ template "postgres-operator.fullname" . }}
 6 |   namespace: {{ .Release.Namespace }}
 7 |   labels:
 8 |     app.kubernetes.io/name: {{ template "postgres-operator.name" . }}
 9 |     helm.sh/chart: {{ template "postgres-operator.chart" . }}
10 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
11 |     app.kubernetes.io/instance: {{ .Release.Name }}
12 | configuration:
13 | {{ tpl (toYaml .Values.configGeneral) . | indent 2 }}
14 |   users:
15 | {{ tpl (toYaml .Values.configUsers) . | indent 4 }}
16 |   major_version_upgrade:
17 | {{ tpl (toYaml .Values.configMajorVersionUpgrade) . | indent 4 }}
18 |   kubernetes:
19 |     {{- if .Values.podPriorityClassName.name }}
20 |     pod_priority_class_name: {{ .Values.podPriorityClassName.name }}
21 |     {{- end }}
22 |     pod_service_account_name: {{ include "postgres-pod.serviceAccountName" . }}
23 |     oauth_token_secret_name: {{ template "postgres-operator.fullname" . }}
24 | {{ tpl (toYaml .Values.configKubernetes) . | indent 4 }}
25 |   postgres_pod_resources:
26 | {{ tpl (toYaml .Values.configPostgresPodResources) . | indent 4 }}
27 |   timeouts:
28 | {{ tpl (toYaml .Values.configTimeouts) . | indent 4 }}
29 |   load_balancer:
30 | {{ tpl (toYaml .Values.configLoadBalancer) . | indent 4 }}
31 |   aws_or_gcp:
32 | {{ tpl (toYaml .Values.configAwsOrGcp) . | indent 4 }}
33 |   logical_backup:
34 | {{ tpl (toYaml .Values.configLogicalBackup) . | indent 4 }}
35 |   debug:
36 | {{ tpl (toYaml .Values.configDebug) . | indent 4 }}
37 |   teams_api:
38 | {{ tpl (toYaml .Values.configTeamsApi) . | indent 4 }}
39 |   logging_rest_api:
40 | {{ tpl (toYaml .Values.configLoggingRestApi) . | indent 4 }}
41 |   connection_pooler:
42 | {{ tpl (toYaml .Values.configConnectionPooler) . | indent 4 }}
43 |   patroni:
44 | {{ tpl (toYaml .Values.configPatroni) . | indent 4 }}
45 | {{- end }}
46 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/templates/postgres-pod-priority-class.yaml:
--------------------------------------------------------------------------------
 1 | {{- if .Values.podPriorityClassName.create }}
 2 | apiVersion: scheduling.k8s.io/v1
 3 | description: 'Use only for databases controlled by Postgres operator'
 4 | kind: PriorityClass
 5 | metadata:
 6 |   labels:
 7 |     app.kubernetes.io/name: {{ template "postgres-operator.name" . }}
 8 |     helm.sh/chart: {{ template "postgres-operator.chart" . }}
 9 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
10 |     app.kubernetes.io/instance: {{ .Release.Name }}
11 |   name: {{ include "postgres-pod.priorityClassName" . }}
12 |   namespace: {{ .Release.Namespace }}
13 | preemptionPolicy: PreemptLowerPriority
14 | globalDefault: false
15 | value: {{ .Values.podPriorityClassName.priority }}
16 | {{- end }}
17 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/templates/service.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: v1
 2 | kind: Service
 3 | metadata:
 4 |   labels:
 5 |     app.kubernetes.io/name: {{ template "postgres-operator.name" . }}
 6 |     helm.sh/chart: {{ template "postgres-operator.chart" . }}
 7 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
 8 |     app.kubernetes.io/instance: {{ .Release.Name }}
 9 |   name: {{ template "postgres-operator.fullname" . }}
10 |   namespace: {{ .Release.Namespace }}
11 | spec:
12 |   type: ClusterIP
13 |   ports:
14 |   - port: 8080
15 |     protocol: TCP
16 |     targetPort: 8080
17 |   selector:
18 |     app.kubernetes.io/instance: {{ .Release.Name }}
19 |     app.kubernetes.io/name: {{ template "postgres-operator.name" . }}
20 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/templates/serviceaccount.yaml:
--------------------------------------------------------------------------------
 1 | {{ if .Values.serviceAccount.create }}
 2 | apiVersion: v1
 3 | kind: ServiceAccount
 4 | metadata:
 5 |   name: {{ include "postgres-operator.serviceAccountName" . }}
 6 |   namespace: {{ .Release.Namespace }}
 7 |   labels:
 8 |     app.kubernetes.io/name: {{ template "postgres-operator.name" . }}
 9 |     helm.sh/chart: {{ template "postgres-operator.chart" . }}
10 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
11 |     app.kubernetes.io/instance: {{ .Release.Name }}
12 | {{ end }}
13 | 


--------------------------------------------------------------------------------
/charts/postgres-operator/templates/user-facing-clusterroles.yaml:
--------------------------------------------------------------------------------
 1 | {{ if .Values.rbac.createAggregateClusterRoles }}
 2 | apiVersion: rbac.authorization.k8s.io/v1
 3 | kind: ClusterRole
 4 | metadata:
 5 |   labels:
 6 |     rbac.authorization.k8s.io/aggregate-to-admin: "true"
 7 |     app.kubernetes.io/name: {{ template "postgres-operator.name" . }}
 8 |     helm.sh/chart: {{ template "postgres-operator.chart" . }}
 9 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
10 |     app.kubernetes.io/instance: {{ .Release.Name }}
11 |   name: {{ template "postgres-operator.fullname" . }}:users:admin
12 | rules:
13 | - apiGroups:
14 |   - acid.zalan.do
15 |   resources:
16 |   - postgresqls
17 |   - postgresqls/status
18 |   verbs:
19 |   - create
20 |   - delete
21 |   - deletecollection
22 |   - get
23 |   - list
24 |   - patch
25 |   - update
26 |   - watch
27 | 
28 | ---
29 | apiVersion: rbac.authorization.k8s.io/v1
30 | kind: ClusterRole
31 | metadata:
32 |   labels:
33 |     rbac.authorization.k8s.io/aggregate-to-edit: "true"
34 |     app.kubernetes.io/name: {{ template "postgres-operator.name" . }}
35 |     helm.sh/chart: {{ template "postgres-operator.chart" . }}
36 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
37 |     app.kubernetes.io/instance: {{ .Release.Name }}
38 |   name: {{ template "postgres-operator.fullname" . }}:users:edit
39 | rules:
40 | - apiGroups:
41 |   - acid.zalan.do
42 |   resources:
43 |   - postgresqls
44 |   verbs:
45 |   - create
46 |   - update
47 |   - patch
48 |   - delete
49 | 
50 | ---
51 | apiVersion: rbac.authorization.k8s.io/v1
52 | kind: ClusterRole
53 | metadata:
54 |   labels:
55 |     rbac.authorization.k8s.io/aggregate-to-view: "true"
56 |     app.kubernetes.io/name: {{ template "postgres-operator.name" . }}
57 |     helm.sh/chart: {{ template "postgres-operator.chart" . }}
58 |     app.kubernetes.io/managed-by: {{ .Release.Service }}
59 |     app.kubernetes.io/instance: {{ .Release.Name }}
60 |   name: {{ template "postgres-operator.fullname" . }}:users:view
61 | rules:
62 | - apiGroups:
63 |   - acid.zalan.do
64 |   resources:
65 |   - postgresqls
66 |   - postgresqls/status
67 |   verbs:
68 |   - get
69 |   - list
70 |   - watch
71 | {{ end }}
72 | 


--------------------------------------------------------------------------------
/cmd/main.go:
--------------------------------------------------------------------------------
  1 | package main
  2 | 
  3 | import (
  4 | 	"flag"
  5 | 	"os"
  6 | 	"os/signal"
  7 | 	"sync"
  8 | 	"syscall"
  9 | 	"time"
 10 | 
 11 | 	log "github.com/sirupsen/logrus"
 12 | 
 13 | 	"github.com/zalando/postgres-operator/pkg/controller"
 14 | 	"github.com/zalando/postgres-operator/pkg/spec"
 15 | 	"github.com/zalando/postgres-operator/pkg/util/k8sutil"
 16 | )
 17 | 
 18 | var (
 19 | 	kubeConfigFile string
 20 | 	outOfCluster   bool
 21 | 	version        string
 22 | 	config         spec.ControllerConfig
 23 | )
 24 | 
 25 | func mustParseDuration(d string) time.Duration {
 26 | 	duration, err := time.ParseDuration(d)
 27 | 	if err != nil {
 28 | 		panic(err)
 29 | 	}
 30 | 	return duration
 31 | }
 32 | 
 33 | func init() {
 34 | 	flag.StringVar(&kubeConfigFile, "kubeconfig", "", "Path to kubeconfig file with authorization and master location information.")
 35 | 	flag.BoolVar(&outOfCluster, "outofcluster", false, "Whether the operator runs in- our outside of the Kubernetes cluster.")
 36 | 	flag.BoolVar(&config.NoDatabaseAccess, "nodatabaseaccess", false, "Disable all access to the database from the operator side.")
 37 | 	flag.BoolVar(&config.NoTeamsAPI, "noteamsapi", false, "Disable all access to the teams API")
 38 | 	flag.IntVar(&config.KubeQPS, "kubeqps", 10, "Kubernetes api requests per second.")
 39 | 	flag.IntVar(&config.KubeBurst, "kubeburst", 20, "Kubernetes api requests burst limit.")
 40 | 	flag.Parse()
 41 | 
 42 | 	config.EnableJsonLogging = os.Getenv("ENABLE_JSON_LOGGING") == "true"
 43 | 
 44 | 	configMapRawName := os.Getenv("CONFIG_MAP_NAME")
 45 | 	if configMapRawName != "" {
 46 | 
 47 | 		err := config.ConfigMapName.Decode(configMapRawName)
 48 | 		if err != nil {
 49 | 			log.Fatalf("incorrect config map name: %v", configMapRawName)
 50 | 		}
 51 | 
 52 | 		log.Printf("Fully qualified configmap name: %v", config.ConfigMapName)
 53 | 
 54 | 	}
 55 | 	if crdInterval := os.Getenv("CRD_READY_WAIT_INTERVAL"); crdInterval != "" {
 56 | 		config.CRDReadyWaitInterval = mustParseDuration(crdInterval)
 57 | 	} else {
 58 | 		config.CRDReadyWaitInterval = 4 * time.Second
 59 | 	}
 60 | 
 61 | 	if crdTimeout := os.Getenv("CRD_READY_WAIT_TIMEOUT"); crdTimeout != "" {
 62 | 		config.CRDReadyWaitTimeout = mustParseDuration(crdTimeout)
 63 | 	} else {
 64 | 		config.CRDReadyWaitTimeout = 30 * time.Second
 65 | 	}
 66 | }
 67 | 
 68 | func main() {
 69 | 	var err error
 70 | 
 71 | 	if config.EnableJsonLogging {
 72 | 		log.SetFormatter(&log.JSONFormatter{})
 73 | 	}
 74 | 	log.SetOutput(os.Stdout)
 75 | 	log.Printf("Spilo operator %s\n", version)
 76 | 
 77 | 	sigs := make(chan os.Signal, 1)
 78 | 	stop := make(chan struct{})
 79 | 	signal.Notify(sigs, os.Interrupt, syscall.SIGTERM) // Push signals into channel
 80 | 
 81 | 	wg := &sync.WaitGroup{} // Goroutines can add themselves to this to be waited on
 82 | 
 83 | 	config.RestConfig, err = k8sutil.RestConfig(kubeConfigFile, outOfCluster)
 84 | 	if err != nil {
 85 | 		log.Fatalf("couldn't get REST config: %v", err)
 86 | 	}
 87 | 
 88 | 	config.RestConfig.QPS = float32(config.KubeQPS)
 89 | 	config.RestConfig.Burst = config.KubeBurst
 90 | 
 91 | 	c := controller.NewController(&config, "")
 92 | 
 93 | 	c.Run(stop, wg)
 94 | 
 95 | 	sig := <-sigs
 96 | 	log.Printf("Shutting down... %+v", sig)
 97 | 
 98 | 	close(stop) // Tell goroutines to stop themselves
 99 | 	wg.Wait()   // Wait for all to be stopped
100 | }
101 | 


--------------------------------------------------------------------------------
/delivery.yaml:
--------------------------------------------------------------------------------
 1 | version: "2017-09-20"
 2 | pipeline:
 3 |     - id: build-postgres-operator
 4 |       type: script
 5 |       vm_config:
 6 |         type: linux
 7 |         size: large
 8 |         image: cdp-runtime/go
 9 |       cache:
10 |         paths:
11 |           - /go/pkg/mod       # pkg cache for Go modules
12 |           - ~/.cache/go-build # Go build cache
13 |       commands:
14 |         - desc: Run unit tests
15 |           cmd: |
16 |             make deps mocks test
17 | 
18 |         - desc: Build Docker image
19 |           cmd: |
20 |             IS_PR_BUILD=${CDP_PULL_REQUEST_NUMBER+"true"}
21 |             if [[ ${CDP_TARGET_BRANCH} == "master" && ${IS_PR_BUILD} != "true" ]]
22 |             then
23 |               IMAGE=registry-write.opensource.zalan.do/acid/postgres-operator
24 |             else
25 |               IMAGE=registry-write.opensource.zalan.do/acid/postgres-operator-test
26 |             fi
27 |             export IMAGE
28 |             make docker push
29 | 
30 |     - id: build-operator-ui
31 |       type: script
32 |       vm_config:
33 |         type: linux
34 | 
35 |       commands:
36 |         - desc: 'Prepare environment'
37 |           cmd: |
38 |             apt-get update
39 |             apt-get install -y build-essential
40 | 
41 |         - desc: 'Compile JavaScript app'
42 |           cmd: |
43 |             cd ui
44 |             make appjs
45 | 
46 |         - desc: 'Build and push Docker image'
47 |           cmd: |
48 |             cd ui
49 |             IS_PR_BUILD=${CDP_PULL_REQUEST_NUMBER+"true"}
50 |             if [[ ${CDP_TARGET_BRANCH} == "master" && ${IS_PR_BUILD} != "true" ]]
51 |             then
52 |               IMAGE=registry-write.opensource.zalan.do/acid/postgres-operator-ui
53 |             else
54 |               IMAGE=registry-write.opensource.zalan.do/acid/postgres-operator-ui-test
55 |             fi
56 |             export IMAGE
57 |             make docker
58 |             make push
59 | 
60 |     - id: build-logical-backup
61 |       type: script
62 |       vm_config:
63 |         type: linux
64 | 
65 |       commands:
66 |         - desc: Build image
67 |           cmd: |
68 |             cd logical-backup
69 |             export TAG=$(git describe --tags --always --dirty)
70 |             IMAGE="registry-write.opensource.zalan.do/acid/logical-backup"
71 |             docker build --rm -t "$IMAGE:$TAG$CDP_TAG" .
72 |             docker push "$IMAGE:$TAG$CDP_TAG"
73 | 


--------------------------------------------------------------------------------
/docker/DebugDockerfile:
--------------------------------------------------------------------------------
 1 | FROM golang:1.23-alpine
 2 | LABEL maintainer="Team ACID @ Zalando <team-acid@zalando.de>"
 3 | 
 4 | # We need root certificates to deal with teams api over https
 5 | RUN apk -U add --no-cache ca-certificates delve
 6 | 
 7 | COPY build/* /
 8 | 
 9 | RUN addgroup -g 1000 pgo
10 | RUN adduser -D -u 1000 -G pgo -g 'Postgres Operator' pgo
11 | 
12 | USER pgo:pgo
13 | RUN ls -l /
14 | 
15 | CMD ["/dlv", "--listen=:7777", "--headless=true", "--api-version=2", "exec", "/postgres-operator"]
16 | 


--------------------------------------------------------------------------------
/docker/Dockerfile:
--------------------------------------------------------------------------------
 1 | ARG BASE_IMAGE=registry.opensource.zalan.do/library/alpine-3:latest
 2 | FROM golang:1.23-alpine AS builder
 3 | ARG VERSION=latest
 4 | 
 5 | COPY  . /go/src/github.com/zalando/postgres-operator
 6 | WORKDIR /go/src/github.com/zalando/postgres-operator
 7 | 
 8 | RUN GO111MODULE=on go mod vendor \
 9 |     && CGO_ENABLED=0 go build -o build/postgres-operator -v -ldflags "-X=main.version=${VERSION}" cmd/main.go
10 | 
11 | FROM ${BASE_IMAGE}
12 | LABEL maintainer="Team ACID @ Zalando <team-acid@zalando.de>"
13 | LABEL org.opencontainers.image.source="https://github.com/zalando/postgres-operator"
14 | 
15 | # We need root certificates to deal with teams api over https
16 | RUN apk -U upgrade --no-cache \
17 |     && apk add --no-cache curl ca-certificates
18 | 
19 | COPY --from=builder /go/src/github.com/zalando/postgres-operator/build/* /
20 | 
21 | RUN addgroup -g 1000 pgo
22 | RUN adduser -D -u 1000 -G pgo -g 'Postgres Operator' pgo
23 | 
24 | USER 1000:1000
25 | 
26 | ENTRYPOINT ["/postgres-operator"]
27 | 


--------------------------------------------------------------------------------
/docker/build_operator.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/bash
 2 | 
 3 | export DEBIAN_FRONTEND=noninteractive
 4 | 
 5 | arch=$(dpkg --print-architecture)
 6 | 
 7 | set -ex
 8 | 
 9 | # Install dependencies
10 | 
11 | apt-get update
12 | apt-get install -y wget
13 | 
14 | (
15 |     cd /tmp
16 |     wget -q "https://storage.googleapis.com/golang/go1.23.4.linux-${arch}.tar.gz" -O go.tar.gz
17 |     tar -xf go.tar.gz
18 |     mv go /usr/local
19 |     ln -s /usr/local/go/bin/go /usr/bin/go
20 |     go version
21 | )
22 | 
23 | # Build
24 | 
25 | export PATH="$PATH:$HOME/go/bin"
26 | export GOPATH="$HOME/go"
27 | mkdir -p build
28 | 
29 | GO111MODULE=on go mod vendor
30 | CGO_ENABLED=0 go build -o build/postgres-operator -v -ldflags "$OPERATOR_LDFLAGS" cmd/main.go
31 | 


--------------------------------------------------------------------------------
/docs/diagrams/Makefile:
--------------------------------------------------------------------------------
 1 | OBJ=$(patsubst %.tex, %.png, $(wildcard *.tex))
 2 | 
 3 | .PHONY: all
 4 | 
 5 | all: $(OBJ)
 6 | 
 7 | %.pdf: %.tex
 8 | 	lualatex 
lt; -shell-escape $@
 9 | 
10 | %.png: %.pdf
11 | 	convert -flatten -density 300 
lt; -quality 90 $@
12 | 


--------------------------------------------------------------------------------
/docs/diagrams/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/logo.png


--------------------------------------------------------------------------------
/docs/diagrams/neutral_operator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/neutral_operator.png


--------------------------------------------------------------------------------
/docs/diagrams/neutral_operator_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/neutral_operator_dark.png


--------------------------------------------------------------------------------
/docs/diagrams/neutral_operator_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/neutral_operator_light.png


--------------------------------------------------------------------------------
/docs/diagrams/operator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/operator.png


--------------------------------------------------------------------------------
/docs/diagrams/pgui-cluster-list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/pgui-cluster-list.png


--------------------------------------------------------------------------------
/docs/diagrams/pgui-cluster-startup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/pgui-cluster-startup.png


--------------------------------------------------------------------------------
/docs/diagrams/pgui-delete-cluster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/pgui-delete-cluster.png


--------------------------------------------------------------------------------
/docs/diagrams/pgui-finished-setup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/pgui-finished-setup.png


--------------------------------------------------------------------------------
/docs/diagrams/pgui-new-cluster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/pgui-new-cluster.png


--------------------------------------------------------------------------------
/docs/diagrams/pgui-operator-logs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/pgui-operator-logs.png


--------------------------------------------------------------------------------
/docs/diagrams/pgui-waiting-for-master.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/pgui-waiting-for-master.png


--------------------------------------------------------------------------------
/docs/diagrams/pod.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/docs/diagrams/pod.png


--------------------------------------------------------------------------------
/docs/reference/command_line_and_environment.md:
--------------------------------------------------------------------------------
 1 | # Command-line options
 2 | 
 3 | The following command-line options are supported for the operator:
 4 | 
 5 | * **-kubeconfig**
 6 |   the path to the kubeconfig file. Usually named config, it contains
 7 |   authorization information as well as the URL of the Kubernetes master.
 8 | 
 9 | * **-outofcluster**
10 |   run the operator on a client machine, as opposed to a within the cluster.
11 |   When running in this mode, the operator cannot connect to databases inside
12 |   the cluster, as well as call URLs of in-cluster objects (i.e. teams api
13 |   server). Mostly useful for debugging, it also requires setting the
14 |   `OPERATOR_NAMESPACE` environment variable for the operator own namespace.
15 | 
16 | * **-nodatabaseaccess**
17 |   disable database access from the operator. Equivalent to the
18 |   `enable_database_access` set to off and can be overridden by the
19 |   aforementioned operator configuration option.
20 | 
21 | * **-noteamsapi**
22 |   disable access to the teams API. Equivalent to the `enable_teams_api` set to
23 |   off can can be overridden by the aforementioned operator configuration
24 |   option.
25 | 
26 | In addition to that, standard [glog
27 | flags](https://godoc.org/github.com/golang/glog) are also supported. For
28 | instance, one may want to add `-alsologtostderr` and `-v=8` to debug the
29 | operator REST calls.
30 | 
31 | # Environment variables
32 | 
33 | The following environment variables are accepted by the operator:
34 | 
35 | * **CONFIG_MAP_NAME**
36 |   name of the config map where the operator should look for its configuration.
37 |   Must be present.
38 | 
39 | * **OPERATOR_NAMESPACE**
40 |   name of the namespace the operator runs it. Overrides autodetection by the
41 |   operator itself.
42 | 
43 | * **WATCHED_NAMESPACE**
44 |   the name of the namespace the operator watches. Special '*' character denotes
45 |   all namespaces. Empty value defaults to the operator namespace. Overrides the
46 |   `watched_namespace` operator parameter.
47 | 
48 | * **SCALYR_API_KEY** (*deprecated*)
49 |   the value of the Scalyr API key to supply to the pods. Overrides the
50 |   `scalyr_api_key` operator parameter.
51 | 
52 | * **CRD_READY_WAIT_TIMEOUT**
53 |   defines the timeout for the complete `postgresql` CRD creation. When not set
54 |   default is 30s.
55 | 
56 | * **CRD_READY_WAIT_INTERVAL**
57 |   defines the  interval between consecutive attempts waiting for the
58 |   `postgresql` CRD to be created. The default is 5s.
59 |   
60 | * **ENABLE_JSON_LOGGING**
61 |   Set to `true` for JSON formatted logging output.
62 |   The default is false.
63 | 


--------------------------------------------------------------------------------
/e2e/Dockerfile:
--------------------------------------------------------------------------------
 1 | # An image to run e2e tests.
 2 | # The image does not include the tests; all necessary files are bind-mounted when a container starts.
 3 | FROM ubuntu:20.04
 4 | LABEL maintainer="Team ACID @ Zalando <team-acid@zalando.de>"
 5 | 
 6 | ENV TERM xterm-256color
 7 | 
 8 | COPY requirements.txt ./
 9 | 
10 | RUN apt-get update \
11 |     && apt-get install --no-install-recommends -y \
12 |            python3 \
13 |            python3-setuptools \
14 |            python3-pip \
15 |            curl \
16 |            vim \
17 |     && pip3 install --no-cache-dir -r requirements.txt \
18 |     && curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.24.3/bin/linux/amd64/kubectl \
19 |     && chmod +x ./kubectl \
20 |     && mv ./kubectl /usr/local/bin/kubectl \
21 |     && apt-get clean \
22 |     && rm -rf /var/lib/apt/lists/*
23 | 
24 | # working line
25 | # python3 -m unittest discover -v --failfast -k test_e2e.EndToEndTestCase.test_lazy_spilo_upgrade --start-directory tests
26 | ENTRYPOINT ["python3", "-m", "unittest"]
27 | CMD ["discover","-v","--failfast","--start-directory","/tests"]


--------------------------------------------------------------------------------
/e2e/Makefile:
--------------------------------------------------------------------------------
 1 | .PHONY: clean copy docker push tools test
 2 | 
 3 | BINARY ?= postgres-operator-e2e-tests-runner
 4 | BUILD_FLAGS ?= -v
 5 | CGO_ENABLED ?= 0
 6 | ifeq ($(RACE),1)
 7 | 	BUILD_FLAGS += -race -a
 8 |     CGO_ENABLED=1
 9 | endif
10 | 
11 | LOCAL_BUILD_FLAGS ?= $(BUILD_FLAGS)
12 | LDFLAGS ?= -X=main.version=$(VERSION)
13 | 
14 | IMAGE            ?= registry.opensource.zalan.do/acid/$(BINARY)
15 | VERSION          ?= $(shell git describe --tags --always --dirty)
16 | TAG              ?= $(VERSION)
17 | GITHEAD          = $(shell git rev-parse --short HEAD)
18 | GITURL           = $(shell git config --get remote.origin.url)
19 | GITSTATU         = $(shell git status --porcelain || echo 'no changes')
20 | TTYFLAGS         = $(shell test -t 0 && echo '-it')
21 | 
22 | ifndef GOPATH
23 | 	GOPATH := $(HOME)/go
24 | endif
25 | 
26 | PATH := $(GOPATH)/bin:$(PATH)
27 | 
28 | default: tools
29 | 
30 | clean:
31 | 	rm -rf manifests
32 | 	rm -rf tls
33 | 
34 | copy: clean
35 | 	mkdir manifests
36 | 	cp -r ../manifests .
37 | 	mkdir tls
38 | 
39 | docker:
40 | 	docker build -t "$(IMAGE):$(TAG)" .
41 | 
42 | push: docker
43 | 	docker push "$(IMAGE):$(TAG)"
44 | 
45 | tools:
46 | 	# install pinned version of 'kind'
47 | 	# go install must run outside of a dir with a (module-based) Go project !
48 | 	# otherwise go install updates project's dependencies and/or behaves differently
49 | 	cd "/tmp" && GO111MODULE=on go install sigs.k8s.io/kind@v0.24.0
50 | 
51 | e2etest: tools copy clean
52 | 	./run.sh main
53 | 
54 | cleanup: clean
55 | 	./run.sh cleanup


--------------------------------------------------------------------------------
/e2e/exec.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | kubectl exec -i $1 -- sh -c "$2"
3 | 


--------------------------------------------------------------------------------
/e2e/exec_into_env.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/bash
 2 | 
 3 | export cluster_name="postgres-operator-e2e-tests"
 4 | export kubeconfig_path="/tmp/kind-config-${cluster_name}"
 5 | export operator_image="registry.opensource.zalan.do/acid/postgres-operator:latest"
 6 | export e2e_test_runner_image="registry.opensource.zalan.do/acid/postgres-operator-e2e-tests-runner:0.4"
 7 | 
 8 | docker run -it --entrypoint /bin/bash --network=host -e "TERM=xterm-256color" \
 9 |     --mount type=bind,source="$(readlink -f ${kubeconfig_path})",target=/root/.kube/config \
10 |     --mount type=bind,source="$(readlink -f manifests)",target=/manifests \
11 |     --mount type=bind,source="$(readlink -f tests)",target=/tests \
12 |     --mount type=bind,source="$(readlink -f exec.sh)",target=/exec.sh \
13 |     --mount type=bind,source="$(readlink -f scripts)",target=/scripts \
14 |     -e OPERATOR_IMAGE="${operator_image}" "${e2e_test_runner_image}"
15 | 


--------------------------------------------------------------------------------
/e2e/kind-cluster-postgres-operator-e2e-tests.yaml:
--------------------------------------------------------------------------------
1 | kind: Cluster
2 | apiVersion: kind.x-k8s.io/v1alpha4
3 | nodes:
4 | - role: control-plane
5 | - role: worker
6 | - role: worker
7 | featureGates:
8 |   StatefulSetAutoDeletePVC: true
9 | 


--------------------------------------------------------------------------------
/e2e/requirements.txt:
--------------------------------------------------------------------------------
1 | kubernetes==29.2.0
2 | timeout_decorator==0.5.0
3 | pyyaml==6.0.1
4 | 


--------------------------------------------------------------------------------
/e2e/scripts/cleanup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | kubectl delete postgresql acid-minimal-cluster
3 | kubectl delete deployments -l application=db-connection-pooler,cluster-name=acid-minimal-cluster
4 | kubectl delete statefulsets -l application=spilo,cluster-name=acid-minimal-cluster
5 | kubectl delete services -l application=spilo,cluster-name=acid-minimal-cluster
6 | kubectl delete configmap postgres-operator
7 | kubectl delete deployment postgres-operator


--------------------------------------------------------------------------------
/e2e/scripts/get_logs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | kubectl logs $(kubectl get pods -l name=postgres-operator --field-selector status.phase=Running -o jsonpath='{.items..metadata.name}')
3 | 


--------------------------------------------------------------------------------
/e2e/scripts/watch_objects.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/bash
 2 | 
 3 | watch -c "
 4 | kubectl get postgresql --all-namespaces
 5 | echo
 6 | echo -n 'Rolling upgrade pending: '
 7 | kubectl get pods -o jsonpath='{.items[].metadata.annotations.zalando-postgres-operator-rolling-update-required}'
 8 | echo
 9 | echo
10 | echo 'Pods'
11 | kubectl get pods -l application=spilo -o wide --all-namespaces
12 | echo
13 | kubectl get pods -l application=db-connection-pooler -o wide --all-namespaces
14 | echo
15 | echo 'Statefulsets'
16 | kubectl get statefulsets --all-namespaces
17 | echo
18 | echo 'Deployments'
19 | kubectl get deployments --all-namespaces -l application=db-connection-pooler
20 | kubectl get deployments --all-namespaces -l application=postgres-operator
21 | echo
22 | echo
23 | echo 'Step from operator deployment'
24 | kubectl get pods -l name=postgres-operator -o jsonpath='{.items..metadata.annotations.step}'
25 | echo
26 | echo
27 | echo 'Spilo Image in statefulset'
28 | kubectl get pods -l application=spilo -o jsonpath='{.items..spec.containers..image}'
29 | echo
30 | echo
31 | echo 'Queue Status'
32 | kubectl exec -it \$(kubectl get pods -l name=postgres-operator -o jsonpath='{.items..metadata.name}') -- curl localhost:8080/workers/all/status/
33 | echo"


--------------------------------------------------------------------------------
/e2e/tests/__init__.py:
--------------------------------------------------------------------------------
1 | # This version is replaced during release process.
2 | __version__ = '2019.0.dev1'
3 | 


--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
 1 | module github.com/zalando/postgres-operator
 2 | 
 3 | go 1.23.4
 4 | 
 5 | require (
 6 | 	github.com/aws/aws-sdk-go v1.53.8
 7 | 	github.com/golang/mock v1.6.0
 8 | 	github.com/lib/pq v1.10.9
 9 | 	github.com/motomux/pretty v0.0.0-20161209205251-b2aad2c9a95d
10 | 	github.com/pkg/errors v0.9.1
11 | 	github.com/r3labs/diff v1.1.0
12 | 	github.com/sirupsen/logrus v1.9.3
13 | 	github.com/stretchr/testify v1.9.0
14 | 	golang.org/x/crypto v0.31.0
15 | 	golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3
16 | 	gopkg.in/yaml.v2 v2.4.0
17 | 	k8s.io/api v0.30.4
18 | 	k8s.io/apiextensions-apiserver v0.25.9
19 | 	k8s.io/apimachinery v0.30.4
20 | 	k8s.io/client-go v0.30.4
21 | 	k8s.io/code-generator v0.25.9
22 | )
23 | 
24 | require (
25 | 	github.com/Masterminds/semver v1.5.0
26 | 	github.com/davecgh/go-spew v1.1.1 // indirect
27 | 	github.com/emicklei/go-restful/v3 v3.11.0 // indirect
28 | 	github.com/evanphx/json-patch v4.12.0+incompatible // indirect
29 | 	github.com/go-logr/logr v1.4.1 // indirect
30 | 	github.com/go-openapi/jsonpointer v0.19.6 // indirect
31 | 	github.com/go-openapi/jsonreference v0.20.2 // indirect
32 | 	github.com/go-openapi/swag v0.22.3 // indirect
33 | 	github.com/gogo/protobuf v1.3.2 // indirect
34 | 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
35 | 	github.com/golang/protobuf v1.5.4 // indirect
36 | 	github.com/google/gnostic-models v0.6.8 // indirect
37 | 	github.com/google/go-cmp v0.6.0 // indirect
38 | 	github.com/google/gofuzz v1.2.0 // indirect
39 | 	github.com/google/uuid v1.3.0 // indirect
40 | 	github.com/gorilla/websocket v1.5.0 // indirect
41 | 	github.com/imdario/mergo v0.3.6 // indirect
42 | 	github.com/jmespath/go-jmespath v0.4.0 // indirect
43 | 	github.com/josharian/intern v1.0.0 // indirect
44 | 	github.com/json-iterator/go v1.1.12 // indirect
45 | 	github.com/kr/text v0.2.0 // indirect
46 | 	github.com/mailru/easyjson v0.7.7 // indirect
47 | 	github.com/moby/spdystream v0.2.0 // indirect
48 | 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
49 | 	github.com/modern-go/reflect2 v1.0.2 // indirect
50 | 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
51 | 	github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
52 | 	github.com/pmezard/go-difflib v1.0.0 // indirect
53 | 	github.com/spf13/pflag v1.0.5 // indirect
54 | 	golang.org/x/mod v0.17.0 // indirect
55 | 	golang.org/x/net v0.25.0 // indirect
56 | 	golang.org/x/oauth2 v0.10.0 // indirect
57 | 	golang.org/x/sync v0.10.0 // indirect
58 | 	golang.org/x/sys v0.28.0 // indirect
59 | 	golang.org/x/term v0.27.0 // indirect
60 | 	golang.org/x/text v0.21.0 // indirect
61 | 	golang.org/x/time v0.3.0 // indirect
62 | 	golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
63 | 	google.golang.org/appengine v1.6.7 // indirect
64 | 	google.golang.org/protobuf v1.33.0 // indirect
65 | 	gopkg.in/inf.v0 v0.9.1 // indirect
66 | 	gopkg.in/yaml.v3 v3.0.1 // indirect
67 | 	k8s.io/gengo v0.0.0-20220902162205-c0856e24416d // indirect
68 | 	k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect
69 | 	k8s.io/klog/v2 v2.120.1 // indirect
70 | 	k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
71 | 	k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
72 | 	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
73 | 	sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
74 | 	sigs.k8s.io/yaml v1.3.0 // indirect
75 | )
76 | 


--------------------------------------------------------------------------------
/hack/custom-boilerplate.go.txt:
--------------------------------------------------------------------------------
 1 | /*
 2 | Copyright YEAR Compose, Zalando SE
 3 | 
 4 | Permission is hereby granted, free of charge, to any person obtaining a copy
 5 | of this software and associated documentation files (the "Software"), to deal
 6 | in the Software without restriction, including without limitation the rights
 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 8 | copies of the Software, and to permit persons to whom the Software is
 9 | furnished to do so, subject to the following conditions:
10 | 
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 | 
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | SOFTWARE.
21 | */
22 | 


--------------------------------------------------------------------------------
/hack/tools.go:
--------------------------------------------------------------------------------
 1 | // +build tools
 2 | 
 3 | /*
 4 | Copyright 2019 The Kubernetes Authors.
 5 | Licensed under the Apache License, Version 2.0 (the "License");
 6 | you may not use this file except in compliance with the License.
 7 | You may obtain a copy of the License at
 8 |     http://www.apache.org/licenses/LICENSE-2.0
 9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 | */
15 | 
16 | // This package imports things required by build scripts, to force `go mod` to see them as dependencies
17 | package tools
18 | 
19 | import _ "k8s.io/code-generator"
20 | 


--------------------------------------------------------------------------------
/hack/update-codegen.sh:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/env bash
 2 | 
 3 | set -o errexit
 4 | set -o nounset
 5 | set -o pipefail
 6 | 
 7 | GENERATED_PACKAGE_ROOT="github.com"
 8 | OPERATOR_PACKAGE_ROOT="${GENERATED_PACKAGE_ROOT}/zalando/postgres-operator"
 9 | SCRIPT_ROOT=$(dirname ${BASH_SOURCE})/..
10 | TARGET_CODE_DIR=${1-${SCRIPT_ROOT}/pkg}
11 | CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo "${GOPATH}"/src/k8s.io/code-generator)}
12 | 
13 | cleanup() {
14 |     rm -rf "${GENERATED_PACKAGE_ROOT}"
15 | }
16 | trap "cleanup" EXIT SIGINT
17 | 
18 | bash "${CODEGEN_PKG}/generate-groups.sh" client,deepcopy,informer,lister \
19 |   "${OPERATOR_PACKAGE_ROOT}/pkg/generated" "${OPERATOR_PACKAGE_ROOT}/pkg/apis" \
20 |   "acid.zalan.do:v1 zalando.org:v1" \
21 |   --go-header-file "${SCRIPT_ROOT}"/hack/custom-boilerplate.go.txt \
22 |   -o ./
23 | 
24 | cp -r "${OPERATOR_PACKAGE_ROOT}"/pkg/* "${TARGET_CODE_DIR}"
25 | 
26 | cleanup
27 | 


--------------------------------------------------------------------------------
/hack/verify-codegen.sh:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/env bash
 2 | 
 3 | set -o errexit
 4 | set -o nounset
 5 | set -o pipefail
 6 | 
 7 | SCRIPT_ROOT=$(dirname "${BASH_SOURCE}")/..
 8 | DIFFROOT="${SCRIPT_ROOT}/pkg"
 9 | TMP_DIFFROOT="${SCRIPT_ROOT}/_tmp/pkg"
10 | _tmp="${SCRIPT_ROOT}/_tmp"
11 | 
12 | cleanup() {
13 |     rm -rf "${_tmp}"
14 | }
15 | trap "cleanup" EXIT SIGINT
16 | 
17 | cleanup
18 | 
19 | mkdir -p "${TMP_DIFFROOT}"
20 | cp -a "${DIFFROOT}"/* "${TMP_DIFFROOT}"
21 | 
22 | "${SCRIPT_ROOT}/hack/update-codegen.sh" "${TMP_DIFFROOT}"
23 | echo "diffing ${DIFFROOT} against freshly generated codegen"
24 | ret=0
25 | diff -Naupr "${DIFFROOT}" "${TMP_DIFFROOT}" || ret=$?
26 | if [[ $ret -eq 0 ]]
27 | then
28 |     echo "${DIFFROOT} up to date."
29 | else
30 |     echo "${DIFFROOT} is out of date. Please run 'make codegen'"
31 |     exit 1
32 | fi
33 | 


--------------------------------------------------------------------------------
/kubectl-pg/build.sh:
--------------------------------------------------------------------------------
1 | 
2 | VERSION=1.0
3 | sed -i "s/KubectlPgVersion string = \"[^\"]*\"/KubectlPgVersion string = \"${VERSION}\"/" cmd/version.go
4 | go install


--------------------------------------------------------------------------------
/kubectl-pg/cmd/check.go:
--------------------------------------------------------------------------------
 1 | /*
 2 | Copyright © 2019 Vineeth Pothulapati <vineethpothulapati@outlook.com>
 3 | 
 4 | Permission is hereby granted, free of charge, to any person obtaining a copy
 5 | of this software and associated documentation files (the "Software"), to deal
 6 | in the Software without restriction, including without limitation the rights
 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 8 | copies of the Software, and to permit persons to whom the Software is
 9 | furnished to do so, subject to the following conditions:
10 | 
11 | The above copyright notice and this permission notice shall be included in
12 | all copies or substantial portions of the Software.
13 | 
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | THE SOFTWARE.
21 | */
22 | 
23 | package cmd
24 | 
25 | import (
26 | 	"context"
27 | 	"fmt"
28 | 	"log"
29 | 
30 | 	"github.com/spf13/cobra"
31 | 	postgresConstants "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
32 | 	v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
33 | 	apiextv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
34 | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
35 | )
36 | 
37 | // checkCmd represent kubectl pg check.
38 | var checkCmd = &cobra.Command{
39 | 	Use:   "check",
40 | 	Short: "Checks the Postgres operator is installed in the k8s cluster",
41 | 	Long: `Checks that the Postgres CRD is registered in a k8s cluster.
42 | This means that the operator pod was able to start normally.`,
43 | 	Run: func(cmd *cobra.Command, args []string) {
44 | 		check()
45 | 	},
46 | 	Example: `
47 | kubectl pg check
48 | `,
49 | }
50 | 
51 | // check validates postgresql CRD registered or not.
52 | func check() *v1.CustomResourceDefinition {
53 | 	config := getConfig()
54 | 	apiExtClient, err := apiextv1.NewForConfig(config)
55 | 	if err != nil {
56 | 		log.Fatal(err)
57 | 	}
58 | 
59 | 	crdInfo, err := apiExtClient.CustomResourceDefinitions().Get(context.TODO(), postgresConstants.PostgresCRDResouceName, metav1.GetOptions{})
60 | 	if err != nil {
61 | 		log.Fatal(err)
62 | 	}
63 | 
64 | 	if crdInfo.Name == postgresConstants.PostgresCRDResouceName {
65 | 		fmt.Printf("Postgres Operator is installed in the k8s cluster.\n")
66 | 	} else {
67 | 		fmt.Printf("Postgres Operator is not installed in the k8s cluster.\n")
68 | 	}
69 | 	return crdInfo
70 | }
71 | 
72 | func init() {
73 | 	rootCmd.AddCommand(checkCmd)
74 | }
75 | 


--------------------------------------------------------------------------------
/kubectl-pg/cmd/create.go:
--------------------------------------------------------------------------------
 1 | /*
 2 | Copyright © 2019 Vineeth Pothulapati <vineethpothulapati@outlook.com>
 3 | 
 4 | Permission is hereby granted, free of charge, to any person obtaining a copy
 5 | of this software and associated documentation files (the "Software"), to deal
 6 | in the Software without restriction, including without limitation the rights
 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 8 | copies of the Software, and to permit persons to whom the Software is
 9 | furnished to do so, subject to the following conditions:
10 | 
11 | The above copyright notice and this permission notice shall be included in
12 | all copies or substantial portions of the Software.
13 | 
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | THE SOFTWARE.
21 | */
22 | 
23 | package cmd
24 | 
25 | import (
26 | 	"context"
27 | 	"fmt"
28 | 	"log"
29 | 	"os"
30 | 
31 | 	"github.com/spf13/cobra"
32 | 	v1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1"
33 | 	PostgresqlLister "github.com/zalando/postgres-operator/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1"
34 | 	"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/scheme"
35 | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
36 | )
37 | 
38 | // createCmd kubectl pg create.
39 | var createCmd = &cobra.Command{
40 | 	Use:   "create",
41 | 	Short: "Creates postgres object using manifest file",
42 | 	Long:  `Creates postgres custom resource objects from a manifest file.`,
43 | 	Run: func(cmd *cobra.Command, args []string) {
44 | 		fileName, _ := cmd.Flags().GetString("file")
45 | 		create(fileName)
46 | 	},
47 | 	Example: `
48 | kubectl pg create -f cluster-manifest.yaml
49 | `,
50 | }
51 | 
52 | // Create postgresql resources.
53 | func create(fileName string) {
54 | 	config := getConfig()
55 | 	postgresConfig, err := PostgresqlLister.NewForConfig(config)
56 | 	if err != nil {
57 | 		log.Fatal(err)
58 | 	}
59 | 	ymlFile, err := os.ReadFile(fileName)
60 | 	if err != nil {
61 | 		log.Fatal(err)
62 | 	}
63 | 
64 | 	decode := scheme.Codecs.UniversalDeserializer().Decode
65 | 	obj, _, err := decode([]byte(ymlFile), nil, &v1.Postgresql{})
66 | 	if err != nil {
67 | 		log.Fatal(err)
68 | 	}
69 | 
70 | 	postgresSql := obj.(*v1.Postgresql)
71 | 	_, err = postgresConfig.Postgresqls(postgresSql.Namespace).Create(context.TODO(), postgresSql, metav1.CreateOptions{})
72 | 	if err != nil {
73 | 		log.Fatal(err)
74 | 	}
75 | 
76 | 	fmt.Printf("postgresql %s created.\n", postgresSql.Name)
77 | }
78 | 
79 | func init() {
80 | 	createCmd.Flags().StringP("file", "f", "", "manifest file with the cluster definition.")
81 | 	rootCmd.AddCommand(createCmd)
82 | }
83 | 


--------------------------------------------------------------------------------
/kubectl-pg/cmd/root.go:
--------------------------------------------------------------------------------
 1 | /*
 2 | Copyright © 2019 Vineeth Pothulapati <vineethpothulapati@outlook.com>
 3 | 
 4 | Permission is hereby granted, free of charge, to any person obtaining a copy
 5 | of this software and associated documentation files (the "Software"), to deal
 6 | in the Software without restriction, including without limitation the rights
 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 8 | copies of the Software, and to permit persons to whom the Software is
 9 | furnished to do so, subject to the following conditions:
10 | 
11 | The above copyright notice and this permission notice shall be included in
12 | all copies or substantial portions of the Software.
13 | 
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | THE SOFTWARE.
21 | */
22 | 
23 | package cmd
24 | 
25 | import (
26 | 	"fmt"
27 | 	"os"
28 | 
29 | 	"github.com/spf13/cobra"
30 | 	"github.com/spf13/viper"
31 | )
32 | 
33 | var rootCmd = &cobra.Command{
34 | 	Use:   "kubectl-pg",
35 | 	Short: "kubectl plugin for the Zalando Postgres operator.",
36 | 	Long:  `kubectl pg plugin for interaction with Zalando postgres operator.`,
37 | }
38 | 
39 | // Execute adds all child commands to the root command and sets flags appropriately.
40 | // This is called by main.main(). It only needs to happen once to the rootCmd.
41 | func Execute() {
42 | 	if err := rootCmd.Execute(); err != nil {
43 | 		fmt.Println(err)
44 | 		os.Exit(1)
45 | 	}
46 | }
47 | 
48 | func init() {
49 | 	viper.SetDefault("author", "Vineeth Pothulapati <vineethpothulapati@outlook.com>")
50 | 	viper.SetDefault("license", "mit")
51 | }
52 | 


--------------------------------------------------------------------------------
/kubectl-pg/cmd/version.go:
--------------------------------------------------------------------------------
 1 | /*
 2 | Copyright © 2019 Vineeth Pothulapati <vineethpothulapati@outlook.com>
 3 | 
 4 | Permission is hereby granted, free of charge, to any person obtaining a copy
 5 | of this software and associated documentation files (the "Software"), to deal
 6 | in the Software without restriction, including without limitation the rights
 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 8 | copies of the Software, and to permit persons to whom the Software is
 9 | furnished to do so, subject to the following conditions:
10 | 
11 | The above copyright notice and this permission notice shall be included in
12 | all copies or substantial portions of the Software.
13 | 
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | THE SOFTWARE.
21 | */
22 | 
23 | package cmd
24 | 
25 | import (
26 | 	"fmt"
27 | 	"log"
28 | 	"strings"
29 | 
30 | 	"github.com/spf13/cobra"
31 | 	"k8s.io/client-go/kubernetes"
32 | )
33 | 
34 | var KubectlPgVersion string = "1.0"
35 | 
36 | // versionCmd represents the version command
37 | var versionCmd = &cobra.Command{
38 | 	Use:   "version",
39 | 	Short: "version of kubectl-pg & postgres-operator",
40 | 	Long:  `version of kubectl-pg and current running postgres-operator`,
41 | 	Run: func(cmd *cobra.Command, args []string) {
42 | 		namespace, err := cmd.Flags().GetString("namespace")
43 | 		if err != nil {
44 | 			log.Fatal(err)
45 | 		}
46 | 		version(namespace)
47 | 	},
48 | 	Example: `
49 | #Lists the version of kubectl pg plugin and postgres operator in current namespace
50 | kubectl pg version
51 | 
52 | #Lists the version of kubectl pg plugin and postgres operator in provided namespace
53 | kubectl pg version -n namespace01
54 | `,
55 | }
56 | 
57 | func version(namespace string) {
58 | 	fmt.Printf("kubectl-pg: %s\n", KubectlPgVersion)
59 | 
60 | 	config := getConfig()
61 | 	client, err := kubernetes.NewForConfig(config)
62 | 	if err != nil {
63 | 		log.Fatal(err)
64 | 	}
65 | 
66 | 	operatorDeployment := getPostgresOperator(client)
67 | 	if operatorDeployment.Name == "" {
68 | 		log.Fatal("make sure zalando's postgres operator is running")
69 | 	}
70 | 	operatorImage := operatorDeployment.Spec.Template.Spec.Containers[0].Image
71 | 	imageDetails := strings.Split(operatorImage, ":")
72 | 	imageSplit := len(imageDetails)
73 | 	imageVersion := imageDetails[imageSplit-1]
74 | 	fmt.Printf("Postgres-Operator: %s\n", imageVersion)
75 | }
76 | 
77 | func init() {
78 | 	rootCmd.AddCommand(versionCmd)
79 | 	versionCmd.Flags().StringP("namespace", "n", DefaultNamespace, "provide the namespace.")
80 | }
81 | 


--------------------------------------------------------------------------------
/kubectl-pg/main.go:
--------------------------------------------------------------------------------
 1 | /*
 2 | Copyright © 2019 Vineeth Pothulapati <vineethpothulapati@outlook.com>
 3 | 
 4 | Permission is hereby granted, free of charge, to any person obtaining a copy
 5 | of this software and associated documentation files (the "Software"), to deal
 6 | in the Software without restriction, including without limitation the rights
 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 8 | copies of the Software, and to permit persons to whom the Software is
 9 | furnished to do so, subject to the following conditions:
10 | 
11 | The above copyright notice and this permission notice shall be included in
12 | all copies or substantial portions of the Software.
13 | 
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | THE SOFTWARE.
21 | */
22 | 
23 | package main
24 | 
25 | import (
26 | 	"github.com/zalando/postgres-operator/kubectl-pg/cmd"
27 | )
28 | 
29 | func main() {
30 | 	cmd.Execute()
31 | }
32 | 


--------------------------------------------------------------------------------
/logical-backup/Dockerfile:
--------------------------------------------------------------------------------
 1 | ARG BASE_IMAGE=registry.opensource.zalan.do/library/ubuntu-22.04:latest
 2 | FROM ${BASE_IMAGE}
 3 | LABEL maintainer="Team ACID @ Zalando <team-acid@zalando.de>"
 4 | 
 5 | SHELL ["/bin/bash", "-o", "pipefail", "-c"]
 6 | RUN apt-get update     \
 7 |     && apt-get install --no-install-recommends -y \
 8 |         apt-utils \
 9 |         ca-certificates \
10 |         lsb-release \
11 |         pigz \
12 |         python3-pip \
13 |         python3-setuptools \
14 |         curl \
15 |         jq \
16 |         gnupg \
17 |         gcc \
18 |         libffi-dev \
19 |     && curl -sL https://aka.ms/InstallAzureCLIDeb | bash \
20 |     && pip3 install --upgrade pip \
21 |     && pip3 install --no-cache-dir awscli --upgrade \
22 |     && pip3 install --no-cache-dir gsutil --upgrade \
23 |     && echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
24 |     && cat /etc/apt/sources.list.d/pgdg.list \
25 |     && curl --silent https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
26 |     && apt-get update \
27 |     && apt-get install --no-install-recommends -y  \
28 |         postgresql-client-17  \
29 |         postgresql-client-16  \
30 |         postgresql-client-15  \
31 |         postgresql-client-14  \
32 |         postgresql-client-13  \
33 |     && apt-get clean \
34 |     && rm -rf /var/lib/apt/lists/*
35 | 
36 | COPY dump.sh ./
37 | 
38 | ENV PG_DIR=/usr/lib/postgresql
39 | 
40 | ENTRYPOINT ["/dump.sh"]
41 | 


--------------------------------------------------------------------------------
/manifests/api-service.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: v1
 2 | kind: Service
 3 | metadata:
 4 |   name: postgres-operator
 5 | spec:
 6 |   type: ClusterIP
 7 |   ports:
 8 |   - port: 8080
 9 |     protocol: TCP
10 |     targetPort: 8080
11 |   selector:
12 |     name: postgres-operator
13 | 


--------------------------------------------------------------------------------
/manifests/custom-team-membership.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: "acid.zalan.do/v1"
 2 | kind: PostgresTeam
 3 | metadata:
 4 |   name: custom-team-membership
 5 | spec:
 6 |   additionalSuperuserTeams:
 7 |     acid:
 8 |     - "postgres_superusers"
 9 |   additionalTeams:
10 |     acid: []
11 |   additionalMembers:
12 |     acid:
13 |     - "elephant"
14 | 


--------------------------------------------------------------------------------
/manifests/e2e-storage-class.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: storage.k8s.io/v1
2 | kind: StorageClass
3 | metadata:
4 |   name: standard
5 |   annotations:
6 |     storageclass.kubernetes.io/is-default-class: "true"
7 | provisioner: kubernetes.io/host-path
8 | 


--------------------------------------------------------------------------------
/manifests/fake-teams-api.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: apps/v1
 2 | kind: Deployment
 3 | metadata:
 4 |   name: fake-teams-api
 5 | spec:
 6 |   replicas: 1
 7 |   selector:
 8 |     matchLabels:
 9 |       name: fake-teams-api
10 |   template:
11 |     metadata:
12 |       labels:
13 |         name: fake-teams-api
14 |     spec:
15 |       containers:
16 |       - name: fake-teams-api
17 |         image: ikitiki/fake-teams-api:latest
18 | 
19 | ---
20 | 
21 | apiVersion: v1
22 | kind: Service
23 | metadata:
24 |   name: fake-teams-api
25 | spec:
26 |   selector:
27 |     name: fake-teams-api
28 |   ports:
29 |   - name: server
30 |     port: 80
31 |     protocol: TCP
32 |     targetPort: 80
33 |   type: NodePort
34 | 
35 | ---
36 | 
37 | apiVersion: v1
38 | kind: Secret
39 | metadata:
40 |   name: postgresql-operator
41 |   namespace: default
42 | type: Opaque
43 | data:
44 |   read-only-token-secret: dGVzdHRva2Vu
45 |   read-only-token-type: QmVhcmVy
46 | 


--------------------------------------------------------------------------------
/manifests/fes.crd.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: apiextensions.k8s.io/v1
 2 | kind: CustomResourceDefinition
 3 | metadata:
 4 |   name: fabriceventstreams.zalando.org
 5 | spec:
 6 |   group: zalando.org
 7 |   names:
 8 |     kind: FabricEventStream
 9 |     listKind: FabricEventStreamList
10 |     plural: fabriceventstreams
11 |     singular: fabriceventstream
12 |     shortNames:
13 |     - fes
14 |     categories:
15 |     - all
16 |   scope: Namespaced
17 |   versions:
18 |   - name: v1
19 |     served: true
20 |     storage: true
21 |     schema:
22 |       openAPIV3Schema:
23 |         type: object
24 | 


--------------------------------------------------------------------------------
/manifests/infrastructure-roles-configmap.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: v1
 2 | kind: ConfigMap
 3 | metadata:
 4 |   name: postgresql-infrastructure-roles
 5 | data:
 6 |   batman: |
 7 |     inrole: [admin]  # following roles will be assigned to the new user
 8 |     user_flags:
 9 |       - createdb
10 |     db_parameters:  # db parameters, applyed for this particular user
11 |       log_statement: all
12 | 


--------------------------------------------------------------------------------
/manifests/infrastructure-roles-new.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: v1
 2 | data:
 3 |   # infrastructure role definition in the new format
 4 |   # robot_zmon_acid_monitoring_new
 5 |   user: cm9ib3Rfem1vbl9hY2lkX21vbml0b3JpbmdfbmV3
 6 |   # foobar_new
 7 |   password: Zm9vYmFyX25ldw==
 8 | kind: Secret
 9 | metadata:
10 |   name: postgresql-infrastructure-roles-new
11 | type: Opaque
12 | 


--------------------------------------------------------------------------------
/manifests/infrastructure-roles.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: v1
 2 | data:
 3 |   # required format (w/o quotes): 'propertyNumber: value'
 4 |   # allowed properties: 'user', 'password', 'inrole'
 5 |   # numbers >= 1 are mandatory
 6 |   # alternatively, supply the user: password pairs and
 7 |   # provide other options in the configmap.
 8 |   # robot_zmon_acid_monitoring
 9 |   user1: cm9ib3Rfem1vbl9hY2lkX21vbml0b3Jpbmc=
10 |   # foobar
11 |   password1: Zm9vYmFy
12 |   # robot_zmon
13 |   inrole1: cm9ib3Rfem1vbg==
14 |   # testuser
15 |   user2: dGVzdHVzZXI=
16 |   # testpassword
17 |   password2: dGVzdHBhc3N3b3Jk
18 |   # user batman with the password justice
19 |   # look for other fields in the infrastructure roles configmap
20 |   batman: anVzdGljZQ==
21 | kind: Secret
22 | metadata:
23 |   name: postgresql-infrastructure-roles
24 | type: Opaque
25 | 


--------------------------------------------------------------------------------
/manifests/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 | resources:
4 | - configmap.yaml
5 | - operator-service-account-rbac.yaml
6 | - postgres-operator.yaml
7 | - api-service.yaml
8 | 


--------------------------------------------------------------------------------
/manifests/minimal-fake-pooler-deployment.yaml:
--------------------------------------------------------------------------------
 1 | # will not run but is good enough for tests to fail
 2 | apiVersion: apps/v1
 3 | kind: Deployment
 4 | metadata:
 5 |   name: acid-minimal-cluster-pooler
 6 |   labels:
 7 |     application: db-connection-pooler
 8 |     connection-pooler: acid-minimal-cluster-pooler
 9 | spec:
10 |   replicas: 1
11 |   selector:
12 |     matchLabels:
13 |       application: db-connection-pooler
14 |       connection-pooler: acid-minimal-cluster-pooler
15 |       cluster-name: acid-minimal-cluster
16 |   template:
17 |     metadata:
18 |       labels:
19 |         application: db-connection-pooler
20 |         connection-pooler: acid-minimal-cluster-pooler
21 |         cluster-name: acid-minimal-cluster
22 |     spec:
23 |       serviceAccountName: postgres-operator
24 |       containers:
25 |       - name: postgres-operator
26 |         image: registry.opensource.zalan.do/acid/pgbouncer:master-32
27 |         imagePullPolicy: IfNotPresent
28 |         resources:
29 |           requests:
30 |             cpu: 100m
31 |             memory: 250Mi
32 |           limits:
33 |             cpu: 500m
34 |             memory: 500Mi
35 |         env: []
36 | 


--------------------------------------------------------------------------------
/manifests/minimal-postgres-lowest-version-manifest.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: "acid.zalan.do/v1"
 2 | kind: postgresql
 3 | metadata:
 4 |   name: acid-upgrade-test
 5 | spec:
 6 |   teamId: "acid"
 7 |   volume:
 8 |     size: 1Gi
 9 |   numberOfInstances: 2
10 |   users:
11 |     zalando:  # database owner
12 |     - superuser
13 |     - createdb
14 |     foo_user: []  # role for application foo
15 |   databases:
16 |     foo: zalando  # dbname: owner
17 |   preparedDatabases:
18 |     bar: {}
19 |   postgresql:
20 |     version: "13"
21 | 


--------------------------------------------------------------------------------
/manifests/minimal-postgres-manifest.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: "acid.zalan.do/v1"
 2 | kind: postgresql
 3 | metadata:
 4 |   name: acid-minimal-cluster
 5 | spec:
 6 |   teamId: "acid"
 7 |   volume:
 8 |     size: 1Gi
 9 |   numberOfInstances: 2
10 |   users:
11 |     zalando:  # database owner
12 |     - superuser
13 |     - createdb
14 |     foo_user: []  # role for application foo
15 |   databases:
16 |     foo: zalando  # dbname: owner
17 |   preparedDatabases:
18 |     bar: {}
19 |   postgresql:
20 |     version: "17"
21 | 


--------------------------------------------------------------------------------
/manifests/platform-credentials.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: "zalando.org/v1"
 2 | kind: PlatformCredentialsSet
 3 | metadata:
 4 |   name: postgresql-operator
 5 | spec:
 6 |   application: postgresql-operator
 7 |   tokens:
 8 |     read-only:
 9 |       privileges:
10 |     cluster-registry-rw:
11 |       privileges:
12 |     cluster-rw:
13 |       privileges:
14 | 


--------------------------------------------------------------------------------
/manifests/postgres-operator.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: apps/v1
 2 | kind: Deployment
 3 | metadata:
 4 |   name: postgres-operator
 5 |   labels:
 6 |     application: postgres-operator
 7 | spec:
 8 |   replicas: 1
 9 |   strategy:
10 |     type: "Recreate"
11 |   selector:
12 |     matchLabels:
13 |       name: postgres-operator
14 |   template:
15 |     metadata:
16 |       labels:
17 |         name: postgres-operator
18 |     spec:
19 |       serviceAccountName: postgres-operator
20 |       containers:
21 |       - name: postgres-operator
22 |         image: ghcr.io/zalando/postgres-operator:v1.14.0
23 |         imagePullPolicy: IfNotPresent
24 |         resources:
25 |           requests:
26 |             cpu: 100m
27 |             memory: 250Mi
28 |           limits:
29 |             cpu: 500m
30 |             memory: 500Mi
31 |         securityContext:
32 |           runAsUser: 1000
33 |           runAsNonRoot: true
34 |           readOnlyRootFilesystem: true
35 |           allowPrivilegeEscalation: false
36 |         env:
37 |         # provided additional ENV vars can overwrite individual config map entries
38 |         - name: CONFIG_MAP_NAME
39 |           value: "postgres-operator"
40 |         # In order to use the CRD OperatorConfiguration instead, uncomment these lines and comment out the two lines above
41 |         # - name: POSTGRES_OPERATOR_CONFIGURATION_OBJECT
42 |         #  value: postgresql-operator-default-configuration
43 |         # Define an ID to isolate controllers from each other
44 |         # - name: CONTROLLER_ID
45 |         #   value: "second-operator"
46 | 


--------------------------------------------------------------------------------
/manifests/postgres-pod-priority-class.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: scheduling.k8s.io/v1
 2 | description: 'This priority class must be used only for databases controlled by the
 3 |   Postgres operator'
 4 | kind: PriorityClass
 5 | metadata:
 6 |   labels:
 7 |     application: postgres-operator
 8 |   name: postgres-pod-priority
 9 | preemptionPolicy: PreemptLowerPriority
10 | globalDefault: false
11 | value: 1000000
12 | 


--------------------------------------------------------------------------------
/manifests/postgresteam.crd.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: apiextensions.k8s.io/v1
 2 | kind: CustomResourceDefinition
 3 | metadata:
 4 |   name: postgresteams.acid.zalan.do
 5 | spec:
 6 |   group: acid.zalan.do
 7 |   names:
 8 |     kind: PostgresTeam
 9 |     listKind: PostgresTeamList
10 |     plural: postgresteams
11 |     singular: postgresteam
12 |     shortNames:
13 |     - pgteam
14 |     categories:
15 |     - all
16 |   scope: Namespaced
17 |   versions:
18 |   - name: v1
19 |     served: true
20 |     storage: true
21 |     subresources:
22 |       status: {}
23 |     schema:
24 |       openAPIV3Schema:
25 |         type: object
26 |         required:
27 |           - kind
28 |           - apiVersion
29 |           - spec
30 |         properties:
31 |           kind:
32 |             type: string
33 |             enum:
34 |               - PostgresTeam
35 |           apiVersion:
36 |             type: string
37 |             enum:
38 |               - acid.zalan.do/v1
39 |           spec:
40 |             type: object
41 |             properties:
42 |               additionalSuperuserTeams:
43 |                 type: object
44 |                 description: "Map for teamId and associated additional superuser teams"
45 |                 additionalProperties:
46 |                   type: array
47 |                   nullable: true
48 |                   description: "List of teams to become Postgres superusers"
49 |                   items:
50 |                     type: string
51 |               additionalTeams:
52 |                 type: object
53 |                 description: "Map for teamId and associated additional teams"
54 |                 additionalProperties:
55 |                   type: array
56 |                   nullable: true
57 |                   description: "List of teams whose members will also be added to the Postgres cluster"
58 |                   items:
59 |                     type: string
60 |               additionalMembers:
61 |                 type: object
62 |                 description: "Map for teamId and associated additional users"
63 |                 additionalProperties:
64 |                   type: array
65 |                   nullable: true
66 |                   description: "List of users who will also be added to the Postgres cluster"
67 |                   items:
68 |                     type: string
69 | 


--------------------------------------------------------------------------------
/manifests/standby-manifest.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: "acid.zalan.do/v1"
 2 | kind: postgresql
 3 | metadata:
 4 |   name: acid-standby-cluster
 5 | spec:
 6 |   teamId: "acid"
 7 |   volume:
 8 |     size: 1Gi
 9 |   numberOfInstances: 1
10 |   postgresql:
11 |     version: "17"
12 |   # Make this a standby cluster and provide either the s3 bucket path of source cluster or the remote primary host for continuous streaming.
13 |   standby:
14 |     # s3_wal_path: "s3://mybucket/spilo/acid-minimal-cluster/abcd1234-2a4b-4b2a-8c9c-c1234defg567/wal/14/"
15 |     standby_host: "acid-minimal-cluster.default"
16 |     # standby_port: "5432"
17 | 


--------------------------------------------------------------------------------
/manifests/user-facing-clusterroles.yaml:
--------------------------------------------------------------------------------
 1 | apiVersion: rbac.authorization.k8s.io/v1
 2 | kind: ClusterRole
 3 | metadata:
 4 |   labels:
 5 |     rbac.authorization.k8s.io/aggregate-to-admin: "true"
 6 |   name: zalando-postgres-operator:users:admin
 7 | rules:
 8 | - apiGroups:
 9 |   - acid.zalan.do
10 |   resources:
11 |   - postgresqls
12 |   - postgresqls/status
13 |   verbs:
14 |   - create
15 |   - delete
16 |   - deletecollection
17 |   - get
18 |   - list
19 |   - patch
20 |   - update
21 |   - watch
22 | 
23 | ---
24 | apiVersion: rbac.authorization.k8s.io/v1
25 | kind: ClusterRole
26 | metadata:
27 |   labels:
28 |     rbac.authorization.k8s.io/aggregate-to-edit: "true"
29 |   name: zalando-postgres-operator:users:edit
30 | rules:
31 | - apiGroups:
32 |   - acid.zalan.do
33 |   resources:
34 |   - postgresqls
35 |   verbs:
36 |   - create
37 |   - update
38 |   - patch
39 |   - delete
40 | 
41 | ---
42 | apiVersion: rbac.authorization.k8s.io/v1
43 | kind: ClusterRole
44 | metadata:
45 |   labels:
46 |     rbac.authorization.k8s.io/aggregate-to-view: "true"
47 |   name: zalando-postgres-operator:users:view
48 | rules:
49 | - apiGroups:
50 |   - acid.zalan.do
51 |   resources:
52 |   - postgresqls
53 |   - postgresqls/status
54 |   verbs:
55 |   - get
56 |   - list
57 |   - watch
58 | 


--------------------------------------------------------------------------------
/mkdocs.yml:
--------------------------------------------------------------------------------
 1 | site_name: Postgres Operator
 2 | repo_url: https://github.com/zalando/postgres-operator
 3 | theme: readthedocs
 4 | 
 5 | nav:
 6 |   - Concepts: 'index.md'
 7 |   - Quickstart: 'quickstart.md'
 8 |   - Postgres Operator UI: 'operator-ui.md'
 9 |   - Admin guide: 'administrator.md'
10 |   - User guide: 'user.md'
11 |   - Developer guide: 'developer.md'
12 |   - Reference:
13 |     - Config parameters: 'reference/operator_parameters.md'
14 |     - Manifest parameters: 'reference/cluster_manifest.md'
15 |     - CLI options and environment: 'reference/command_line_and_environment.md'
16 | 


--------------------------------------------------------------------------------
/mocks/mocks.go:
--------------------------------------------------------------------------------
1 | package mocks
2 | 


--------------------------------------------------------------------------------
/pkg/apis/acid.zalan.do/register.go:
--------------------------------------------------------------------------------
1 | package acidzalando
2 | 
3 | const (
4 | 	// GroupName is the group name for the operator CRDs
5 | 	GroupName = "acid.zalan.do"
6 | )
7 | 


--------------------------------------------------------------------------------
/pkg/apis/acid.zalan.do/v1/const.go:
--------------------------------------------------------------------------------
 1 | package v1
 2 | 
 3 | // ClusterStatusUnknown etc : status of a Postgres cluster known to the operator
 4 | const (
 5 | 	ClusterStatusUnknown      = ""
 6 | 	ClusterStatusCreating     = "Creating"
 7 | 	ClusterStatusUpdating     = "Updating"
 8 | 	ClusterStatusUpdateFailed = "UpdateFailed"
 9 | 	ClusterStatusSyncFailed   = "SyncFailed"
10 | 	ClusterStatusAddFailed    = "CreateFailed"
11 | 	ClusterStatusRunning      = "Running"
12 | 	ClusterStatusInvalid      = "Invalid"
13 | )
14 | 
15 | const (
16 | 	serviceNameMaxLength   = 63
17 | 	clusterNameMaxLength   = serviceNameMaxLength - len("-repl")
18 | 	serviceNameRegexString = `^[a-z]([-a-z0-9]*[a-z0-9])?



    
    

    
    

    
    
    
    

    
    
    
    




    

    
The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
19 | ) 20 | -------------------------------------------------------------------------------- /pkg/apis/acid.zalan.do/v1/doc.go: -------------------------------------------------------------------------------- 1 | // Package v1 is the v1 version of the API. 2 | // +k8s:deepcopy-gen=package,register 3 | 4 | // +groupName=acid.zalan.do 5 | 6 | package v1 7 | -------------------------------------------------------------------------------- /pkg/apis/acid.zalan.do/v1/postgres_team_type.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | import ( 4 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 5 | ) 6 | 7 | // +genclient 8 | // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 9 | 10 | // PostgresTeam defines Custom Resource Definition Object for team management. 11 | type PostgresTeam struct { 12 | metav1.TypeMeta `json:",inline"` 13 | metav1.ObjectMeta `json:"metadata,omitempty"` 14 | 15 | Spec PostgresTeamSpec `json:"spec"` 16 | } 17 | 18 | // PostgresTeamSpec defines the specification for the PostgresTeam TPR. 19 | type PostgresTeamSpec struct { 20 | AdditionalSuperuserTeams map[string][]string `json:"additionalSuperuserTeams,omitempty"` 21 | AdditionalTeams map[string][]string `json:"additionalTeams,omitempty"` 22 | AdditionalMembers map[string][]string `json:"additionalMembers,omitempty"` 23 | } 24 | 25 | // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object 26 | 27 | // PostgresTeamList defines a list of PostgresTeam definitions. 28 | type PostgresTeamList struct { 29 | metav1.TypeMeta `json:",inline"` 30 | metav1.ListMeta `json:"metadata"` 31 | 32 | Items []PostgresTeam `json:"items"` 33 | } 34 | -------------------------------------------------------------------------------- /pkg/apis/acid.zalan.do/v1/register.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | import ( 4 | acidzalando "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do" 5 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 6 | "k8s.io/apimachinery/pkg/runtime" 7 | "k8s.io/apimachinery/pkg/runtime/schema" 8 | ) 9 | 10 | // APIVersion of the `postgresql` and `operator` CRDs 11 | const ( 12 | APIVersion = "v1" 13 | ) 14 | 15 | var ( 16 | // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. 17 | 18 | // SchemeBuilder : An instance of runtime.SchemeBuilder, global for this package 19 | SchemeBuilder runtime.SchemeBuilder 20 | localSchemeBuilder = &SchemeBuilder 21 | //AddToScheme is localSchemeBuilder.AddToScheme 22 | AddToScheme = localSchemeBuilder.AddToScheme 23 | //SchemeGroupVersion has GroupName and APIVersion 24 | SchemeGroupVersion = schema.GroupVersion{Group: acidzalando.GroupName, Version: APIVersion} 25 | ) 26 | 27 | func init() { 28 | // We only register manually written functions here. The registration of the 29 | // generated functions takes place in the generated files. The separation 30 | // makes the code compile even when the generated files are missing. 31 | localSchemeBuilder.Register(addKnownTypes) 32 | } 33 | 34 | // Resource takes an unqualified resource and returns a Group qualified GroupResource 35 | func Resource(resource string) schema.GroupResource { 36 | return SchemeGroupVersion.WithResource(resource).GroupResource() 37 | } 38 | 39 | // Adds the list of known types to api.Scheme. 40 | func addKnownTypes(scheme *runtime.Scheme) error { 41 | // AddKnownType assumes derives the type kind from the type name, which is always uppercase. 42 | // For our CRDs we use lowercase names historically, therefore we have to supply the name separately. 43 | // TODO: User uppercase CRDResourceKind of our types in the next major API version 44 | scheme.AddKnownTypeWithName(SchemeGroupVersion.WithKind("postgresql"), &Postgresql{}) 45 | scheme.AddKnownTypeWithName(SchemeGroupVersion.WithKind("postgresqlList"), &PostgresqlList{}) 46 | scheme.AddKnownTypeWithName(SchemeGroupVersion.WithKind("PostgresTeam"), &PostgresTeam{}) 47 | scheme.AddKnownTypeWithName(SchemeGroupVersion.WithKind("PostgresTeamList"), &PostgresTeamList{}) 48 | scheme.AddKnownTypeWithName(SchemeGroupVersion.WithKind("OperatorConfiguration"), 49 | &OperatorConfiguration{}) 50 | scheme.AddKnownTypeWithName(SchemeGroupVersion.WithKind("OperatorConfigurationList"), 51 | &OperatorConfigurationList{}) 52 | metav1.AddToGroupVersion(scheme, SchemeGroupVersion) 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /pkg/apis/zalando.org/register.go: -------------------------------------------------------------------------------- 1 | package zalando 2 | 3 | const ( 4 | // GroupName is the group name for the operator CRDs 5 | GroupName = "zalando.org" 6 | ) 7 | -------------------------------------------------------------------------------- /pkg/apis/zalando.org/v1/register.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | import ( 4 | "github.com/zalando/postgres-operator/pkg/apis/zalando.org" 5 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 6 | "k8s.io/apimachinery/pkg/runtime" 7 | "k8s.io/apimachinery/pkg/runtime/schema" 8 | "k8s.io/client-go/kubernetes/scheme" 9 | ) 10 | 11 | // APIVersion of the `fabriceventstream` CRD 12 | const ( 13 | APIVersion = "v1" 14 | ) 15 | 16 | var ( 17 | schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) 18 | AddToScheme = schemeBuilder.AddToScheme 19 | ) 20 | 21 | func init() { 22 | err := AddToScheme(scheme.Scheme) 23 | if err != nil { 24 | panic(err) 25 | } 26 | } 27 | 28 | // SchemeGroupVersion is the group version used to register these objects. 29 | var SchemeGroupVersion = schema.GroupVersion{Group: zalando.GroupName, Version: APIVersion} 30 | 31 | // Resource takes an unqualified resource and returns a Group-qualified GroupResource. 32 | func Resource(resource string) schema.GroupResource { 33 | return SchemeGroupVersion.WithResource(resource).GroupResource() 34 | } 35 | 36 | // addKnownTypes adds the set of types defined in this package to the supplied scheme. 37 | func addKnownTypes(scheme *runtime.Scheme) error { 38 | scheme.AddKnownTypes(SchemeGroupVersion, 39 | &FabricEventStream{}, 40 | &FabricEventStreamList{}, 41 | ) 42 | metav1.AddToGroupVersion(scheme, SchemeGroupVersion) 43 | return nil 44 | } 45 | -------------------------------------------------------------------------------- /pkg/apiserver/apiserver_test.go: -------------------------------------------------------------------------------- 1 | package apiserver 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | const ( 8 | clusterStatusTest = "/clusters/test-namespace/testcluster/" 9 | clusterStatusNumericTest = "/clusters/test-namespace-1/testcluster/" 10 | clusterLogsTest = "/clusters/test-namespace/testcluster/logs/" 11 | teamTest = "/clusters/test-id/" 12 | ) 13 | 14 | func TestUrlRegexps(t *testing.T) { 15 | if clusterStatusURL.FindStringSubmatch(clusterStatusTest) == nil { 16 | t.Errorf("clusterStatusURL can't match %s", clusterStatusTest) 17 | } 18 | 19 | if clusterStatusURL.FindStringSubmatch(clusterStatusNumericTest) == nil { 20 | t.Errorf("clusterStatusURL can't match %s", clusterStatusNumericTest) 21 | } 22 | 23 | if clusterLogsURL.FindStringSubmatch(clusterLogsTest) == nil { 24 | t.Errorf("clusterLogsURL can't match %s", clusterLogsTest) 25 | } 26 | 27 | if teamURL.FindStringSubmatch(teamTest) == nil { 28 | t.Errorf("teamURL can't match %s", teamTest) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /pkg/cluster/connection_pooler_new_test.go: -------------------------------------------------------------------------------- 1 | package cluster 2 | 3 | import ( 4 | "testing" 5 | 6 | "context" 7 | 8 | appsv1 "k8s.io/api/apps/v1" 9 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 | 11 | "k8s.io/apimachinery/pkg/labels" 12 | 13 | "k8s.io/client-go/kubernetes/fake" 14 | ) 15 | 16 | func TestFakeClient(t *testing.T) { 17 | clientSet := fake.NewSimpleClientset() 18 | namespace := "default" 19 | 20 | l := labels.Set(map[string]string{ 21 | "application": "spilo", 22 | }) 23 | 24 | deployment := &appsv1.Deployment{ 25 | ObjectMeta: metav1.ObjectMeta{ 26 | Name: "my-deployment1", 27 | Namespace: namespace, 28 | Labels: l, 29 | }, 30 | } 31 | 32 | clientSet.AppsV1().Deployments(namespace).Create(context.TODO(), deployment, metav1.CreateOptions{}) 33 | 34 | deployment2, _ := clientSet.AppsV1().Deployments(namespace).Get(context.TODO(), "my-deployment1", metav1.GetOptions{}) 35 | 36 | if deployment.ObjectMeta.Name != deployment2.ObjectMeta.Name { 37 | t.Errorf("Deployments are not equal") 38 | } 39 | 40 | deployments, _ := clientSet.AppsV1().Deployments(namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: "application=spilo"}) 41 | 42 | if len(deployments.Items) != 1 { 43 | t.Errorf("Label search does not work") 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pkg/cluster/exec.go: -------------------------------------------------------------------------------- 1 | package cluster 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "fmt" 7 | "strings" 8 | 9 | v1 "k8s.io/api/core/v1" 10 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 | "k8s.io/client-go/kubernetes/scheme" 12 | "k8s.io/client-go/tools/remotecommand" 13 | 14 | "github.com/zalando/postgres-operator/pkg/spec" 15 | "github.com/zalando/postgres-operator/pkg/util/constants" 16 | ) 17 | 18 | // ExecCommand executes arbitrary command inside the pod 19 | func (c *Cluster) ExecCommand(podName *spec.NamespacedName, command ...string) (string, error) { 20 | c.setProcessName("executing command %q", strings.Join(command, " ")) 21 | 22 | var ( 23 | execOut bytes.Buffer 24 | execErr bytes.Buffer 25 | ) 26 | 27 | pod, err := c.KubeClient.Pods(podName.Namespace).Get(context.TODO(), podName.Name, metav1.GetOptions{}) 28 | if err != nil { 29 | return "", fmt.Errorf("could not get pod info: %v", err) 30 | } 31 | 32 | // iterate through all containers looking for the one running PostgreSQL. 33 | targetContainer := -1 34 | for i, cr := range pod.Spec.Containers { 35 | if cr.Name == constants.PostgresContainerName { 36 | targetContainer = i 37 | break 38 | } 39 | } 40 | 41 | if targetContainer < 0 { 42 | return "", fmt.Errorf("could not find %s container to exec to", constants.PostgresContainerName) 43 | } 44 | 45 | req := c.KubeClient.RESTClient.Post(). 46 | Resource("pods"). 47 | Name(podName.Name). 48 | Namespace(podName.Namespace). 49 | SubResource("exec") 50 | req.VersionedParams(&v1.PodExecOptions{ 51 | Container: pod.Spec.Containers[targetContainer].Name, 52 | Command: command, 53 | Stdout: true, 54 | Stderr: true, 55 | }, scheme.ParameterCodec) 56 | 57 | exec, err := remotecommand.NewSPDYExecutor(c.RestConfig, "POST", req.URL()) 58 | if err != nil { 59 | return "", fmt.Errorf("failed to init executor: %v", err) 60 | } 61 | 62 | err = exec.StreamWithContext(context.TODO(), remotecommand.StreamOptions{ 63 | Stdout: &execOut, 64 | Stderr: &execErr, 65 | Tty: false, 66 | }) 67 | 68 | if err != nil { 69 | return "", fmt.Errorf("could not execute: %v", err) 70 | } 71 | 72 | if execErr.Len() > 0 { 73 | return "", fmt.Errorf("stderr: %v", execErr.String()) 74 | } 75 | 76 | return execOut.String(), nil 77 | } 78 | -------------------------------------------------------------------------------- /pkg/cluster/filesystems.go: -------------------------------------------------------------------------------- 1 | package cluster 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/zalando/postgres-operator/pkg/spec" 8 | "github.com/zalando/postgres-operator/pkg/util/constants" 9 | "github.com/zalando/postgres-operator/pkg/util/filesystems" 10 | ) 11 | 12 | func (c *Cluster) getPostgresFilesystemInfo(podName *spec.NamespacedName) (device, fstype string, err error) { 13 | out, err := c.ExecCommand(podName, "bash", "-c", fmt.Sprintf("df -T %s|tail -1", constants.PostgresDataMount)) 14 | if err != nil { 15 | return "", "", err 16 | } 17 | fields := strings.Fields(out) 18 | if len(fields) < 2 { 19 | return "", "", fmt.Errorf("too few fields in the df output") 20 | } 21 | 22 | return fields[0], fields[1], nil 23 | } 24 | 25 | func (c *Cluster) resizePostgresFilesystem(podName *spec.NamespacedName, resizers []filesystems.FilesystemResizer) error { 26 | // resize2fs always writes to stderr, and ExecCommand considers a non-empty stderr an error 27 | // first, determine the device and the filesystem 28 | deviceName, fsType, err := c.getPostgresFilesystemInfo(podName) 29 | if err != nil { 30 | return fmt.Errorf("could not get device and type for the postgres filesystem: %v", err) 31 | } 32 | for _, resizer := range resizers { 33 | if !resizer.CanResizeFilesystem(fsType) { 34 | continue 35 | } 36 | err := resizer.ResizeFilesystem(deviceName, func(cmd string) (out string, err error) { 37 | return c.ExecCommand(podName, "bash", "-c", cmd) 38 | }) 39 | 40 | return err 41 | } 42 | return fmt.Errorf("could not resize filesystem: no compatible resizers for the filesystem of type %q", fsType) 43 | } 44 | -------------------------------------------------------------------------------- /pkg/cluster/types.go: -------------------------------------------------------------------------------- 1 | package cluster 2 | 3 | import ( 4 | "time" 5 | 6 | acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" 7 | appsv1 "k8s.io/api/apps/v1" 8 | v1 "k8s.io/api/core/v1" 9 | policyv1 "k8s.io/api/policy/v1" 10 | "k8s.io/apimachinery/pkg/types" 11 | ) 12 | 13 | // PostgresRole describes role of the node 14 | type PostgresRole string 15 | 16 | const ( 17 | // spilo roles 18 | Master PostgresRole = "master" 19 | Replica PostgresRole = "replica" 20 | Patroni PostgresRole = "config" 21 | 22 | // roles returned by Patroni cluster endpoint 23 | Leader PostgresRole = "leader" 24 | StandbyLeader PostgresRole = "standby_leader" 25 | SyncStandby PostgresRole = "sync_standby" 26 | ) 27 | 28 | // PodEventType represents the type of a pod-related event 29 | type PodEventType string 30 | 31 | // Possible values for the EventType 32 | const ( 33 | PodEventAdd PodEventType = "ADD" 34 | PodEventUpdate PodEventType = "UPDATE" 35 | PodEventDelete PodEventType = "DELETE" 36 | ) 37 | 38 | // PodEvent describes the event for a single Pod 39 | type PodEvent struct { 40 | ResourceVersion string 41 | PodName types.NamespacedName 42 | PrevPod *v1.Pod 43 | CurPod *v1.Pod 44 | EventType PodEventType 45 | } 46 | 47 | // Process describes process of the cluster 48 | type Process struct { 49 | Name string 50 | StartTime time.Time 51 | } 52 | 53 | // WorkerStatus describes status of the worker 54 | type WorkerStatus struct { 55 | CurrentCluster types.NamespacedName 56 | CurrentProcess Process 57 | } 58 | 59 | // ClusterStatus describes status of the cluster 60 | type ClusterStatus struct { 61 | Team string 62 | Cluster string 63 | Namespace string 64 | MasterService *v1.Service 65 | ReplicaService *v1.Service 66 | MasterEndpoint *v1.Endpoints 67 | ReplicaEndpoint *v1.Endpoints 68 | StatefulSet *appsv1.StatefulSet 69 | PrimaryPodDisruptionBudget *policyv1.PodDisruptionBudget 70 | CriticalOpPodDisruptionBudget *policyv1.PodDisruptionBudget 71 | 72 | CurrentProcess Process 73 | Worker uint32 74 | Status acidv1.PostgresStatus 75 | Spec acidv1.PostgresSpec 76 | Error error 77 | } 78 | 79 | type TemplateParams map[string]interface{} 80 | 81 | type InstallFunction func(schema string, user string) error 82 | 83 | type SyncReason []string 84 | 85 | // no sync happened, empty value 86 | var NoSync SyncReason = []string{} 87 | -------------------------------------------------------------------------------- /pkg/controller/node_test.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/zalando/postgres-operator/pkg/spec" 7 | v1 "k8s.io/api/core/v1" 8 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 9 | ) 10 | 11 | const ( 12 | readyLabel = "lifecycle-status" 13 | readyValue = "ready" 14 | ) 15 | 16 | func newNodeTestController() *Controller { 17 | var controller = NewController(&spec.ControllerConfig{}, "node-test") 18 | return controller 19 | } 20 | 21 | func makeNode(labels map[string]string, isSchedulable bool) *v1.Node { 22 | return &v1.Node{ 23 | ObjectMeta: metav1.ObjectMeta{ 24 | Namespace: v1.NamespaceDefault, 25 | Labels: labels, 26 | }, 27 | Spec: v1.NodeSpec{ 28 | Unschedulable: !isSchedulable, 29 | }, 30 | } 31 | } 32 | 33 | var nodeTestController = newNodeTestController() 34 | 35 | func TestNodeIsReady(t *testing.T) { 36 | testName := "TestNodeIsReady" 37 | var testTable = []struct { 38 | in *v1.Node 39 | out bool 40 | readinessLabel map[string]string 41 | }{ 42 | { 43 | in: makeNode(map[string]string{"foo": "bar"}, true), 44 | out: true, 45 | readinessLabel: map[string]string{readyLabel: readyValue}, 46 | }, 47 | { 48 | in: makeNode(map[string]string{"foo": "bar"}, false), 49 | out: false, 50 | readinessLabel: map[string]string{readyLabel: readyValue}, 51 | }, 52 | { 53 | in: makeNode(map[string]string{readyLabel: readyValue}, false), 54 | out: true, 55 | readinessLabel: map[string]string{readyLabel: readyValue}, 56 | }, 57 | { 58 | in: makeNode(map[string]string{"foo": "bar", "master": "true"}, false), 59 | out: true, 60 | readinessLabel: map[string]string{readyLabel: readyValue}, 61 | }, 62 | { 63 | in: makeNode(map[string]string{"foo": "bar", "master": "true"}, false), 64 | out: true, 65 | readinessLabel: map[string]string{readyLabel: readyValue}, 66 | }, 67 | { 68 | in: makeNode(map[string]string{"foo": "bar"}, true), 69 | out: true, 70 | readinessLabel: map[string]string{}, 71 | }, 72 | { 73 | in: makeNode(map[string]string{"foo": "bar"}, false), 74 | out: false, 75 | readinessLabel: map[string]string{}, 76 | }, 77 | { 78 | in: makeNode(map[string]string{readyLabel: readyValue}, false), 79 | out: false, 80 | readinessLabel: map[string]string{}, 81 | }, 82 | { 83 | in: makeNode(map[string]string{"foo": "bar", "master": "true"}, false), 84 | out: true, 85 | readinessLabel: map[string]string{}, 86 | }, 87 | } 88 | for _, tt := range testTable { 89 | nodeTestController.opConfig.NodeReadinessLabel = tt.readinessLabel 90 | if isReady := nodeTestController.nodeIsReady(tt.in); isReady != tt.out { 91 | t.Errorf("%s: expected response %t does not match the actual %t for the node %#v", 92 | testName, tt.out, isReady, tt.in) 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /pkg/controller/pod.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "context" 5 | 6 | v1 "k8s.io/api/core/v1" 7 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 8 | "k8s.io/apimachinery/pkg/runtime" 9 | "k8s.io/apimachinery/pkg/watch" 10 | 11 | "github.com/zalando/postgres-operator/pkg/cluster" 12 | "github.com/zalando/postgres-operator/pkg/spec" 13 | "github.com/zalando/postgres-operator/pkg/util" 14 | "k8s.io/apimachinery/pkg/types" 15 | ) 16 | 17 | func (c *Controller) podListFunc(options metav1.ListOptions) (runtime.Object, error) { 18 | opts := metav1.ListOptions{ 19 | Watch: options.Watch, 20 | ResourceVersion: options.ResourceVersion, 21 | TimeoutSeconds: options.TimeoutSeconds, 22 | } 23 | 24 | return c.KubeClient.Pods(c.opConfig.WatchedNamespace).List(context.TODO(), opts) 25 | } 26 | 27 | func (c *Controller) podWatchFunc(options metav1.ListOptions) (watch.Interface, error) { 28 | opts := metav1.ListOptions{ 29 | Watch: options.Watch, 30 | ResourceVersion: options.ResourceVersion, 31 | TimeoutSeconds: options.TimeoutSeconds, 32 | } 33 | 34 | return c.KubeClient.Pods(c.opConfig.WatchedNamespace).Watch(context.TODO(), opts) 35 | } 36 | 37 | func (c *Controller) dispatchPodEvent(clusterName spec.NamespacedName, event cluster.PodEvent) { 38 | c.clustersMu.RLock() 39 | cluster, ok := c.clusters[clusterName] 40 | c.clustersMu.RUnlock() 41 | if ok { 42 | cluster.ReceivePodEvent(event) 43 | } 44 | } 45 | 46 | func (c *Controller) podAdd(obj interface{}) { 47 | if pod, ok := obj.(*v1.Pod); ok { 48 | c.preparePodEventForDispatch(pod, nil, cluster.PodEventAdd) 49 | } 50 | } 51 | 52 | func (c *Controller) podUpdate(prev, cur interface{}) { 53 | prevPod, ok := prev.(*v1.Pod) 54 | if !ok { 55 | return 56 | } 57 | 58 | curPod, ok := cur.(*v1.Pod) 59 | if !ok { 60 | return 61 | } 62 | 63 | c.preparePodEventForDispatch(curPod, prevPod, cluster.PodEventUpdate) 64 | } 65 | 66 | func (c *Controller) podDelete(obj interface{}) { 67 | 68 | if pod, ok := obj.(*v1.Pod); ok { 69 | c.preparePodEventForDispatch(pod, nil, cluster.PodEventDelete) 70 | } 71 | } 72 | 73 | func (c *Controller) preparePodEventForDispatch(curPod, prevPod *v1.Pod, event cluster.PodEventType) { 74 | podEvent := cluster.PodEvent{ 75 | PodName: types.NamespacedName(util.NameFromMeta(curPod.ObjectMeta)), 76 | CurPod: curPod, 77 | PrevPod: prevPod, 78 | EventType: event, 79 | ResourceVersion: curPod.ResourceVersion, 80 | } 81 | 82 | c.dispatchPodEvent(c.podClusterName(curPod), podEvent) 83 | } 84 | -------------------------------------------------------------------------------- /pkg/controller/types.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "time" 5 | 6 | "k8s.io/apimachinery/pkg/types" 7 | 8 | acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" 9 | ) 10 | 11 | // EventType contains type of the events for the TPRs and Pods received from Kubernetes 12 | type EventType string 13 | 14 | // Possible values for the EventType 15 | const ( 16 | EventAdd EventType = "ADD" 17 | EventUpdate EventType = "UPDATE" 18 | EventDelete EventType = "DELETE" 19 | EventSync EventType = "SYNC" 20 | EventRepair EventType = "REPAIR" 21 | ) 22 | 23 | // ClusterEvent carries the payload of the Cluster TPR events. 24 | type ClusterEvent struct { 25 | EventTime time.Time 26 | UID types.UID 27 | EventType EventType 28 | OldSpec *acidv1.Postgresql 29 | NewSpec *acidv1.Postgresql 30 | WorkerID uint32 31 | } 32 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | // This package has the automatically generated clientset. 26 | package versioned 27 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | // This package has the automatically generated fake clientset. 26 | package fake 27 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/fake/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | package fake 26 | 27 | import ( 28 | acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" 29 | zalandov1 "github.com/zalando/postgres-operator/pkg/apis/zalando.org/v1" 30 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 31 | runtime "k8s.io/apimachinery/pkg/runtime" 32 | schema "k8s.io/apimachinery/pkg/runtime/schema" 33 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 34 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 35 | ) 36 | 37 | var scheme = runtime.NewScheme() 38 | var codecs = serializer.NewCodecFactory(scheme) 39 | 40 | var localSchemeBuilder = runtime.SchemeBuilder{ 41 | acidv1.AddToScheme, 42 | zalandov1.AddToScheme, 43 | } 44 | 45 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 46 | // of clientsets, like in: 47 | // 48 | // import ( 49 | // "k8s.io/client-go/kubernetes" 50 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 51 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 52 | // ) 53 | // 54 | // kclientset, _ := kubernetes.NewForConfig(c) 55 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 56 | // 57 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 58 | // correctly. 59 | var AddToScheme = localSchemeBuilder.AddToScheme 60 | 61 | func init() { 62 | v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) 63 | utilruntime.Must(AddToScheme(scheme)) 64 | } 65 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/scheme/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | // This package contains the scheme of the automatically generated clientset. 26 | package scheme 27 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/scheme/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | package scheme 26 | 27 | import ( 28 | acidv1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" 29 | zalandov1 "github.com/zalando/postgres-operator/pkg/apis/zalando.org/v1" 30 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 31 | runtime "k8s.io/apimachinery/pkg/runtime" 32 | schema "k8s.io/apimachinery/pkg/runtime/schema" 33 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 34 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 35 | ) 36 | 37 | var Scheme = runtime.NewScheme() 38 | var Codecs = serializer.NewCodecFactory(Scheme) 39 | var ParameterCodec = runtime.NewParameterCodec(Scheme) 40 | var localSchemeBuilder = runtime.SchemeBuilder{ 41 | acidv1.AddToScheme, 42 | zalandov1.AddToScheme, 43 | } 44 | 45 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 46 | // of clientsets, like in: 47 | // 48 | // import ( 49 | // "k8s.io/client-go/kubernetes" 50 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 51 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 52 | // ) 53 | // 54 | // kclientset, _ := kubernetes.NewForConfig(c) 55 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 56 | // 57 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 58 | // correctly. 59 | var AddToScheme = localSchemeBuilder.AddToScheme 60 | 61 | func init() { 62 | v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) 63 | utilruntime.Must(AddToScheme(Scheme)) 64 | } 65 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | // This package has the automatically generated typed clients. 26 | package v1 27 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | // Package fake has the automatically generated clients. 26 | package fake 27 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_acid.zalan.do_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | package fake 26 | 27 | import ( 28 | v1 "github.com/zalando/postgres-operator/pkg/generated/clientset/versioned/typed/acid.zalan.do/v1" 29 | rest "k8s.io/client-go/rest" 30 | testing "k8s.io/client-go/testing" 31 | ) 32 | 33 | type FakeAcidV1 struct { 34 | *testing.Fake 35 | } 36 | 37 | func (c *FakeAcidV1) OperatorConfigurations(namespace string) v1.OperatorConfigurationInterface { 38 | return &FakeOperatorConfigurations{c, namespace} 39 | } 40 | 41 | func (c *FakeAcidV1) PostgresTeams(namespace string) v1.PostgresTeamInterface { 42 | return &FakePostgresTeams{c, namespace} 43 | } 44 | 45 | func (c *FakeAcidV1) Postgresqls(namespace string) v1.PostgresqlInterface { 46 | return &FakePostgresqls{c, namespace} 47 | } 48 | 49 | // RESTClient returns a RESTClient that is used to communicate 50 | // with API server by this client implementation. 51 | func (c *FakeAcidV1) RESTClient() rest.Interface { 52 | var ret *rest.RESTClient 53 | return ret 54 | } 55 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/fake/fake_operatorconfiguration.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | package fake 26 | 27 | import ( 28 | "context" 29 | 30 | acidzalandov1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" 31 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 32 | schema "k8s.io/apimachinery/pkg/runtime/schema" 33 | testing "k8s.io/client-go/testing" 34 | ) 35 | 36 | // FakeOperatorConfigurations implements OperatorConfigurationInterface 37 | type FakeOperatorConfigurations struct { 38 | Fake *FakeAcidV1 39 | ns string 40 | } 41 | 42 | var operatorconfigurationsResource = schema.GroupVersionResource{Group: "acid.zalan.do", Version: "v1", Resource: "operatorconfigurations"} 43 | 44 | var operatorconfigurationsKind = schema.GroupVersionKind{Group: "acid.zalan.do", Version: "v1", Kind: "OperatorConfiguration"} 45 | 46 | // Get takes name of the operatorConfiguration, and returns the corresponding operatorConfiguration object, and an error if there is any. 47 | func (c *FakeOperatorConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *acidzalandov1.OperatorConfiguration, err error) { 48 | obj, err := c.Fake. 49 | Invokes(testing.NewGetAction(operatorconfigurationsResource, c.ns, name), &acidzalandov1.OperatorConfiguration{}) 50 | 51 | if obj == nil { 52 | return nil, err 53 | } 54 | return obj.(*acidzalandov1.OperatorConfiguration), err 55 | } 56 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/generated_expansion.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | package v1 26 | 27 | type OperatorConfigurationExpansion interface{} 28 | 29 | type PostgresTeamExpansion interface{} 30 | 31 | type PostgresqlExpansion interface{} 32 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/typed/acid.zalan.do/v1/operatorconfiguration.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | package v1 26 | 27 | import ( 28 | "context" 29 | 30 | acidzalandov1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" 31 | scheme "github.com/zalando/postgres-operator/pkg/generated/clientset/versioned/scheme" 32 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 33 | rest "k8s.io/client-go/rest" 34 | ) 35 | 36 | // OperatorConfigurationsGetter has a method to return a OperatorConfigurationInterface. 37 | // A group's client should implement this interface. 38 | type OperatorConfigurationsGetter interface { 39 | OperatorConfigurations(namespace string) OperatorConfigurationInterface 40 | } 41 | 42 | // OperatorConfigurationInterface has methods to work with OperatorConfiguration resources. 43 | type OperatorConfigurationInterface interface { 44 | Get(ctx context.Context, name string, opts v1.GetOptions) (*acidzalandov1.OperatorConfiguration, error) 45 | OperatorConfigurationExpansion 46 | } 47 | 48 | // operatorConfigurations implements OperatorConfigurationInterface 49 | type operatorConfigurations struct { 50 | client rest.Interface 51 | ns string 52 | } 53 | 54 | // newOperatorConfigurations returns a OperatorConfigurations 55 | func newOperatorConfigurations(c *AcidV1Client, namespace string) *operatorConfigurations { 56 | return &operatorConfigurations{ 57 | client: c.RESTClient(), 58 | ns: namespace, 59 | } 60 | } 61 | 62 | // Get takes name of the operatorConfiguration, and returns the corresponding operatorConfiguration object, and an error if there is any. 63 | func (c *operatorConfigurations) Get(ctx context.Context, name string, options v1.GetOptions) (result *acidzalandov1.OperatorConfiguration, err error) { 64 | result = &acidzalandov1.OperatorConfiguration{} 65 | err = c.client.Get(). 66 | Namespace(c.ns). 67 | Resource("operatorconfigurations"). 68 | Name(name). 69 | VersionedParams(&options, scheme.ParameterCodec). 70 | Do(ctx). 71 | Into(result) 72 | return 73 | } 74 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/typed/zalando.org/v1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | // This package has the automatically generated typed clients. 26 | package v1 27 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/typed/zalando.org/v1/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | // Package fake has the automatically generated clients. 26 | package fake 27 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/typed/zalando.org/v1/fake/fake_zalando.org_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | package fake 26 | 27 | import ( 28 | v1 "github.com/zalando/postgres-operator/pkg/generated/clientset/versioned/typed/zalando.org/v1" 29 | rest "k8s.io/client-go/rest" 30 | testing "k8s.io/client-go/testing" 31 | ) 32 | 33 | type FakeZalandoV1 struct { 34 | *testing.Fake 35 | } 36 | 37 | func (c *FakeZalandoV1) FabricEventStreams(namespace string) v1.FabricEventStreamInterface { 38 | return &FakeFabricEventStreams{c, namespace} 39 | } 40 | 41 | // RESTClient returns a RESTClient that is used to communicate 42 | // with API server by this client implementation. 43 | func (c *FakeZalandoV1) RESTClient() rest.Interface { 44 | var ret *rest.RESTClient 45 | return ret 46 | } 47 | -------------------------------------------------------------------------------- /pkg/generated/clientset/versioned/typed/zalando.org/v1/generated_expansion.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by client-gen. DO NOT EDIT. 24 | 25 | package v1 26 | 27 | type FabricEventStreamExpansion interface{} 28 | -------------------------------------------------------------------------------- /pkg/generated/informers/externalversions/acid.zalan.do/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by informer-gen. DO NOT EDIT. 24 | 25 | package acid 26 | 27 | import ( 28 | v1 "github.com/zalando/postgres-operator/pkg/generated/informers/externalversions/acid.zalan.do/v1" 29 | internalinterfaces "github.com/zalando/postgres-operator/pkg/generated/informers/externalversions/internalinterfaces" 30 | ) 31 | 32 | // Interface provides access to each of this group's versions. 33 | type Interface interface { 34 | // V1 provides access to shared informers for resources in V1. 35 | V1() v1.Interface 36 | } 37 | 38 | type group struct { 39 | factory internalinterfaces.SharedInformerFactory 40 | namespace string 41 | tweakListOptions internalinterfaces.TweakListOptionsFunc 42 | } 43 | 44 | // New returns a new Interface. 45 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 46 | return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 47 | } 48 | 49 | // V1 returns a new v1.Interface. 50 | func (g *group) V1() v1.Interface { 51 | return v1.New(g.factory, g.namespace, g.tweakListOptions) 52 | } 53 | -------------------------------------------------------------------------------- /pkg/generated/informers/externalversions/acid.zalan.do/v1/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by informer-gen. DO NOT EDIT. 24 | 25 | package v1 26 | 27 | import ( 28 | internalinterfaces "github.com/zalando/postgres-operator/pkg/generated/informers/externalversions/internalinterfaces" 29 | ) 30 | 31 | // Interface provides access to all the informers in this group version. 32 | type Interface interface { 33 | // PostgresTeams returns a PostgresTeamInformer. 34 | PostgresTeams() PostgresTeamInformer 35 | // Postgresqls returns a PostgresqlInformer. 36 | Postgresqls() PostgresqlInformer 37 | } 38 | 39 | type version struct { 40 | factory internalinterfaces.SharedInformerFactory 41 | namespace string 42 | tweakListOptions internalinterfaces.TweakListOptionsFunc 43 | } 44 | 45 | // New returns a new Interface. 46 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 47 | return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 48 | } 49 | 50 | // PostgresTeams returns a PostgresTeamInformer. 51 | func (v *version) PostgresTeams() PostgresTeamInformer { 52 | return &postgresTeamInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} 53 | } 54 | 55 | // Postgresqls returns a PostgresqlInformer. 56 | func (v *version) Postgresqls() PostgresqlInformer { 57 | return &postgresqlInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} 58 | } 59 | -------------------------------------------------------------------------------- /pkg/generated/informers/externalversions/generic.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by informer-gen. DO NOT EDIT. 24 | 25 | package externalversions 26 | 27 | import ( 28 | "fmt" 29 | 30 | v1 "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do/v1" 31 | zalandoorgv1 "github.com/zalando/postgres-operator/pkg/apis/zalando.org/v1" 32 | schema "k8s.io/apimachinery/pkg/runtime/schema" 33 | cache "k8s.io/client-go/tools/cache" 34 | ) 35 | 36 | // GenericInformer is type of SharedIndexInformer which will locate and delegate to other 37 | // sharedInformers based on type 38 | type GenericInformer interface { 39 | Informer() cache.SharedIndexInformer 40 | Lister() cache.GenericLister 41 | } 42 | 43 | type genericInformer struct { 44 | informer cache.SharedIndexInformer 45 | resource schema.GroupResource 46 | } 47 | 48 | // Informer returns the SharedIndexInformer. 49 | func (f *genericInformer) Informer() cache.SharedIndexInformer { 50 | return f.informer 51 | } 52 | 53 | // Lister returns the GenericLister. 54 | func (f *genericInformer) Lister() cache.GenericLister { 55 | return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) 56 | } 57 | 58 | // ForResource gives generic access to a shared informer of the matching type 59 | // TODO extend this to unknown resources with a client pool 60 | func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { 61 | switch resource { 62 | // Group=acid.zalan.do, Version=v1 63 | case v1.SchemeGroupVersion.WithResource("postgresteams"): 64 | return &genericInformer{resource: resource.GroupResource(), informer: f.Acid().V1().PostgresTeams().Informer()}, nil 65 | case v1.SchemeGroupVersion.WithResource("postgresqls"): 66 | return &genericInformer{resource: resource.GroupResource(), informer: f.Acid().V1().Postgresqls().Informer()}, nil 67 | 68 | // Group=zalando.org, Version=v1 69 | case zalandoorgv1.SchemeGroupVersion.WithResource("fabriceventstreams"): 70 | return &genericInformer{resource: resource.GroupResource(), informer: f.Zalando().V1().FabricEventStreams().Informer()}, nil 71 | 72 | } 73 | 74 | return nil, fmt.Errorf("no informer found for %v", resource) 75 | } 76 | -------------------------------------------------------------------------------- /pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by informer-gen. DO NOT EDIT. 24 | 25 | package internalinterfaces 26 | 27 | import ( 28 | time "time" 29 | 30 | versioned "github.com/zalando/postgres-operator/pkg/generated/clientset/versioned" 31 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 32 | runtime "k8s.io/apimachinery/pkg/runtime" 33 | cache "k8s.io/client-go/tools/cache" 34 | ) 35 | 36 | // NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer. 37 | type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer 38 | 39 | // SharedInformerFactory a small interface to allow for adding an informer without an import cycle 40 | type SharedInformerFactory interface { 41 | Start(stopCh <-chan struct{}) 42 | InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer 43 | } 44 | 45 | // TweakListOptionsFunc is a function that transforms a v1.ListOptions. 46 | type TweakListOptionsFunc func(*v1.ListOptions) 47 | -------------------------------------------------------------------------------- /pkg/generated/informers/externalversions/zalando.org/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by informer-gen. DO NOT EDIT. 24 | 25 | package zalando 26 | 27 | import ( 28 | internalinterfaces "github.com/zalando/postgres-operator/pkg/generated/informers/externalversions/internalinterfaces" 29 | v1 "github.com/zalando/postgres-operator/pkg/generated/informers/externalversions/zalando.org/v1" 30 | ) 31 | 32 | // Interface provides access to each of this group's versions. 33 | type Interface interface { 34 | // V1 provides access to shared informers for resources in V1. 35 | V1() v1.Interface 36 | } 37 | 38 | type group struct { 39 | factory internalinterfaces.SharedInformerFactory 40 | namespace string 41 | tweakListOptions internalinterfaces.TweakListOptionsFunc 42 | } 43 | 44 | // New returns a new Interface. 45 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 46 | return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 47 | } 48 | 49 | // V1 returns a new v1.Interface. 50 | func (g *group) V1() v1.Interface { 51 | return v1.New(g.factory, g.namespace, g.tweakListOptions) 52 | } 53 | -------------------------------------------------------------------------------- /pkg/generated/informers/externalversions/zalando.org/v1/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by informer-gen. DO NOT EDIT. 24 | 25 | package v1 26 | 27 | import ( 28 | internalinterfaces "github.com/zalando/postgres-operator/pkg/generated/informers/externalversions/internalinterfaces" 29 | ) 30 | 31 | // Interface provides access to all the informers in this group version. 32 | type Interface interface { 33 | // FabricEventStreams returns a FabricEventStreamInformer. 34 | FabricEventStreams() FabricEventStreamInformer 35 | } 36 | 37 | type version struct { 38 | factory internalinterfaces.SharedInformerFactory 39 | namespace string 40 | tweakListOptions internalinterfaces.TweakListOptionsFunc 41 | } 42 | 43 | // New returns a new Interface. 44 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 45 | return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 46 | } 47 | 48 | // FabricEventStreams returns a FabricEventStreamInformer. 49 | func (v *version) FabricEventStreams() FabricEventStreamInformer { 50 | return &fabricEventStreamInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} 51 | } 52 | -------------------------------------------------------------------------------- /pkg/generated/listers/acid.zalan.do/v1/expansion_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by lister-gen. DO NOT EDIT. 24 | 25 | package v1 26 | 27 | // PostgresTeamListerExpansion allows custom methods to be added to 28 | // PostgresTeamLister. 29 | type PostgresTeamListerExpansion interface{} 30 | 31 | // PostgresTeamNamespaceListerExpansion allows custom methods to be added to 32 | // PostgresTeamNamespaceLister. 33 | type PostgresTeamNamespaceListerExpansion interface{} 34 | 35 | // PostgresqlListerExpansion allows custom methods to be added to 36 | // PostgresqlLister. 37 | type PostgresqlListerExpansion interface{} 38 | 39 | // PostgresqlNamespaceListerExpansion allows custom methods to be added to 40 | // PostgresqlNamespaceLister. 41 | type PostgresqlNamespaceListerExpansion interface{} 42 | -------------------------------------------------------------------------------- /pkg/generated/listers/zalando.org/v1/expansion_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 Compose, Zalando SE 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | */ 22 | 23 | // Code generated by lister-gen. DO NOT EDIT. 24 | 25 | package v1 26 | 27 | // FabricEventStreamListerExpansion allows custom methods to be added to 28 | // FabricEventStreamLister. 29 | type FabricEventStreamListerExpansion interface{} 30 | 31 | // FabricEventStreamNamespaceListerExpansion allows custom methods to be added to 32 | // FabricEventStreamNamespaceLister. 33 | type FabricEventStreamNamespaceListerExpansion interface{} 34 | -------------------------------------------------------------------------------- /pkg/spec/types_test.go: -------------------------------------------------------------------------------- 1 | package spec 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | ) 7 | 8 | const ( 9 | mockOperatorNamespace = "acid" 10 | ) 11 | 12 | var nnTests = []struct { 13 | s string 14 | expected NamespacedName 15 | expectedMarshal []byte 16 | }{ 17 | {`acid/cluster`, NamespacedName{Namespace: mockOperatorNamespace, Name: "cluster"}, []byte(`"acid/cluster"`)}, 18 | {`/name`, NamespacedName{Namespace: mockOperatorNamespace, Name: "name"}, []byte(`"acid/name"`)}, 19 | {`test`, NamespacedName{Namespace: mockOperatorNamespace, Name: "test"}, []byte(`"acid/test"`)}, 20 | } 21 | 22 | var nnErr = []string{"test/", "/", "", "//"} 23 | 24 | func TestNamespacedNameDecode(t *testing.T) { 25 | 26 | for _, tt := range nnTests { 27 | var actual NamespacedName 28 | err := actual.DecodeWorker(tt.s, mockOperatorNamespace) 29 | if err != nil { 30 | t.Errorf("decode error: %v", err) 31 | } 32 | if actual != tt.expected { 33 | t.Errorf("expected: %v, got %#v", tt.expected, actual) 34 | } 35 | } 36 | 37 | } 38 | 39 | func TestNamespacedNameMarshal(t *testing.T) { 40 | for _, tt := range nnTests { 41 | var actual NamespacedName 42 | 43 | m, err := actual.MarshalJSON() 44 | if err != nil { 45 | t.Errorf("marshal error: %v", err) 46 | } 47 | if bytes.Equal(m, tt.expectedMarshal) { 48 | t.Errorf("expected marshal: %v, got %#v", tt.expected, actual) 49 | } 50 | } 51 | } 52 | 53 | func TestNamespacedNameError(t *testing.T) { 54 | for _, tt := range nnErr { 55 | var actual NamespacedName 56 | err := actual.DecodeWorker(tt, mockOperatorNamespace) 57 | if err == nil { 58 | t.Errorf("error expected for %q, got: %#v", tt, actual) 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /pkg/util/config/config_test.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | var getMapPairsFromStringTest = []struct { 10 | in string 11 | expected []string 12 | err error 13 | }{ 14 | {"log_statement:all, work_mem:'4GB'", []string{"log_statement:all", "work_mem:'4GB'"}, nil}, 15 | {`log_statement:none, search_path:'"$user", public'`, []string{"log_statement:none", `search_path:'"$user", public'`}, nil}, 16 | {`search_path:'"$user"`, nil, fmt.Errorf("unmatched quote starting at position 13")}, 17 | {"", []string{""}, nil}, 18 | {",,log_statement:all ,", []string{"", "", "log_statement:all", ""}, nil}, 19 | } 20 | 21 | func TestGetMapPairsFromString(t *testing.T) { 22 | for _, tt := range getMapPairsFromStringTest { 23 | got, err := getMapPairsFromString(tt.in) 24 | if err != tt.err && ((err == nil || tt.err == nil) || (err.Error() != tt.err.Error())) { 25 | t.Errorf("TestGetMapPairsFromString with %s: expected error: %#v, got %#v", tt.in, tt.err, err) 26 | } 27 | if !reflect.DeepEqual(got, tt.expected) { 28 | t.Errorf("TestGetMapPairsFromString with %s: expected %#v, got %#v", tt.in, tt.expected, got) 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /pkg/util/constants/annotations.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | // Names and values in Kubernetes annotation for services, statefulsets and volumes 4 | const ( 5 | ZalandoDNSNameAnnotation = "external-dns.alpha.kubernetes.io/hostname" 6 | ElbTimeoutAnnotationName = "service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout" 7 | ElbTimeoutAnnotationValue = "3600" 8 | KubeIAmAnnotation = "iam.amazonaws.com/role" 9 | VolumeStorateProvisionerAnnotation = "pv.kubernetes.io/provisioned-by" 10 | PostgresqlControllerAnnotationKey = "acid.zalan.do/controller" 11 | ) 12 | -------------------------------------------------------------------------------- /pkg/util/constants/aws.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | import "time" 4 | 5 | // AWS specific constants used by other modules 6 | const ( 7 | // EBS related constants 8 | EBSVolumeIDStart = "/vol-" 9 | EBSProvisioner = "kubernetes.io/aws-ebs" 10 | EBSDriver = "ebs.csi.aws.com" 11 | //https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_VolumeModification.html 12 | EBSVolumeStateModifying = "modifying" 13 | EBSVolumeStateOptimizing = "optimizing" 14 | EBSVolumeStateFailed = "failed" 15 | EBSVolumeStateCompleted = "completed" 16 | EBSVolumeResizeWaitInterval = 2 * time.Second 17 | EBSVolumeResizeWaitTimeout = 30 * time.Second 18 | ) 19 | -------------------------------------------------------------------------------- /pkg/util/constants/kubernetes.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | import "time" 4 | 5 | // General kubernetes-related constants 6 | const ( 7 | PostgresContainerName = "postgres" 8 | K8sAPIPath = "/apis" 9 | 10 | QueueResyncPeriodPod = 5 * time.Minute 11 | QueueResyncPeriodTPR = 5 * time.Minute 12 | QueueResyncPeriodNode = 5 * time.Minute 13 | ) 14 | -------------------------------------------------------------------------------- /pkg/util/constants/pooler.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | // Connection pooler specific constants 4 | const ( 5 | ConnectionPoolerResourceSuffix = "pooler" 6 | ConnectionPoolerUserName = "pooler" 7 | ConnectionPoolerSchemaName = "pooler" 8 | ConnectionPoolerDefaultType = "pgbouncer" 9 | ConnectionPoolerDefaultMode = "transaction" 10 | ConnectionPoolerDefaultCpuRequest = "500m" 11 | ConnectionPoolerDefaultCpuLimit = "1" 12 | ConnectionPoolerDefaultMemoryRequest = "100Mi" 13 | ConnectionPoolerDefaultMemoryLimit = "100Mi" 14 | 15 | ConnectionPoolerContainer = 0 16 | ConnectionPoolerMaxDBConnections = 60 17 | ConnectionPoolerMaxClientConnections = 10000 18 | ConnectionPoolerMinInstances = 1 19 | ) 20 | -------------------------------------------------------------------------------- /pkg/util/constants/postgresql.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | import "time" 4 | 5 | // PostgreSQL specific constants 6 | const ( 7 | DataVolumeName = "pgdata" 8 | PostgresDataMount = "/home/postgres/pgdata" 9 | PostgresDataPath = PostgresDataMount + "/pgroot" 10 | 11 | PatroniPGParametersParameterName = "parameters" 12 | 13 | PostgresConnectRetryTimeout = 2 * time.Minute 14 | PostgresConnectTimeout = 15 * time.Second 15 | 16 | ShmVolumeName = "dshm" 17 | ShmVolumePath = "/dev/shm" 18 | 19 | RunVolumeName = "postgresql-run" 20 | RunVolumePath = "/var/run/postgresql" 21 | ) 22 | -------------------------------------------------------------------------------- /pkg/util/constants/roles.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | // Roles specific constants 4 | const ( 5 | PasswordLength = 64 6 | SuperuserKeyName = "superuser" 7 | ReplicationUserKeyName = "replication" 8 | ConnectionPoolerUserKeyName = "pooler" 9 | EventStreamUserKeyName = "streamer" 10 | RoleFlagSuperuser = "SUPERUSER" 11 | RoleFlagInherit = "INHERIT" 12 | RoleFlagLogin = "LOGIN" 13 | RoleFlagNoLogin = "NOLOGIN" 14 | RoleFlagCreateRole = "CREATEROLE" 15 | RoleFlagCreateDB = "CREATEDB" 16 | RoleFlagReplication = "REPLICATION" 17 | RoleFlagByPassRLS = "BYPASSRLS" 18 | OwnerRoleNameSuffix = "_owner" 19 | ReaderRoleNameSuffix = "_reader" 20 | WriterRoleNameSuffix = "_writer" 21 | UserRoleNameSuffix = "_user" 22 | DefaultSearchPath = "\"$user\"" 23 | RotationUserDateFormat = "060102" 24 | ) 25 | -------------------------------------------------------------------------------- /pkg/util/constants/streams.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | // PostgreSQL specific constants 4 | const ( 5 | EventStreamCRDApiVersion = "zalando.org/v1" 6 | EventStreamCRDKind = "FabricEventStream" 7 | EventStreamCRDName = "fabriceventstreams.zalando.org" 8 | EventStreamSourcePGType = "PostgresLogicalReplication" 9 | EventStreamSourceSlotPrefix = "fes" 10 | EventStreamSourcePluginType = "pgoutput" 11 | EventStreamSourceAuthType = "DatabaseAuthenticationSecret" 12 | EventStreamFlowPgGenericType = "PostgresWalToGenericNakadiEvent" 13 | EventStreamSinkNakadiType = "Nakadi" 14 | EventStreamRecoveryDLQType = "DeadLetter" 15 | EventStreamRecoveryIgnoreType = "Ignore" 16 | EventStreamRecoveryNoneType = "None" 17 | EventStreamRecoverySuffix = "dead-letter-queue" 18 | EventStreamCpuAnnotationKey = "fes.zalando.org/FES_CPU" 19 | EventStreamMemoryAnnotationKey = "fes.zalando.org/FES_MEMORY" 20 | ) 21 | -------------------------------------------------------------------------------- /pkg/util/constants/units.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | // Measurement-unit definitions 4 | const ( 5 | Gigabyte = 1073741824 6 | ) 7 | -------------------------------------------------------------------------------- /pkg/util/filesystems/ext234.go: -------------------------------------------------------------------------------- 1 | package filesystems 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | "strings" 7 | ) 8 | 9 | var ( 10 | ext2fsSuccessRegexp = regexp.MustCompile(`The filesystem on [/a-z0-9]+ is now \d+ \(\d+\w+\) blocks long.`) 11 | ) 12 | 13 | const ( 14 | ext2 = "ext2" 15 | ext3 = "ext3" 16 | ext4 = "ext4" 17 | resize2fs = "resize2fs" 18 | ) 19 | 20 | //Ext234Resize implements the FilesystemResizer interface for the ext4/3/2fs. 21 | type Ext234Resize struct { 22 | } 23 | 24 | // CanResizeFilesystem checks whether Ext234Resize can resize this filesystem. 25 | func (c *Ext234Resize) CanResizeFilesystem(fstype string) bool { 26 | return fstype == ext2 || fstype == ext3 || fstype == ext4 27 | } 28 | 29 | // ResizeFilesystem calls resize2fs to resize the filesystem if necessary. 30 | func (c *Ext234Resize) ResizeFilesystem(deviceName string, commandExecutor func(cmd string) (out string, err error)) error { 31 | command := fmt.Sprintf("%s %s 2>&1", resize2fs, deviceName) 32 | out, err := commandExecutor(command) 33 | if err != nil { 34 | return err 35 | } 36 | if strings.Contains(out, "Nothing to do") || 37 | (strings.Contains(out, "on-line resizing required") && ext2fsSuccessRegexp.MatchString(out)) { 38 | return nil 39 | } 40 | return fmt.Errorf("unrecognized output: %q, assuming error", out) 41 | } 42 | -------------------------------------------------------------------------------- /pkg/util/filesystems/filesystems.go: -------------------------------------------------------------------------------- 1 | package filesystems 2 | 3 | // FilesystemResizer has methods to work with resizing of a filesystem 4 | type FilesystemResizer interface { 5 | CanResizeFilesystem(fstype string) bool 6 | ResizeFilesystem(deviceName string, commandExecutor func(string) (out string, err error)) error 7 | } 8 | -------------------------------------------------------------------------------- /pkg/util/httpclient/httpclient.go: -------------------------------------------------------------------------------- 1 | package httpclient 2 | 3 | //go:generate mockgen -package mocks -destination=../../../mocks/$GOFILE -source=$GOFILE -build_flags=-mod=vendor 4 | 5 | import "net/http" 6 | 7 | // HTTPClient interface 8 | type HTTPClient interface { 9 | Do(req *http.Request) (*http.Response, error) 10 | Get(url string) (resp *http.Response, err error) 11 | } 12 | -------------------------------------------------------------------------------- /pkg/util/retryutil/retry_util.go: -------------------------------------------------------------------------------- 1 | package retryutil 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // RetryTicker is a wrapper aroung time.Tick, 9 | // that allows to mock its implementation 10 | type RetryTicker interface { 11 | Stop() 12 | Tick() 13 | } 14 | 15 | // Ticker is a real implementation of RetryTicker interface 16 | type Ticker struct { 17 | ticker *time.Ticker 18 | } 19 | 20 | // Stop is a convenience wrapper around ticker.Stop 21 | func (t *Ticker) Stop() { t.ticker.Stop() } 22 | 23 | // Tick is a convenience wrapper around ticker.C 24 | func (t *Ticker) Tick() { <-t.ticker.C } 25 | 26 | // Retry is a wrapper around RetryWorker that provides a real RetryTicker 27 | func Retry(interval time.Duration, timeout time.Duration, f func() (bool, error)) error { 28 | //TODO: make the retry exponential 29 | if timeout < interval { 30 | return fmt.Errorf("timeout(%s) should be greater than interval(%v)", timeout, interval) 31 | } 32 | tick := &Ticker{time.NewTicker(interval)} 33 | return RetryWorker(interval, timeout, tick, f) 34 | } 35 | 36 | // RetryWorker calls ConditionFunc until either: 37 | // * it returns boolean true 38 | // * a timeout expires 39 | // * an error occurs 40 | func RetryWorker( 41 | interval time.Duration, 42 | timeout time.Duration, 43 | tick RetryTicker, 44 | f func() (bool, error)) error { 45 | 46 | maxRetries := int(timeout / interval) 47 | defer tick.Stop() 48 | 49 | for i := 0; ; i++ { 50 | ok, err := f() 51 | if err != nil { 52 | return err 53 | } 54 | if ok { 55 | return nil 56 | } 57 | if i+1 == maxRetries { 58 | break 59 | } 60 | tick.Tick() 61 | } 62 | return fmt.Errorf("still failing after %d retries", maxRetries) 63 | } 64 | -------------------------------------------------------------------------------- /pkg/util/retryutil/retry_util_test.go: -------------------------------------------------------------------------------- 1 | package retryutil 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | ) 7 | 8 | type mockTicker struct { 9 | test *testing.T 10 | counter int 11 | } 12 | 13 | func (t *mockTicker) Stop() {} 14 | 15 | func (t *mockTicker) Tick() { 16 | t.counter++ 17 | } 18 | 19 | func TestRetryWorkerSuccess(t *testing.T) { 20 | tick := &mockTicker{t, 0} 21 | result := RetryWorker(10, 20, tick, func() (bool, error) { 22 | return true, nil 23 | }) 24 | 25 | if result != nil { 26 | t.Errorf("Wrong result, expected: %#v, got: %#v", nil, result) 27 | } 28 | 29 | if tick.counter != 0 { 30 | t.Errorf("Ticker was started once, but it shouldn't be") 31 | } 32 | } 33 | 34 | func TestRetryWorkerOneFalse(t *testing.T) { 35 | var counter = 0 36 | 37 | tick := &mockTicker{t, 0} 38 | result := RetryWorker(1, 3, tick, func() (bool, error) { 39 | counter++ 40 | return counter > 1, nil 41 | }) 42 | 43 | if result != nil { 44 | t.Errorf("Wrong result, expected: %#v, got: %#v", nil, result) 45 | } 46 | 47 | if tick.counter != 1 { 48 | t.Errorf("Ticker was started %#v, but supposed to be just once", tick.counter) 49 | } 50 | } 51 | 52 | func TestRetryWorkerError(t *testing.T) { 53 | fail := errors.New("Error") 54 | 55 | tick := &mockTicker{t, 0} 56 | result := RetryWorker(1, 3, tick, func() (bool, error) { 57 | return false, fail 58 | }) 59 | 60 | if result != fail { 61 | t.Errorf("Wrong result, expected: %#v, got: %#v", fail, result) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /pkg/util/ringlog/ringlog.go: -------------------------------------------------------------------------------- 1 | package ringlog 2 | 3 | import ( 4 | "container/list" 5 | "sync" 6 | ) 7 | 8 | // RingLogger describes ring logger methods 9 | type RingLogger interface { 10 | Insert(interface{}) 11 | Walk() []interface{} 12 | } 13 | 14 | // RingLog is a capped logger with fixed size 15 | type RingLog struct { 16 | sync.RWMutex 17 | size int 18 | list *list.List 19 | } 20 | 21 | // New creates new Ring logger 22 | func New(size int) *RingLog { 23 | r := RingLog{ 24 | list: list.New(), 25 | size: size, 26 | } 27 | 28 | return &r 29 | } 30 | 31 | // Insert inserts new entry into the ring logger 32 | func (r *RingLog) Insert(obj interface{}) { 33 | r.Lock() 34 | defer r.Unlock() 35 | 36 | r.list.PushBack(obj) 37 | if r.list.Len() > r.size { 38 | r.list.Remove(r.list.Front()) 39 | } 40 | } 41 | 42 | // Walk dumps all the entries from the Ring logger 43 | func (r *RingLog) Walk() []interface{} { 44 | res := make([]interface{}, 0) 45 | 46 | r.RLock() 47 | defer r.RUnlock() 48 | 49 | st := r.list.Front() 50 | for i := 0; i < r.size; i++ { 51 | if st == nil { 52 | return res 53 | } 54 | res = append(res, st.Value) 55 | st = st.Next() 56 | } 57 | 58 | return res 59 | } 60 | -------------------------------------------------------------------------------- /pkg/util/volumes/volumes.go: -------------------------------------------------------------------------------- 1 | package volumes 2 | 3 | //go:generate mockgen -package mocks -destination=../../../mocks/$GOFILE -source=$GOFILE -build_flags=-mod=vendor 4 | 5 | import v1 "k8s.io/api/core/v1" 6 | 7 | // VolumeProperties ... 8 | type VolumeProperties struct { 9 | VolumeID string 10 | VolumeType string 11 | Size int64 12 | Iops int64 13 | Throughput int64 14 | } 15 | 16 | // VolumeResizer defines the set of methods used to implememnt provider-specific resizing of persistent volumes. 17 | type VolumeResizer interface { 18 | ConnectToProvider() error 19 | IsConnectedToProvider() bool 20 | VolumeBelongsToProvider(pv *v1.PersistentVolume) bool 21 | GetProviderVolumeID(pv *v1.PersistentVolume) (string, error) 22 | ExtractVolumeID(volumeID string) (string, error) 23 | ResizeVolume(providerVolumeID string, newSize int64) error 24 | ModifyVolume(providerVolumeID string, newType *string, newSize *int64, iops *int64, throughput *int64) error 25 | DisconnectFromProvider() error 26 | DescribeVolumes(providerVolumesID []string) ([]VolumeProperties, error) 27 | } 28 | -------------------------------------------------------------------------------- /pkg/util/volumes/volumes_test.go: -------------------------------------------------------------------------------- 1 | package volumes 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestExtractVolumeID(t *testing.T) { 9 | var tests = []struct { 10 | input string 11 | expectedResult string 12 | expectedErr error 13 | }{ 14 | { 15 | input: "aws://eu-central-1c/vol-01234a5b6c78df9gh", 16 | expectedResult: "vol-01234a5b6c78df9gh", 17 | expectedErr: nil, 18 | }, 19 | { 20 | input: "vol-0g9fd87c6b5a43210", 21 | expectedResult: "vol-0g9fd87c6b5a43210", 22 | expectedErr: nil, 23 | }, 24 | { 25 | input: "aws://eu-central-1c/01234a5b6c78df9g0", 26 | expectedResult: "", 27 | expectedErr: fmt.Errorf("malformed EBS volume id %q", "aws://eu-central-1c/01234a5b6c78df9g0"), 28 | }, 29 | { 30 | input: "hg9fd87c6b5a43210", 31 | expectedResult: "", 32 | expectedErr: fmt.Errorf("malformed EBS volume id %q", "hg9fd87c6b5a43210"), 33 | }, 34 | } 35 | 36 | resizer := EBSVolumeResizer{} 37 | 38 | for _, tt := range tests { 39 | volumeId, err := resizer.ExtractVolumeID(tt.input) 40 | if volumeId != tt.expectedResult { 41 | t.Errorf("%s expected: %s, got %s", t.Name(), tt.expectedResult, volumeId) 42 | } 43 | if err != tt.expectedErr { 44 | if tt.expectedErr != nil && err.Error() != tt.expectedErr.Error() { 45 | t.Errorf("%s unexpected error: got %v", t.Name(), err) 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ui/.dockerignore: -------------------------------------------------------------------------------- 1 | *# 2 | *.pyc 3 | *~ 4 | .*.sw? 5 | .git 6 | __pycache__ 7 | 8 | .npm/ 9 | 10 | app/node_modules 11 | operator_ui/static/build/*.hot-update.js 12 | operator_ui/static/build/*.hot-update.json 13 | -------------------------------------------------------------------------------- /ui/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE=registry.opensource.zalan.do/library/python-3.11-slim:latest 2 | ARG NODE_IMAGE=node:lts-alpine 3 | 4 | FROM $NODE_IMAGE AS build 5 | 6 | COPY . /workdir 7 | WORKDIR /workdir/app 8 | 9 | RUN npm install \ 10 | && npm run build 11 | 12 | FROM $BASE_IMAGE 13 | LABEL maintainer="Team ACID @ Zalando <team-acid@zalando.de>" 14 | 15 | EXPOSE 8081 16 | WORKDIR /app 17 | 18 | RUN apt-get -qq -y update \ 19 | # https://www.psycopg.org/docs/install.html#psycopg-vs-psycopg-binary 20 | && apt-get -qq -y install --no-install-recommends g++ libpq-dev python3-dev python3-distutils \ 21 | && apt-get -qq -y clean \ 22 | && rm -rf /var/lib/apt/lists/* 23 | 24 | COPY requirements.txt . 25 | COPY start_server.sh . 26 | RUN pip install -r requirements.txt 27 | 28 | COPY operator_ui operator_ui/ 29 | COPY --from=build /workdir/operator_ui/static/build/ operator_ui/static/build/ 30 | 31 | ARG VERSION=dev 32 | RUN sed -i "s/__version__ = .*/__version__ = '${VERSION}'/" operator_ui/__init__.py 33 | 34 | CMD ["python", "-m", "operator_ui"] 35 | -------------------------------------------------------------------------------- /ui/MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include operator_ui/static * 2 | recursive-include operator_ui/templates * 3 | include *.rst 4 | -------------------------------------------------------------------------------- /ui/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean test appjs docker push mock 2 | 3 | IMAGE ?= registry.opensource.zalan.do/acid/postgres-operator-ui 4 | VERSION ?= $(shell git describe --tags --always --dirty) 5 | TAG ?= $(VERSION) 6 | GITHEAD = $(shell git rev-parse --short HEAD) 7 | GITURL = $(shell git config --get remote.origin.url) 8 | GITSTATUS = $(shell git status --porcelain || echo 'no changes') 9 | TTYFLAGS = $(shell test -t 0 && echo '-it') 10 | 11 | ifdef CDP_PULL_REQUEST_NUMBER 12 | CDP_TAG := -${CDP_BUILD_VERSION} 13 | endif 14 | 15 | default: docker 16 | 17 | clean: 18 | rm -fr operator_ui/static/build 19 | 20 | test: 21 | tox 22 | 23 | appjs: 24 | docker run $(TTYFLAGS) -u $(id -u) -v $(pwd):/workdir -w /workdir/app node:lts-alpine npm install --cache /workdir/.npm 25 | docker run $(TTYFLAGS) -u $(id -u) -v $(pwd):/workdir -w /workdir/app node:lts-alpine npm run build --cache /workdir/.npm 26 | 27 | docker: appjs 28 | echo `(env)` 29 | echo "Tag ${TAG}" 30 | echo "Version ${VERSION}" 31 | echo "CDP tag ${CDP_TAG}" 32 | echo "git describe $(shell git describe --tags --always --dirty)" 33 | docker build --rm -t "$(IMAGE):$(TAG)$(CDP_TAG)" -f Dockerfile . 34 | 35 | push: 36 | docker push "$(IMAGE):$(TAG)$(CDP_TAG)" 37 | 38 | mock: 39 | docker run -it -p 8081:8081 "$(IMAGE):$(TAG)" --mock 40 | -------------------------------------------------------------------------------- /ui/app/.eslintignore: -------------------------------------------------------------------------------- 1 | src/vendor/*.js 2 | -------------------------------------------------------------------------------- /ui/app/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | parserOptions: 2 | sourceType: module 3 | env: 4 | browser: true 5 | node: true 6 | es6: true 7 | extends: 'eslint:recommended' 8 | rules: 9 | indent: 10 | - error 11 | - 4 12 | linebreak-style: 13 | - error 14 | - unix 15 | quotes: 16 | - error 17 | - single 18 | prefer-const: 19 | - error 20 | no-redeclare: 21 | - error 22 | no-unused-vars: 23 | - warn 24 | - argsIgnorePattern: "^_" 25 | semi: 26 | - error 27 | - never 28 | -------------------------------------------------------------------------------- /ui/app/README.rst: -------------------------------------------------------------------------------- 1 | This directory contains the EcmaScript frontend code of the PostgreSQL Operator UI and is only needed during build time. 2 | 3 | The JavaScript application bundle (webpack) will be generated to ``operator_ui/static/build/app*.js`` by running: 4 | 5 | .. code-block:: bash 6 | 7 | $ npm install 8 | $ npm run build 9 | 10 | Frontend development is supported by watching the source code and continuously recompiling the webpack: 11 | 12 | .. code-block:: bash 13 | 14 | $ npm start 15 | -------------------------------------------------------------------------------- /ui/app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postgres-operator-ui", 3 | "version": "1.14.0", 4 | "description": "PostgreSQL Operator UI", 5 | "main": "src/app.js", 6 | "config": { 7 | "buildDir": "../operator_ui/static/build" 8 | }, 9 | "scripts": { 10 | "prestart": "npm install", 11 | "start": "NODE_ENV=development webpack --watch", 12 | "webpack": "webpack --config ./webpack.config.js", 13 | "build": "NODE_ENV=development npm run webpack", 14 | "prewebpack": "npm run clean", 15 | "lint": "eslint ./src/**/*.js", 16 | "clean": "rimraf $npm_package_config_buildDir && mkdir $npm_package_config_buildDir" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "git+https://github.com/zalando/postgres-operator.git" 21 | }, 22 | "author": "", 23 | "license": "ISC", 24 | "bugs": { 25 | "url": "https://github.com/zalando/postgres-operator.git/issues" 26 | }, 27 | "homepage": "https://github.com/zalando/postgres-operator.git#readme", 28 | "dependencies": { 29 | "@babel/core": "^7.20.12", 30 | "@babel/polyfill": "^7.12.1", 31 | "@babel/runtime": "^7.20.13", 32 | "pixi.js": "^7.1.1" 33 | }, 34 | "devDependencies": { 35 | "@babel/plugin-transform-runtime": "^7.19.6", 36 | "@babel/preset-env": "^7.20.2", 37 | "babel-loader": "^8.2.5", 38 | "brfs": "^2.0.2", 39 | "dedent-js": "1.0.1", 40 | "eslint": "^8.32.0", 41 | "js-yaml": "4.1.0", 42 | "pug": "^3.0.2", 43 | "rimraf": "^4.1.2", 44 | "riot": "^3.13.2", 45 | "riot-hot-reload": "1.0.0", 46 | "riot-route": "^3.1.4", 47 | "riot-tag-loader": "2.1.0", 48 | "sort-by": "^1.2.0", 49 | "transform-loader": "^0.2.4", 50 | "webpack": "^4.46.0", 51 | "webpack-cli": "^4.10.0" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ui/app/src/help-edit.tag.pug: -------------------------------------------------------------------------------- 1 | help-edit 2 | 3 | h2 Help 4 | 5 | .well 6 | 7 | h3(style='margin-top: 0') 8 | | Docs 9 | 10 | a(href="{ opts.config.docs_link }") 11 | | more... 12 | 13 | h3 Editing 14 | 15 | p. 16 | The text box shows you the properties that can currently edit. Verify that the preview shows a valid part of the spec before submitting. After a successful submit the changes may take some time to be applied. 17 | 18 | h3 Volume size 19 | 20 | p. 21 | You need to specify in format "123Gi". You can only increase the volume size. You can only increase volume size once very 6 hours, per AWS limitation. 22 | 23 | virtual( 24 | if='{ opts.config.static_network_whitelist && Object.keys(opts.config.static_network_whitelist).length > 0 }' 25 | ) 26 | h3 IP Ranges 27 | 28 | // Raw tags are required here, as otherwise either riotjs removes space it shouldn't, or pugjs adds space it shouldn't. And it has to be all in one line, as it has to be a pre tag (otherwise the riotjs compiler breaks the whitespace). 29 | <pre><virtual each="{ network, network_index in Object.keys(opts.config.static_network_whitelist) }"><virtual if="{ network_index > 0 }"><br></virtual> # { network }<br><virtual each="{ range, range_index in opts.config.static_network_whitelist[network] }"> - { range }<virtual if="index < network.length - 1"><br></virtual></virtual></virtual></pre> 30 | -------------------------------------------------------------------------------- /ui/app/src/help-general.tag.pug: -------------------------------------------------------------------------------- 1 | help-general 2 | 3 | h2 Help 4 | 5 | .well 6 | 7 | h3(style='margin-top: 0') 8 | | Docs 9 | 10 | a(href="{ opts.config.docs_link }") 11 | | more... 12 | 13 | h3 Basics 14 | 15 | p. 16 | The Postgres Operator will use your definition to create a new 17 | PostgreSQL cluster for you. You can either copy the yaml definition 18 | to a repositiory or hit create cluster (not available in prod). 19 | -------------------------------------------------------------------------------- /ui/app/src/logs.tag.pug: -------------------------------------------------------------------------------- 1 | logs 2 | 3 | h1.page-header(if='{ cluster_path }') 4 | nav(aria-label="breadcrumb") 5 | ol.breadcrumb 6 | 7 | li.breadcrumb-item 8 | a(href='./#/list') 9 | | PostgreSQL clusters 10 | 11 | li.breadcrumb-item 12 | a(href='./#/status/{ cluster_path }') 13 | | { qname } 14 | 15 | li.breadcrumb-item 16 | a(href='./#/logs/{ cluster_path }') 17 | | Logs 18 | 19 | .sk-spinner-pulse(if='{ logs === undefined }') 20 | 21 | .container-fluid(if='{ logs === null }') 22 | p 23 | | Error loading logs. Please 24 | | 25 | a(onclick="window.location.reload(true)") try again 26 | | 27 | | or 28 | | 29 | a(href="./") start over 30 | | . 31 | 32 | .container-fluid(if='{ logs }') 33 | 34 | table.table.table-hover 35 | 36 | tr(each='{ logs }') 37 | 38 | td(each='{ [levels[Level]] }') 39 | span.label.label-font-size(class='label-{ color_class }') 40 | | { label } 41 | 42 | td(style='white-space: pre') 43 | | { Time } 44 | 45 | td(style='font-family: monospace') 46 | | { Message } 47 | 48 | script. 49 | 50 | this.levels = { 51 | "panic": { label: "Panic" , color_class: "danger" }, 52 | "fatal": { label: "Fatal" , color_class: "danger" }, 53 | "error": { label: "Error" , color_class: "danger" }, 54 | "warning": { label: "Warning", color_class: "warning" }, 55 | "info": { label: "Info" , color_class: "primary" }, 56 | "debug": { label: "Debug" , color_class: "warning" }, 57 | } 58 | 59 | this.logs = undefined 60 | 61 | this.on('mount', () => { 62 | if ( 63 | this.namespace !== this.opts.namespace 64 | || this.clustername !== this.opts.clustername 65 | ) { 66 | const namespace = this.namespace = this.opts.namespace 67 | const clustername = this.clustername = this.opts.clustername 68 | const qname = this.qname = namespace + '/' + clustername 69 | const cluster_path = this.cluster_path = ( 70 | encodeURI(namespace) 71 | + '/' + encodeURI(clustername) 72 | ) 73 | ;( 74 | jQuery 75 | .get(`./operator/clusters/${cluster_path}/logs`) 76 | .done(logs => this.logs = logs.reverse()) 77 | .fail(() => this.logs = null) 78 | .always(() => this.update()) 79 | ) 80 | } 81 | }) 82 | -------------------------------------------------------------------------------- /ui/manifests/ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "networking.k8s.io/v1" 2 | kind: "Ingress" 3 | metadata: 4 | name: "postgres-operator-ui" 5 | namespace: "default" 6 | labels: 7 | application: "postgres-operator-ui" 8 | spec: 9 | # ingressClassName: "ingress-nginx" 10 | rules: 11 | - host: "ui.example.org" 12 | http: 13 | paths: 14 | - path: / 15 | pathType: Prefix 16 | backend: 17 | service: 18 | name: "postgres-operator-ui" 19 | port: 20 | number: 80 21 | -------------------------------------------------------------------------------- /ui/manifests/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - deployment.yaml 5 | - ingress.yaml 6 | - service.yaml 7 | - ui-service-account-rbac.yaml 8 | -------------------------------------------------------------------------------- /ui/manifests/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "v1" 2 | kind: "Service" 3 | metadata: 4 | name: "postgres-operator-ui" 5 | namespace: "default" 6 | labels: 7 | application: "postgres-operator-ui" 8 | spec: 9 | type: "ClusterIP" 10 | selector: 11 | name: "postgres-operator-ui" 12 | ports: 13 | - port: 80 14 | protocol: "TCP" 15 | targetPort: 8081 16 | -------------------------------------------------------------------------------- /ui/manifests/ui-service-account-rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: postgres-operator-ui 5 | namespace: default 6 | 7 | --- 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRole 10 | metadata: 11 | name: postgres-operator-ui 12 | rules: 13 | - apiGroups: 14 | - acid.zalan.do 15 | resources: 16 | - postgresqls 17 | verbs: 18 | - create 19 | - delete 20 | - get 21 | - list 22 | - patch 23 | - update 24 | - apiGroups: 25 | - "" 26 | resources: 27 | - pods 28 | verbs: 29 | - get 30 | - list 31 | - watch 32 | - apiGroups: 33 | - "" 34 | resources: 35 | - services 36 | verbs: 37 | - get 38 | - list 39 | - apiGroups: 40 | - apps 41 | resources: 42 | - deployments 43 | - statefulsets 44 | verbs: 45 | - get 46 | - list 47 | - apiGroups: 48 | - "" 49 | resources: 50 | - namespaces 51 | verbs: 52 | - get 53 | - list 54 | --- 55 | apiVersion: rbac.authorization.k8s.io/v1 56 | kind: ClusterRoleBinding 57 | metadata: 58 | name: postgres-operator-ui 59 | roleRef: 60 | apiGroup: rbac.authorization.k8s.io 61 | kind: ClusterRole 62 | name: postgres-operator-ui 63 | subjects: 64 | - kind: ServiceAccount 65 | name: postgres-operator-ui 66 | namespace: default 67 | -------------------------------------------------------------------------------- /ui/operator_ui/__init__.py: -------------------------------------------------------------------------------- 1 | # This version is replaced during release process. 2 | __version__ = '2017.0.dev1' 3 | -------------------------------------------------------------------------------- /ui/operator_ui/__main__.py: -------------------------------------------------------------------------------- 1 | from .main import main 2 | 3 | main() 4 | -------------------------------------------------------------------------------- /ui/operator_ui/adapters/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/ui/operator_ui/adapters/__init__.py -------------------------------------------------------------------------------- /ui/operator_ui/adapters/logger.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from logging.config import dictConfig 3 | 4 | dictConfig( 5 | { 6 | "version": 1, 7 | "disable_existing_loggers": True, 8 | "formatters": { 9 | "json": { 10 | "class": "pythonjsonlogger.jsonlogger.JsonFormatter", 11 | "format": "%(asctime)s %(levelname)s: %(message)s", 12 | } 13 | }, 14 | "handlers": { 15 | "stream_handler": { 16 | "class": "logging.StreamHandler", 17 | "formatter": "json", 18 | "stream": "ext://flask.logging.wsgi_errors_stream", 19 | } 20 | }, 21 | "root": { 22 | "level": "DEBUG", 23 | "handlers": ["stream_handler"] 24 | } 25 | } 26 | ) 27 | 28 | 29 | class Logger: 30 | def __init__(self): 31 | self.logger = logging.getLogger(__name__) 32 | 33 | def debug(self, msg: str, *args, **kwargs): 34 | self.logger.debug(msg, *args, **kwargs) 35 | 36 | def info(self, msg: str, *args, **kwargs): 37 | self.logger.info(msg, *args, **kwargs) 38 | 39 | def error(self, msg: str, *args, **kwargs): 40 | self.logger.error(msg, *args, **kwargs) 41 | 42 | def exception(self, msg: str, *args, **kwargs): 43 | self.logger.exception(msg, *args, **kwargs) 44 | 45 | 46 | logger = Logger() 47 | -------------------------------------------------------------------------------- /ui/operator_ui/backoff.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def expo(n: int, base=2, factor=1, max_value=None): 5 | """Exponential decay. 6 | 7 | Adapted from https://github.com/litl/backoff/blob/master/backoff.py (MIT License) 8 | 9 | Args: 10 | base: The mathematical base of the exponentiation operation 11 | factor: Factor to multiply the exponentation by. 12 | max_value: The maximum value to yield. Once the value in the 13 | true exponential sequence exceeds this, the value 14 | of max_value will forever after be yielded. 15 | """ 16 | a = factor * base ** n 17 | if max_value is None or a < max_value: 18 | return a 19 | else: 20 | return max_value 21 | 22 | 23 | def random_jitter(value, jitter=1): 24 | """Jitter the value a random number of milliseconds. 25 | 26 | Copied from https://github.com/litl/backoff/blob/master/backoff.py (MIT License) 27 | 28 | This adds up to 1 second of additional time to the original value. 29 | Prior to backoff version 1.2 this was the default jitter behavior. 30 | Args: 31 | value: The unadulterated backoff value. 32 | """ 33 | return value + random.uniform(0, jitter) 34 | 35 | 36 | def full_jitter(value): 37 | """Jitter the value across the full range (0 to value). 38 | 39 | Copied from https://github.com/litl/backoff/blob/master/backoff.py (MIT License) 40 | 41 | This corresponds to the "Full Jitter" algorithm specified in the 42 | AWS blog's post on the performance of various jitter algorithms. 43 | (http://www.awsarchitectureblog.com/2015/03/backoff.html) 44 | 45 | Args: 46 | value: The unadulterated backoff value. 47 | """ 48 | return random.uniform(0, value) 49 | -------------------------------------------------------------------------------- /ui/operator_ui/mock.py: -------------------------------------------------------------------------------- 1 | import time 2 | import json 3 | import request 4 | 5 | 6 | class MockCluster: 7 | 8 | def get_pods(self): 9 | return [{"name": "cluster-1-XFF", "role": "master", "ip": "localhost", "port": "8080"}, 10 | {"name": "cluster-1-XFE", "role": "replica", "ip": "localhost", "port": "8080"}, 11 | {"name": "cluster-1-XFS", "role": "replica", "ip": "localhost", "port": "8080"}, 12 | {"name": "cluster-2-SJE", "role": "master", "ip": "localhost", "port": "8080"}] 13 | -------------------------------------------------------------------------------- /ui/operator_ui/static/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zalando/postgres-operator/51135b07db0fb81f5fe5e6f2eab1d4d894f64cd4/ui/operator_ui/static/favicon-96x96.png -------------------------------------------------------------------------------- /ui/operator_ui/static/prism.css: -------------------------------------------------------------------------------- 1 | /* http://prismjs.com/download.html?themes=prism&languages=yaml */ 2 | /** 3 | * prism.js default theme for JavaScript, CSS and HTML 4 | * Based on dabblet (http://dabblet.com) 5 | * @author Lea Verou 6 | */ 7 | 8 | code[class*="language-"], 9 | pre[class*="language-"] { 10 | color: black; 11 | background: none; 12 | text-shadow: 0 1px white; 13 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 14 | text-align: left; 15 | white-space: pre; 16 | word-spacing: normal; 17 | word-break: normal; 18 | word-wrap: normal; 19 | line-height: 1.5; 20 | 21 | -moz-tab-size: 4; 22 | -o-tab-size: 4; 23 | tab-size: 4; 24 | 25 | -webkit-hyphens: none; 26 | -moz-hyphens: none; 27 | -ms-hyphens: none; 28 | hyphens: none; 29 | } 30 | 31 | pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, 32 | code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { 33 | text-shadow: none; 34 | background: #b3d4fc; 35 | } 36 | 37 | pre[class*="language-"]::selection, pre[class*="language-"] ::selection, 38 | code[class*="language-"]::selection, code[class*="language-"] ::selection { 39 | text-shadow: none; 40 | background: #b3d4fc; 41 | } 42 | 43 | @media print { 44 | code[class*="language-"], 45 | pre[class*="language-"] { 46 | text-shadow: none; 47 | } 48 | } 49 | 50 | /* Code blocks */ 51 | pre[class*="language-"] { 52 | padding: 1em; 53 | margin: .5em 0; 54 | overflow: auto; 55 | } 56 | 57 | :not(pre) > code[class*="language-"], 58 | pre[class*="language-"] { 59 | background: #f5f2f0; 60 | } 61 | 62 | /* Inline code */ 63 | :not(pre) > code[class*="language-"] { 64 | padding: .1em; 65 | border-radius: .3em; 66 | white-space: normal; 67 | } 68 | 69 | .token.comment, 70 | .token.prolog, 71 | .token.doctype, 72 | .token.cdata { 73 | color: slategray; 74 | } 75 | 76 | .token.punctuation { 77 | color: #999; 78 | } 79 | 80 | .namespace { 81 | opacity: .7; 82 | } 83 | 84 | .token.property, 85 | .token.tag, 86 | .token.boolean, 87 | .token.number, 88 | .token.constant, 89 | .token.symbol, 90 | .token.deleted { 91 | color: #905; 92 | } 93 | 94 | .token.selector, 95 | .token.attr-name, 96 | .token.string, 97 | .token.char, 98 | .token.builtin, 99 | .token.inserted { 100 | color: #690; 101 | } 102 | 103 | .token.operator, 104 | .token.entity, 105 | .token.url, 106 | .language-css .token.string, 107 | .style .token.string { 108 | color: #a67f59; 109 | background: hsla(0, 0%, 100%, .5); 110 | } 111 | 112 | .token.atrule, 113 | .token.attr-value, 114 | .token.keyword { 115 | color: #07a; 116 | } 117 | 118 | .token.function { 119 | color: #DD4A68; 120 | } 121 | 122 | .token.regex, 123 | .token.important, 124 | .token.variable { 125 | color: #e90; 126 | } 127 | 128 | .token.important, 129 | .token.bold { 130 | font-weight: bold; 131 | } 132 | .token.italic { 133 | font-style: italic; 134 | } 135 | 136 | .token.entity { 137 | cursor: help; 138 | } 139 | 140 | -------------------------------------------------------------------------------- /ui/operator_ui/static/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 70px; 3 | } 4 | 5 | h1, h2, h3 { 6 | font-family: 'Open Sans', sans-serif; 7 | } 8 | 9 | .font-robot { 10 | font-family: 'Roboto 300', sans-serif; 11 | } 12 | 13 | input:invalid { 14 | color: red; 15 | font-weight: 600; 16 | } 17 | 18 | ul.ips { list-style-type: none; margin: 0; padding: 0; overflow-x: hidden; } 19 | ul.ips li { margin: 0; padding: 0; } 20 | ul.ips label { margin: 0; padding: 0; } 21 | 22 | .panel-heading.collapsible { 23 | cursor: pointer; 24 | } 25 | 26 | .timeline { 27 | cursor: pointer; 28 | } 29 | 30 | .panel-heading .collapsible:after { 31 | color: grey; 32 | content: "\e113"; 33 | float: right; 34 | font-family: 'Glyphicons Halflings'; 35 | transition: all 0.5s; 36 | } 37 | 38 | .panel-heading.collapsed .collapsible:after { 39 | transform: rotate(-180deg); 40 | } 41 | 42 | :not(form):invalid,select.owner:disabled { 43 | border: 1px solid red; 44 | box-shadow: 0 0 10px red; 45 | } 46 | 47 | .page-header { 48 | margin-top: 0px; 49 | } 50 | 51 | .page-header h1 { 52 | margin-top: 0px; 53 | } 54 | 55 | label { 56 | font-weight: normal; 57 | margin-top: 0; 58 | } 59 | 60 | .sk-spinner-pulse { 61 | background-color: darkblue; 62 | } 63 | 64 | td { 65 | vertical-align: middle !important; 66 | } 67 | 68 | .tooltip { 69 | position: relative; 70 | display: inline-block; 71 | opacity: 1; 72 | font-size: 14px; 73 | font-weight: bold; 74 | z-index: 0; 75 | } 76 | .tooltip:after { 77 | content: '?'; 78 | display: inline-block; 79 | font-family: sans-serif; 80 | font-weight: bold; 81 | text-align: center; 82 | width: 16px; 83 | height: 16px; 84 | font-size: 12px; 85 | line-height: 16px; 86 | border-radius: 12px; 87 | padding: 0px; 88 | color: white; 89 | background: black; 90 | border: 1px solid black; 91 | } 92 | .tooltip .tooltiptext { 93 | visibility: hidden; 94 | width: 250px; 95 | background-color: white; 96 | color: #000; 97 | text-align: justify; 98 | border-radius: 6px; 99 | padding: 10px 10px; 100 | position: absolute; 101 | bottom: 150%; 102 | left: 50%; 103 | margin-left: -120px; 104 | border: 1px solid black; 105 | font-weight: normal; 106 | } 107 | .tooltip .tooltiptext::after { 108 | content: ""; 109 | position: absolute; 110 | top: 100%; 111 | left: 50%; 112 | margin-left: -5px; 113 | border-width: 5px; 114 | border-style: solid; 115 | border-color: black transparent transparent transparent; 116 | } 117 | .tooltip:hover .tooltiptext { 118 | visibility: visible; 119 | } 120 | -------------------------------------------------------------------------------- /ui/operator_ui/update.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import time 3 | 4 | import gevent 5 | import json_delta 6 | import requests.exceptions 7 | 8 | from .backoff import expo, random_jitter 9 | from .utils import get_short_error_message 10 | 11 | logger = logging.getLogger(__name__) 12 | 13 | -------------------------------------------------------------------------------- /ui/requirements.txt: -------------------------------------------------------------------------------- 1 | backoff==2.2.1 2 | boto3==1.34.110 3 | boto==2.49.0 4 | click==8.1.7 5 | Flask==3.0.3 6 | furl==2.1.3 7 | gevent==24.2.1 8 | jq==1.7.0 9 | json_delta>=2.0.2 10 | kubernetes==11.0.0 11 | python-json-logger==2.0.7 12 | requests==2.32.2 13 | stups-tokens>=1.1.19 14 | werkzeug==3.0.6 15 | -------------------------------------------------------------------------------- /ui/setup.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from setuptools import find_packages, setup 4 | from setuptools.command.test import test as TestCommand 5 | 6 | from pathlib import Path 7 | 8 | 9 | def read_version(package): 10 | with (Path(package) / '__init__.py').open() as fd: 11 | for line in fd: 12 | if line.startswith('__version__ = '): 13 | return line.split()[-1].strip().strip("'") 14 | 15 | 16 | version = read_version('operator_ui') 17 | 18 | 19 | class PyTest(TestCommand): 20 | 21 | user_options = [('cov-html=', None, 'Generate junit html report')] 22 | 23 | def initialize_options(self): 24 | TestCommand.initialize_options(self) 25 | self.cov = None 26 | self.pytest_args = ['--cov', 'operator_ui', '--cov-report', 'term-missing', '-v'] 27 | self.cov_html = False 28 | 29 | def finalize_options(self): 30 | TestCommand.finalize_options(self) 31 | if self.cov_html: 32 | self.pytest_args.extend(['--cov-report', 'html']) 33 | self.pytest_args.extend(['tests']) 34 | 35 | def run_tests(self): 36 | import pytest 37 | 38 | errno = pytest.main(self.pytest_args) 39 | sys.exit(errno) 40 | 41 | 42 | def readme(): 43 | return open('README.rst', encoding='utf-8').read() 44 | 45 | 46 | tests_require = [ 47 | 'pytest', 48 | 'pytest-cov' 49 | ] 50 | 51 | setup( 52 | name='operator-ui', 53 | packages=find_packages(), 54 | version=version, 55 | description='PostgreSQL Kubernetes Operator UI', 56 | long_description=readme(), 57 | author='team-acid@zalando.de', 58 | url='https://github.com/postgres-operator', 59 | keywords='PostgreSQL Kubernetes Operator UI', 60 | license='MIT', 61 | tests_require=tests_require, 62 | extras_require={'tests': tests_require}, 63 | cmdclass={'test': PyTest}, 64 | test_suite='tests', 65 | classifiers=[ 66 | 'Development Status :: 3', 67 | 'Intended Audience :: Developers', 68 | 'Intended Audience :: System Administrators', 69 | 'License :: OSI Approved :: MIT', 70 | 'Operating System :: OS Independent', 71 | 'Programming Language :: Python', 72 | 'Programming Language :: Python :: 3.11', 73 | 'Topic :: System :: Clustering', 74 | 'Topic :: System :: Monitoring', 75 | ], 76 | include_package_data=True, # needed to include JavaScript (see MANIFEST.in) 77 | entry_points={'console_scripts': ['operator-ui = operator_ui.main:main']} 78 | ) 79 | -------------------------------------------------------------------------------- /ui/start_server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | /usr/bin/python3 -m operator_ui 3 | -------------------------------------------------------------------------------- /ui/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist=py35,flake8,eslint 3 | 4 | [tox:travis] 5 | 3.5=py35,flake8,eslint 6 | 7 | [testenv] 8 | deps=pytest 9 | commands= 10 | pip install -r requirements.txt 11 | python setup.py test 12 | 13 | [testenv:flake8] 14 | deps=flake8 15 | commands=python setup.py flake8 16 | 17 | [testenv:eslint] 18 | whitelist_externals=eslint 19 | changedir=app 20 | commands=eslint src 21 | 22 | [flake8] 23 | max-line-length=160 24 | ignore=E402 25 | 26 | [pylama] 27 | ignore=E402 28 | --------------------------------------------------------------------------------