Merge branch 'master' into bump-v1.5.0
This commit is contained in:
		
						commit
						af69afcbfe
					
				|  | @ -49,6 +49,11 @@ rules: | ||||||
|   - events |   - events | ||||||
|   verbs: |   verbs: | ||||||
|   - create |   - create | ||||||
|  |   - get | ||||||
|  |   - list | ||||||
|  |   - patch | ||||||
|  |   - update | ||||||
|  |   - watch | ||||||
| # to manage endpoints which are also used by Patroni | # to manage endpoints which are also used by Patroni | ||||||
| - apiGroups: | - apiGroups: | ||||||
|   - "" |   - "" | ||||||
|  |  | ||||||
							
								
								
									
										19
									
								
								docs/user.md
								
								
								
								
							
							
						
						
									
										19
									
								
								docs/user.md
								
								
								
								
							|  | @ -53,8 +53,19 @@ them. | ||||||
| 
 | 
 | ||||||
| ## Watch pods being created | ## Watch pods being created | ||||||
| 
 | 
 | ||||||
|  | Check if the database pods are coming up. Use the label `application=spilo` to | ||||||
|  | filter and list the label `spilo-role` to see when the master is promoted and | ||||||
|  | replicas get their labels. | ||||||
|  | 
 | ||||||
| ```bash | ```bash | ||||||
| kubectl get pods -w --show-labels | kubectl get pods -l application=spilo -L spilo-role -w | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | The operator also emits K8s events to the Postgresql CRD which can be inspected | ||||||
|  | in the operator logs or with: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | kubectl describe postgresql acid-minimal-cluster | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Connect to PostgreSQL | ## Connect to PostgreSQL | ||||||
|  | @ -736,14 +747,14 @@ spin up more instances). | ||||||
| 
 | 
 | ||||||
| ## Custom TLS certificates | ## Custom TLS certificates | ||||||
| 
 | 
 | ||||||
| By default, the spilo image generates its own TLS certificate during startup. | By default, the Spilo image generates its own TLS certificate during startup. | ||||||
| However, this certificate cannot be verified and thus doesn't protect from | However, this certificate cannot be verified and thus doesn't protect from | ||||||
| active MITM attacks. In this section we show how to specify a custom TLS | active MITM attacks. In this section we show how to specify a custom TLS | ||||||
| certificate which is mounted in the database pods via a K8s Secret. | certificate which is mounted in the database pods via a K8s Secret. | ||||||
| 
 | 
 | ||||||
| Before applying these changes, in k8s the operator must also be configured with | Before applying these changes, in k8s the operator must also be configured with | ||||||
| the `spilo_fsgroup` set to the GID matching the postgres user group. If you | the `spilo_fsgroup` set to the GID matching the postgres user group. If you | ||||||
| don't know the value, use `103` which is the GID from the default spilo image | don't know the value, use `103` which is the GID from the default Spilo image | ||||||
| (`spilo_fsgroup=103` in the cluster request spec). | (`spilo_fsgroup=103` in the cluster request spec). | ||||||
| 
 | 
 | ||||||
| OpenShift allocates the users and groups dynamically (based on scc), and their | OpenShift allocates the users and groups dynamically (based on scc), and their | ||||||
|  | @ -805,5 +816,5 @@ spec: | ||||||
| Alternatively, it is also possible to use | Alternatively, it is also possible to use | ||||||
| [cert-manager](https://cert-manager.io/docs/) to generate these secrets. | [cert-manager](https://cert-manager.io/docs/) to generate these secrets. | ||||||
| 
 | 
 | ||||||
| Certificate rotation is handled in the spilo image which checks every 5 | Certificate rotation is handled in the Spilo image which checks every 5 | ||||||
| minutes if the certificates have changed and reloads postgres accordingly. | minutes if the certificates have changed and reloads postgres accordingly. | ||||||
|  |  | ||||||
|  | @ -50,6 +50,11 @@ rules: | ||||||
|   - events |   - events | ||||||
|   verbs: |   verbs: | ||||||
|   - create |   - create | ||||||
|  |   - get | ||||||
|  |   - list | ||||||
|  |   - patch | ||||||
|  |   - update | ||||||
|  |   - watch | ||||||
| # to manage endpoints which are also used by Patroni | # to manage endpoints which are also used by Patroni | ||||||
| - apiGroups: | - apiGroups: | ||||||
|   - "" |   - "" | ||||||
|  |  | ||||||
|  | @ -76,7 +76,7 @@ func NewController(controllerConfig *spec.ControllerConfig, controllerId string) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	eventBroadcaster := record.NewBroadcaster() | 	eventBroadcaster := record.NewBroadcaster() | ||||||
| 	eventBroadcaster.StartLogging(logger.Debugf) | 	eventBroadcaster.StartLogging(logger.Infof) | ||||||
| 	recorder := eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: myComponentName}) | 	recorder := eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: myComponentName}) | ||||||
| 
 | 
 | ||||||
| 	c := &Controller{ | 	c := &Controller{ | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| FROM alpine:3.6 | FROM alpine:3.6 | ||||||
| MAINTAINER team-acid@zalando.de | MAINTAINER team-acid@zalando.de | ||||||
| 
 | 
 | ||||||
| EXPOSE 8080 | EXPOSE 8081 | ||||||
| 
 | 
 | ||||||
| RUN \ | RUN \ | ||||||
|   apk add --no-cache \ |   apk add --no-cache \ | ||||||
|  | @ -29,6 +29,7 @@ RUN \ | ||||||
|     /var/cache/apk/* |     /var/cache/apk/* | ||||||
| 
 | 
 | ||||||
| COPY requirements.txt / | COPY requirements.txt / | ||||||
|  | COPY start_server.sh / | ||||||
| RUN pip3 install -r /requirements.txt | RUN pip3 install -r /requirements.txt | ||||||
| 
 | 
 | ||||||
| COPY operator_ui /operator_ui | COPY operator_ui /operator_ui | ||||||
|  | @ -37,4 +38,4 @@ ARG VERSION=dev | ||||||
| RUN sed -i "s/__version__ = .*/__version__ = '${VERSION}'/" /operator_ui/__init__.py | RUN sed -i "s/__version__ = .*/__version__ = '${VERSION}'/" /operator_ui/__init__.py | ||||||
| 
 | 
 | ||||||
| WORKDIR / | WORKDIR / | ||||||
| ENTRYPOINT ["/usr/bin/python3", "-m", "operator_ui"] | CMD ["/usr/bin/python3", "-m", "operator_ui"] | ||||||
|  |  | ||||||
|  | @ -36,4 +36,4 @@ push: | ||||||
| 	docker push "$(IMAGE):$(TAG)$(CDP_TAG)" | 	docker push "$(IMAGE):$(TAG)$(CDP_TAG)" | ||||||
| 
 | 
 | ||||||
| mock: | mock: | ||||||
| 	docker run -it -p 8080:8080 "$(IMAGE):$(TAG)" --mock | 	docker run -it -p 8081:8081 "$(IMAGE):$(TAG)" --mock | ||||||
|  |  | ||||||
|  | @ -137,6 +137,7 @@ edit | ||||||
|         o.spec.numberOfInstances = i.spec.numberOfInstances |         o.spec.numberOfInstances = i.spec.numberOfInstances | ||||||
|         o.spec.enableMasterLoadBalancer = i.spec.enableMasterLoadBalancer || false |         o.spec.enableMasterLoadBalancer = i.spec.enableMasterLoadBalancer || false | ||||||
|         o.spec.enableReplicaLoadBalancer = i.spec.enableReplicaLoadBalancer || false |         o.spec.enableReplicaLoadBalancer = i.spec.enableReplicaLoadBalancer || false | ||||||
|  |         o.spec.enableConnectionPooler = i.spec.enableConnectionPooler || false | ||||||
|         o.spec.volume = { size: i.spec.volume.size } |         o.spec.volume = { size: i.spec.volume.size } | ||||||
| 
 | 
 | ||||||
|         if ('users' in i.spec && typeof i.spec.users === 'object') { |         if ('users' in i.spec && typeof i.spec.users === 'object') { | ||||||
|  |  | ||||||
|  | @ -239,6 +239,18 @@ new | ||||||
|                   | |                   | | ||||||
|                   | Enable replica ELB |                   | Enable replica ELB | ||||||
| 
 | 
 | ||||||
|  |             tr | ||||||
|  |               td Enable Connection Pool | ||||||
|  |               td | ||||||
|  |                 label | ||||||
|  |                   input( | ||||||
|  |                     type='checkbox' | ||||||
|  |                     value='{ enableConnectionPooler }' | ||||||
|  |                     onchange='{ toggleEnableConnectionPooler }' | ||||||
|  |                   ) | ||||||
|  |                   | | ||||||
|  |                   | Enable Connection Pool (using PGBouncer) | ||||||
|  | 
 | ||||||
|             tr |             tr | ||||||
|               td Volume size |               td Volume size | ||||||
|               td |               td | ||||||
|  | @ -493,6 +505,9 @@ new | ||||||
|         {{#if enableReplicaLoadBalancer}} |         {{#if enableReplicaLoadBalancer}} | ||||||
|         enableReplicaLoadBalancer: true |         enableReplicaLoadBalancer: true | ||||||
|         {{/if}} |         {{/if}} | ||||||
|  |         {{#if enableConnectionPooler}} | ||||||
|  |         enableConnectionPooler: true | ||||||
|  |         {{/if}} | ||||||
|         volume: |         volume: | ||||||
|           size: "{{ volumeSize }}Gi" |           size: "{{ volumeSize }}Gi" | ||||||
|         {{#if users}} |         {{#if users}} | ||||||
|  | @ -516,13 +531,14 @@ new | ||||||
|           - {{ odd }}/32 |           - {{ odd }}/32 | ||||||
|         {{/if}} |         {{/if}} | ||||||
| 
 | 
 | ||||||
|  |         {{#if resourcesVisible}} | ||||||
|         resources: |         resources: | ||||||
|           requests: |           requests: | ||||||
|             cpu: {{ cpu.state.request.state }}m |             cpu: {{ cpu.state.request.state }}m | ||||||
|             memory: {{ memory.state.request.state }}Mi |             memory: {{ memory.state.request.state }}Mi | ||||||
|           limits: |           limits: | ||||||
|             cpu: {{ cpu.state.limit.state }}m |             cpu: {{ cpu.state.limit.state }}m | ||||||
|             memory: {{ memory.state.limit.state }}Mi{{#if restoring}} |             memory: {{ memory.state.limit.state }}Mi{{/if}}{{#if restoring}} | ||||||
| 
 | 
 | ||||||
|         clone: |         clone: | ||||||
|           cluster: "{{ backup.state.name.state }}" |           cluster: "{{ backup.state.name.state }}" | ||||||
|  | @ -542,6 +558,7 @@ new | ||||||
|         instanceCount: this.instanceCount, |         instanceCount: this.instanceCount, | ||||||
|         enableMasterLoadBalancer: this.enableMasterLoadBalancer, |         enableMasterLoadBalancer: this.enableMasterLoadBalancer, | ||||||
|         enableReplicaLoadBalancer: this.enableReplicaLoadBalancer, |         enableReplicaLoadBalancer: this.enableReplicaLoadBalancer, | ||||||
|  |         enableConnectionPooler: this.enableConnectionPooler, | ||||||
|         volumeSize: this.volumeSize, |         volumeSize: this.volumeSize, | ||||||
|         users: this.users.valids, |         users: this.users.valids, | ||||||
|         databases: this.databases.valids, |         databases: this.databases.valids, | ||||||
|  | @ -552,6 +569,7 @@ new | ||||||
|         memory: this.memory, |         memory: this.memory, | ||||||
|         backup: this.backup, |         backup: this.backup, | ||||||
|         namespace: this.namespace, |         namespace: this.namespace, | ||||||
|  |         resourcesVisible: this.config.resources_visible, | ||||||
|         restoring: this.backup.state.type.state !== 'empty', |         restoring: this.backup.state.type.state !== 'empty', | ||||||
|         pitr: this.backup.state.type.state === 'pitr', |         pitr: this.backup.state.type.state === 'pitr', | ||||||
|       } |       } | ||||||
|  | @ -598,6 +616,10 @@ new | ||||||
|       this.enableReplicaLoadBalancer = !this.enableReplicaLoadBalancer |       this.enableReplicaLoadBalancer = !this.enableReplicaLoadBalancer | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     this.toggleEnableConnectionPooler = e => { | ||||||
|  |       this.enableConnectionPooler = !this.enableConnectionPooler | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     this.volumeChange = e => { |     this.volumeChange = e => { | ||||||
|       this.volumeSize = +e.target.value |       this.volumeSize = +e.target.value | ||||||
|     } |     } | ||||||
|  | @ -892,6 +914,7 @@ new | ||||||
|       this.odd = '' |       this.odd = '' | ||||||
|       this.enableMasterLoadBalancer = false |       this.enableMasterLoadBalancer = false | ||||||
|       this.enableReplicaLoadBalancer = false |       this.enableReplicaLoadBalancer = false | ||||||
|  |       this.enableConnectionPooler = false | ||||||
| 
 | 
 | ||||||
|       this.postgresqlVersion = this.postgresqlVersion = ( |       this.postgresqlVersion = this.postgresqlVersion = ( | ||||||
|         this.config.postgresql_versions[0] |         this.config.postgresql_versions[0] | ||||||
|  |  | ||||||
|  | @ -92,6 +92,8 @@ postgresql | ||||||
|         .alert.alert-success(if='{ progress.masterLabel }') PostgreSQL master available, label is attached |         .alert.alert-success(if='{ progress.masterLabel }') PostgreSQL master available, label is attached | ||||||
|         .alert.alert-success(if='{ progress.masterLabel && progress.dnsName }') PostgreSQL ready: <strong>{ progress.dnsName }</strong> |         .alert.alert-success(if='{ progress.masterLabel && progress.dnsName }') PostgreSQL ready: <strong>{ progress.dnsName }</strong> | ||||||
| 
 | 
 | ||||||
|  |         .alert.alert-success(if='{ progress.pooler }') Connection pooler deployment created | ||||||
|  | 
 | ||||||
|       .col-lg-3 |       .col-lg-3 | ||||||
|         help-general(config='{ opts.config }') |         help-general(config='{ opts.config }') | ||||||
| 
 | 
 | ||||||
|  | @ -122,9 +124,11 @@ postgresql | ||||||
|       jQuery.get( |       jQuery.get( | ||||||
|         '/postgresqls/' + this.cluster_path, |         '/postgresqls/' + this.cluster_path, | ||||||
|       ).done(data => { |       ).done(data => { | ||||||
|  |         this.progress.pooler = false | ||||||
|         this.progress.postgresql = true |         this.progress.postgresql = true | ||||||
|         this.progress.postgresqlManifest = data |         this.progress.postgresqlManifest = data | ||||||
|         this.progress.createdTimestamp = data.metadata.creationTimestamp |         this.progress.createdTimestamp = data.metadata.creationTimestamp | ||||||
|  |         this.progress.poolerEnabled = data.spec.enableConnectionPooler | ||||||
|         this.uid = this.progress.postgresqlManifest.metadata.uid |         this.uid = this.progress.postgresqlManifest.metadata.uid | ||||||
|         this.update() |         this.update() | ||||||
| 
 | 
 | ||||||
|  | @ -160,6 +164,11 @@ postgresql | ||||||
|                 this.progress.dnsName = data.metadata.name + '.' + data.metadata.namespace |                 this.progress.dnsName = data.metadata.name + '.' + data.metadata.namespace | ||||||
|               } |               } | ||||||
| 
 | 
 | ||||||
|  |               jQuery.get('/pooler/' + this.cluster_path).done(data => { | ||||||
|  |                 this.progress.pooler = {"url": ""} | ||||||
|  |                 this.update() | ||||||
|  |               }) | ||||||
|  | 
 | ||||||
|               this.update() |               this.update() | ||||||
|             }) |             }) | ||||||
|           }) |           }) | ||||||
|  |  | ||||||
|  | @ -44,6 +44,8 @@ spec: | ||||||
|               value: "http://postgres-operator:8080" |               value: "http://postgres-operator:8080" | ||||||
|             - name: "OPERATOR_CLUSTER_NAME_LABEL" |             - name: "OPERATOR_CLUSTER_NAME_LABEL" | ||||||
|               value: "cluster-name" |               value: "cluster-name" | ||||||
|  |             - name: "RESOURCES_VISIBLE" | ||||||
|  |               value: "False" | ||||||
|             - name: "TARGET_NAMESPACE" |             - name: "TARGET_NAMESPACE" | ||||||
|               value: "default" |               value: "default" | ||||||
|             - name: "TEAMS" |             - name: "TEAMS" | ||||||
|  |  | ||||||
|  | @ -39,6 +39,7 @@ rules: | ||||||
| - apiGroups: | - apiGroups: | ||||||
|   - apps |   - apps | ||||||
|   resources: |   resources: | ||||||
|  |   - deployments | ||||||
|   - statefulsets |   - statefulsets | ||||||
|   verbs: |   verbs: | ||||||
|   - get |   - get | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ from flask import ( | ||||||
| from flask_oauthlib.client import OAuth | from flask_oauthlib.client import OAuth | ||||||
| from functools import wraps | from functools import wraps | ||||||
| from gevent import sleep, spawn | from gevent import sleep, spawn | ||||||
| from gevent.wsgi import WSGIServer | from gevent.pywsgi import WSGIServer | ||||||
| from jq import jq | from jq import jq | ||||||
| from json import dumps, loads | from json import dumps, loads | ||||||
| from logging import DEBUG, ERROR, INFO, basicConfig, exception, getLogger | from logging import DEBUG, ERROR, INFO, basicConfig, exception, getLogger | ||||||
|  | @ -44,6 +44,7 @@ from .spiloutils import ( | ||||||
|     create_postgresql, |     create_postgresql, | ||||||
|     read_basebackups, |     read_basebackups, | ||||||
|     read_namespaces, |     read_namespaces, | ||||||
|  |     read_pooler, | ||||||
|     read_pods, |     read_pods, | ||||||
|     read_postgresql, |     read_postgresql, | ||||||
|     read_postgresqls, |     read_postgresqls, | ||||||
|  | @ -80,6 +81,7 @@ OPERATOR_CLUSTER_NAME_LABEL = getenv('OPERATOR_CLUSTER_NAME_LABEL', 'cluster-nam | ||||||
| OPERATOR_UI_CONFIG = getenv('OPERATOR_UI_CONFIG', '{}') | OPERATOR_UI_CONFIG = getenv('OPERATOR_UI_CONFIG', '{}') | ||||||
| OPERATOR_UI_MAINTENANCE_CHECK = getenv('OPERATOR_UI_MAINTENANCE_CHECK', '{}') | OPERATOR_UI_MAINTENANCE_CHECK = getenv('OPERATOR_UI_MAINTENANCE_CHECK', '{}') | ||||||
| READ_ONLY_MODE = getenv('READ_ONLY_MODE', False) in [True, 'true'] | READ_ONLY_MODE = getenv('READ_ONLY_MODE', False) in [True, 'true'] | ||||||
|  | RESOURCES_VISIBLE = getenv('RESOURCES_VISIBLE', True) | ||||||
| SPILO_S3_BACKUP_PREFIX = getenv('SPILO_S3_BACKUP_PREFIX', 'spilo/') | SPILO_S3_BACKUP_PREFIX = getenv('SPILO_S3_BACKUP_PREFIX', 'spilo/') | ||||||
| SUPERUSER_TEAM = getenv('SUPERUSER_TEAM', 'acid') | SUPERUSER_TEAM = getenv('SUPERUSER_TEAM', 'acid') | ||||||
| TARGET_NAMESPACE = getenv('TARGET_NAMESPACE') | TARGET_NAMESPACE = getenv('TARGET_NAMESPACE') | ||||||
|  | @ -312,6 +314,7 @@ DEFAULT_UI_CONFIG = { | ||||||
| def get_config(): | def get_config(): | ||||||
|     config = loads(OPERATOR_UI_CONFIG) or DEFAULT_UI_CONFIG |     config = loads(OPERATOR_UI_CONFIG) or DEFAULT_UI_CONFIG | ||||||
|     config['read_only_mode'] = READ_ONLY_MODE |     config['read_only_mode'] = READ_ONLY_MODE | ||||||
|  |     config['resources_visible'] = RESOURCES_VISIBLE | ||||||
|     config['superuser_team'] = SUPERUSER_TEAM |     config['superuser_team'] = SUPERUSER_TEAM | ||||||
|     config['target_namespace'] = TARGET_NAMESPACE |     config['target_namespace'] = TARGET_NAMESPACE | ||||||
| 
 | 
 | ||||||
|  | @ -397,6 +400,22 @@ def get_service(namespace: str, cluster: str): | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @app.route('/pooler/<namespace>/<cluster>') | ||||||
|  | @authorize | ||||||
|  | def get_list_poolers(namespace: str, cluster: str): | ||||||
|  | 
 | ||||||
|  |     if TARGET_NAMESPACE not in ['', '*', namespace]: | ||||||
|  |         return wrong_namespace() | ||||||
|  | 
 | ||||||
|  |     return respond( | ||||||
|  |         read_pooler( | ||||||
|  |             get_cluster(), | ||||||
|  |             namespace, | ||||||
|  |             "{}-pooler".format(cluster), | ||||||
|  |         ), | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| @app.route('/statefulsets/<namespace>/<cluster>') | @app.route('/statefulsets/<namespace>/<cluster>') | ||||||
| @authorize | @authorize | ||||||
| def get_list_clusters(namespace: str, cluster: str): | def get_list_clusters(namespace: str, cluster: str): | ||||||
|  | @ -587,6 +606,17 @@ def update_postgresql(namespace: str, cluster: str): | ||||||
| 
 | 
 | ||||||
|         spec['volume'] = {'size': size} |         spec['volume'] = {'size': size} | ||||||
| 
 | 
 | ||||||
|  |     if 'enableConnectionPooler' in postgresql['spec']: | ||||||
|  |         cp = postgresql['spec']['enableConnectionPooler'] | ||||||
|  |         if not cp: | ||||||
|  |             if 'enableConnectionPooler' in o['spec']: | ||||||
|  |                 del o['spec']['enableConnectionPooler'] | ||||||
|  |         else: | ||||||
|  |             spec['enableConnectionPooler'] = True | ||||||
|  |     else: | ||||||
|  |         if 'enableConnectionPooler' in o['spec']: | ||||||
|  |             del o['spec']['enableConnectionPooler'] | ||||||
|  | 
 | ||||||
|     if 'enableReplicaLoadBalancer' in postgresql['spec']: |     if 'enableReplicaLoadBalancer' in postgresql['spec']: | ||||||
|         rlb = postgresql['spec']['enableReplicaLoadBalancer'] |         rlb = postgresql['spec']['enableReplicaLoadBalancer'] | ||||||
|         if not rlb: |         if not rlb: | ||||||
|  | @ -1006,7 +1036,7 @@ def init_cluster(): | ||||||
| def main(port, secret_key, debug, clusters: list): | def main(port, secret_key, debug, clusters: list): | ||||||
|     global TARGET_NAMESPACE |     global TARGET_NAMESPACE | ||||||
| 
 | 
 | ||||||
|     basicConfig(level=DEBUG if debug else INFO) |     basicConfig(stream=sys.stdout, level=(DEBUG if debug else INFO), format='%(asctime)s %(levelname)s: %(message)s',) | ||||||
| 
 | 
 | ||||||
|     init_cluster() |     init_cluster() | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| from boto3 import client | from boto3 import client | ||||||
| from datetime import datetime, timezone | from datetime import datetime, timezone | ||||||
| from furl import furl | from furl import furl | ||||||
| from json import dumps | from json import dumps, loads | ||||||
| from logging import getLogger | from logging import getLogger | ||||||
| from os import environ, getenv | from os import environ, getenv | ||||||
| from requests import Session | from requests import Session | ||||||
|  | @ -18,6 +18,15 @@ session = Session() | ||||||
| 
 | 
 | ||||||
| OPERATOR_CLUSTER_NAME_LABEL = getenv('OPERATOR_CLUSTER_NAME_LABEL', 'cluster-name') | OPERATOR_CLUSTER_NAME_LABEL = getenv('OPERATOR_CLUSTER_NAME_LABEL', 'cluster-name') | ||||||
| 
 | 
 | ||||||
|  | COMMON_CLUSTER_LABEL = getenv('COMMON_CLUSTER_LABEL', '{"application":"spilo"}') | ||||||
|  | COMMON_POOLER_LABEL = getenv('COMMONG_POOLER_LABEL', '{"application":"db-connection-pooler"}') | ||||||
|  | 
 | ||||||
|  | logger.info("Common Cluster Label: {}".format(COMMON_CLUSTER_LABEL)) | ||||||
|  | logger.info("Common Pooler Label: {}".format(COMMON_POOLER_LABEL)) | ||||||
|  | 
 | ||||||
|  | COMMON_CLUSTER_LABEL = loads(COMMON_CLUSTER_LABEL) | ||||||
|  | COMMON_POOLER_LABEL = loads(COMMON_POOLER_LABEL) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| def request(cluster, path, **kwargs): | def request(cluster, path, **kwargs): | ||||||
|     if 'timeout' not in kwargs: |     if 'timeout' not in kwargs: | ||||||
|  | @ -85,6 +94,7 @@ def resource_api_version(resource_type): | ||||||
|     return { |     return { | ||||||
|         'postgresqls': 'apis/acid.zalan.do/v1', |         'postgresqls': 'apis/acid.zalan.do/v1', | ||||||
|         'statefulsets': 'apis/apps/v1', |         'statefulsets': 'apis/apps/v1', | ||||||
|  |         'deployments': 'apis/apps/v1', | ||||||
|     }.get(resource_type, 'api/v1') |     }.get(resource_type, 'api/v1') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -149,7 +159,7 @@ def read_pod(cluster, namespace, resource_name): | ||||||
|         resource_type='pods', |         resource_type='pods', | ||||||
|         namespace=namespace, |         namespace=namespace, | ||||||
|         resource_name=resource_name, |         resource_name=resource_name, | ||||||
|         label_selector={'application': 'spilo'}, |         label_selector=COMMON_CLUSTER_LABEL, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -159,7 +169,17 @@ def read_service(cluster, namespace, resource_name): | ||||||
|         resource_type='services', |         resource_type='services', | ||||||
|         namespace=namespace, |         namespace=namespace, | ||||||
|         resource_name=resource_name, |         resource_name=resource_name, | ||||||
|         label_selector={'application': 'spilo'}, |         label_selector=COMMON_CLUSTER_LABEL, | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def read_pooler(cluster, namespace, resource_name): | ||||||
|  |     return kubernetes_get( | ||||||
|  |         cluster=cluster, | ||||||
|  |         resource_type='deployments', | ||||||
|  |         namespace=namespace, | ||||||
|  |         resource_name=resource_name, | ||||||
|  |         label_selector=COMMON_POOLER_LABEL, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -169,7 +189,7 @@ def read_statefulset(cluster, namespace, resource_name): | ||||||
|         resource_type='statefulsets', |         resource_type='statefulsets', | ||||||
|         namespace=namespace, |         namespace=namespace, | ||||||
|         resource_name=resource_name, |         resource_name=resource_name, | ||||||
|         label_selector={'application': 'spilo'}, |         label_selector=COMMON_CLUSTER_LABEL, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -302,7 +322,7 @@ def read_basebackups( | ||||||
|             f=configure_backup_cxt, |             f=configure_backup_cxt, | ||||||
|             aws_instance_profile=use_aws_instance_profile, |             aws_instance_profile=use_aws_instance_profile, | ||||||
|             s3_prefix=f's3://{bucket}/{prefix}{pg_cluster}{suffix}/wal/', |             s3_prefix=f's3://{bucket}/{prefix}{pg_cluster}{suffix}/wal/', | ||||||
|         )._backup_list(detail=True) |         )._backup_list(detail=True)._backup_list(prefix=f"{prefix}{pg_cluster}{suffix}/wal/") | ||||||
|     ] |     ] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| Flask-OAuthlib==0.9.5 | Flask-OAuthlib==0.9.5 | ||||||
| Flask==1.1.1 | Flask==1.1.2 | ||||||
| backoff==1.8.1 | backoff==1.8.1 | ||||||
| boto3==1.10.4 | boto3==1.10.4 | ||||||
| boto==2.49.0 | boto==2.49.0 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,2 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | /usr/bin/python3 -m operator_ui | ||||||
		Loading…
	
		Reference in New Issue