From a3a2805de0431a82a0de285fb25b67b670e406f8 Mon Sep 17 00:00:00 2001 From: "B. Heath Robinson" Date: Mon, 11 Aug 2014 14:05:17 -0500 Subject: [PATCH 01/13] Add wrapper to set SCRIPT_NAME from proxy header --- handyrep/hdaemon.wsgi | 37 +++++++++++++++++++++++++++++++++++- handyrepGUI/handyrepGUI.wsgi | 37 +++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/handyrep/hdaemon.wsgi b/handyrep/hdaemon.wsgi index 93e1b40..43a2ec1 100644 --- a/handyrep/hdaemon.wsgi +++ b/handyrep/hdaemon.wsgi @@ -1,2 +1,37 @@ -from hdaemon import app as application +from hdaemon import app + +class ReverseProxied(object): + '''Wrap the application in this middleware and configure the + front-end server to add these headers, to let you quietly bind + this to a URL other than / and to an HTTP scheme that is + different than what is used locally. + + In nginx: + location /myprefix { + proxy_pass http://192.168.0.1:5001; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Script-Name /myprefix; + } + + :param app: the WSGI application + ''' + def __init__(self, app): + self.app = app + + def __call__(self, environ, start_response): + script_name = environ.get('HTTP_X_SCRIPT_NAME', '') + if script_name: + environ['SCRIPT_NAME'] = script_name + path_info = environ['PATH_INFO'] + if path_info.startswith(script_name): + environ['PATH_INFO'] = path_info[len(script_name):] + + scheme = environ.get('HTTP_X_SCHEME', '') + if scheme: + environ['wsgi.url_scheme'] = scheme + return self.app(environ, start_response) + +application = ReverseProxied(app) diff --git a/handyrepGUI/handyrepGUI.wsgi b/handyrepGUI/handyrepGUI.wsgi index d3a1b07..88ae79d 100644 --- a/handyrepGUI/handyrepGUI.wsgi +++ b/handyrepGUI/handyrepGUI.wsgi @@ -1,2 +1,37 @@ -from GUI_app import app as application +from GUI_app import app +class ReverseProxied(object): + '''Wrap the application in this middleware and configure the + front-end server to add these headers, to let you quietly bind + this to a URL other than / and to an HTTP scheme that is + different than what is used locally. + + In nginx: + location /myprefix { + proxy_pass http://192.168.0.1:5001; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Script-Name /myprefix; + } + + :param app: the WSGI application + ''' + def __init__(self, app): + self.app = app + + def __call__(self, environ, start_response): + script_name = environ.get('HTTP_X_SCRIPT_NAME', '') + if script_name: + self.app.static_url_path = script_name + '/static' + environ['SCRIPT_NAME'] = script_name + path_info = environ['PATH_INFO'] + if path_info.startswith(script_name): + environ['PATH_INFO'] = path_info[len(script_name):] + + scheme = environ.get('HTTP_X_SCHEME', '') + if scheme: + environ['wsgi.url_scheme'] = scheme + return self.app(environ, start_response) + +application = ReverseProxied(app) From c44905bade2b19d60fc53aa692e55c489ca29e6b Mon Sep 17 00:00:00 2001 From: "B. Heath Robinson" Date: Mon, 11 Aug 2014 14:05:43 -0500 Subject: [PATCH 02/13] User url_for instead of hard-coding path for redirects --- handyrepGUI/GUI_app/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/handyrepGUI/GUI_app/views.py b/handyrepGUI/GUI_app/views.py index 8afe062..f8495ed 100755 --- a/handyrepGUI/GUI_app/views.py +++ b/handyrepGUI/GUI_app/views.py @@ -36,7 +36,7 @@ def logout(): username = None global password password = None - return redirect('/index') + return redirect('index') @app.route('/login/', methods=['GET', 'POST']) @@ -65,7 +65,7 @@ def login(): message = "Please check username and password" return render_template('login.html', form=form, message=message) - return redirect(request.args.get('next') or '/index') + return redirect(request.args.get('next') or url_for('index')) return render_template('login.html', form=form) From 3126d6bf0d04db6cb8f98d99b6616bd698dd797c Mon Sep 17 00:00:00 2001 From: "B. Heath Robinson" Date: Mon, 11 Aug 2014 14:08:13 -0500 Subject: [PATCH 03/13] Use url_for for static files and logout and index links on base template --- handyrepGUI/GUI_app/templates/base.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/handyrepGUI/GUI_app/templates/base.html b/handyrepGUI/GUI_app/templates/base.html index 01c9f99..33bd894 100755 --- a/handyrepGUI/GUI_app/templates/base.html +++ b/handyrepGUI/GUI_app/templates/base.html @@ -2,19 +2,19 @@ handyrepGUI<!--{% block title %}{% endblock %}--> - + -
logout
+
logout
- \ No newline at end of file + From 2f3c6fefeee35851a377bb77ec78cc194fd59592 Mon Sep 17 00:00:00 2001 From: "B. Heath Robinson" Date: Mon, 11 Aug 2014 14:08:40 -0500 Subject: [PATCH 04/13] Use url_for to generate links --- handyrepGUI/GUI_app/templates/base2.html | 6 +++--- handyrepGUI/GUI_app/templates/index.html | 6 +++--- handyrepGUI/GUI_app/templates/server_base_page.html | 4 ++-- handyrepGUI/GUI_app/templates/server_page.html | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/handyrepGUI/GUI_app/templates/base2.html b/handyrepGUI/GUI_app/templates/base2.html index cdd8ad9..0882691 100644 --- a/handyrepGUI/GUI_app/templates/base2.html +++ b/handyrepGUI/GUI_app/templates/base2.html @@ -11,7 +11,7 @@ Enabled -

cluster

+

cluster

{{ status.cluster.get("status") }}

{{ status.cluster.get("status_message") }}

{{ status.cluster.get("status_ts") }}

@@ -20,7 +20,7 @@ {% for key, value in status.get("servers")|dictsort %} -

{{key}}

+

{{key}}

{{value.get("status")}}

{{value.get("status_message")}}

{{value.get("status_ts")}}

@@ -31,4 +31,4 @@ {% block eachcontent %}{% endblock %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/handyrepGUI/GUI_app/templates/index.html b/handyrepGUI/GUI_app/templates/index.html index 926631e..70e323f 100644 --- a/handyrepGUI/GUI_app/templates/index.html +++ b/handyrepGUI/GUI_app/templates/index.html @@ -9,7 +9,7 @@

-

Cluster status is {{ status.get(category).get("status") }} because {{ status.get(category).get("status_message") }}. +

Cluster status is {{ status.get(category).get("status") }} because {{ status.get(category).get("status_message") }}. This was reported at {{ status.get(category).get("status_ts") }}

@@ -23,7 +23,7 @@

{% endif %} {% endfor %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/handyrepGUI/GUI_app/templates/server_base_page.html b/handyrepGUI/GUI_app/templates/server_base_page.html index 7d50b45..519f590 100644 --- a/handyrepGUI/GUI_app/templates/server_base_page.html +++ b/handyrepGUI/GUI_app/templates/server_base_page.html @@ -5,7 +5,7 @@
{% if info %} {% for key in info %} -

{{key|capitalize}}'s server information:

+

{{key|capitalize}}'s server information:

@@ -31,4 +31,4 @@

{{key|capitalize}}'s server information: -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/handyrepGUI/GUI_app/templates/server_page.html b/handyrepGUI/GUI_app/templates/server_page.html index 8ee8efe..dc33e9b 100644 --- a/handyrepGUI/GUI_app/templates/server_page.html +++ b/handyrepGUI/GUI_app/templates/server_page.html @@ -4,7 +4,7 @@ {% if info %} {% set server=[] %} {% for key in info %} -

Functions callable on {{ key |capitalize}}:

+

Functions callable on {{ key |capitalize}}:

{% set _ = server.append(key) %} {% endfor %} @@ -13,7 +13,7 @@

Functions callable on {{ key |capitalize}}:

{% for function in functions %} - + {% if loop.index is divisibleby 5 %}

{{ function.short_description }} {{ function }}

{{ function.short_description }} {{ function }}

@@ -28,7 +28,7 @@

Functions callable on the Cluster:

{% for function in functions %} - + {% if loop.index is divisibleby 5 %} @@ -40,4 +40,4 @@

Functions callable on the Cluster:

{% endif %} -{% endblock %} \ No newline at end of file +{% endblock %} From e70018714d4a6bfad0d4a3142bfdff9056335f9e Mon Sep 17 00:00:00 2001 From: "B. Heath Robinson" Date: Mon, 11 Aug 2014 14:28:38 -0500 Subject: [PATCH 05/13] Add default handy rep so most don't have to type the same thing every time --- handyrepGUI/GUI_app/templates/login.html | 2 +- handyrepGUI/config.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/handyrepGUI/GUI_app/templates/login.html b/handyrepGUI/GUI_app/templates/login.html index 37349f2..0dd08bd 100755 --- a/handyrepGUI/GUI_app/templates/login.html +++ b/handyrepGUI/GUI_app/templates/login.html @@ -14,7 +14,7 @@

{{ message }}

Please enter the address where HandyRep is running.
Please remember to include http://

{{form.hidden_tag()}} -

{{form.address(size=80)}}

+

{{form.address(size=80,value=config.DEFAULT_HANDYREP)}}

Please enter your HandyRep user name.

{{form.username(size=80)}}

Please enter your HandyRep password.

diff --git a/handyrepGUI/config.py b/handyrepGUI/config.py index a94dd93..e6f19e7 100755 --- a/handyrepGUI/config.py +++ b/handyrepGUI/config.py @@ -5,4 +5,5 @@ basedir = os.path.abspath(os.path.dirname(__file__)) CSRF_ENABLED = True -SECRET_KEY = 'GUI-secret-key-597621139' \ No newline at end of file +SECRET_KEY = 'GUI-secret-key-597621139' +DEFAULT_HANDYREP = 'http://localhost:8080' From 56c5044f32f37ecd12c8edde566fc1a752ddae5e Mon Sep 17 00:00:00 2001 From: "B. Heath Robinson" Date: Mon, 11 Aug 2014 14:28:53 -0500 Subject: [PATCH 06/13] Use a password field of the password --- handyrepGUI/GUI_app/templates/login.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/handyrepGUI/GUI_app/templates/login.html b/handyrepGUI/GUI_app/templates/login.html index 0dd08bd..97b28c9 100755 --- a/handyrepGUI/GUI_app/templates/login.html +++ b/handyrepGUI/GUI_app/templates/login.html @@ -18,9 +18,9 @@

Please enter the address where HandyRep is running.

Please enter your HandyRep user name.

{{form.username(size=80)}}

Please enter your HandyRep password.

-

{{form.password(size=80)}}

+

{{form.password(type='password',size=80)}}

- {% endblock %} \ No newline at end of file + {% endblock %} From d30559dea6558bd22ef1e58fe0a1a2f33bcdf347 Mon Sep 17 00:00:00 2001 From: "B. Heath Robinson" Date: Wed, 19 Nov 2014 17:46:17 +0000 Subject: [PATCH 07/13] Add ability to specify connection params per database --- handyrep/plugins/multi_pgbouncer.py | 40 +++++++++++++++++------------ 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/handyrep/plugins/multi_pgbouncer.py b/handyrep/plugins/multi_pgbouncer.py index b9ca456..6218d78 100644 --- a/handyrep/plugins/multi_pgbouncer.py +++ b/handyrep/plugins/multi_pgbouncer.py @@ -108,8 +108,12 @@ def bouncer_list(self): def test(self): #check that we have all config variables required - if self.failed( self.test_plugin_conf("multi_pgbouncer","pgbouncerbin","template","owner","config_location","database_list","readonly_suffix","all_replicas")): + if self.failed( self.test_plugin_conf("multi_pgbouncer","pgbouncerbin","template","owner","config_location","readonly_suffix","all_replicas")): return self.rd(False, "multi-pgbouncer failover is not configured" ) + + if self.failed( self.test_plugin_conf("multi_pgbouncer","database_list") or self.test_plugin_conf("multi_pgbouncer","databases")): + return self.rd(False, "multi-pgbouncer failover has no configured databases" ) + #check that we can connect to the pgbouncer servers blist = self.bouncer_list() if len(blist) == 0: @@ -157,23 +161,31 @@ def dbconnect_list(self, master): # servers for pgbouncer # build master string first myconf = self.conf["plugins"]["multi_pgbouncer"] - dblist = myconf["database_list"] + if myconf["databases"]: + dbconfig = myconf["databases"] + + if myconf["database_list"]: + dbconfig = {} + for dbname in myconf["database_list"]: + dbconfig[dbname] = myconf["extra_connect_param"] + # add in the handyrep db if the user has forgotten it - if self.conf["handyrep"]["handyrep_db"] not in dblist: - dblist.append(self.conf["handyrep"]["handyrep_db"]) - constr = self.dbconnect_line(dblist, self.servers[master]["hostname"], self.servers[master]["port"], "", myconf["extra_connect_param"]) + if not dbconf.has_key(self.conf["handyrep"]["handyrep_db"]): + dbconf[self.conf["handyrep"]["handyrep_db"]] = myconf["extra_connect_param"] + + constr = self.dbconnect_line(dbconfig, self.servers[master]["hostname"], self.servers[master]["port"], "") replicas = self.sorted_replicas() if self.is_true(myconf["all_replicas"]): #if we're doing all replicas, we need to put them in as _ro0, _ro1, etc. # if there's no replicas, set ro1 to go to the master: if len(replicas) == 0 or (len(replicas) == 1 and master in replicas): rsuff = "%s%d" % (myconf["readonly_suffix"],1,) - constr += self.dbconnect_line(myconf["database_list"], self.servers[master]["hostname"], self.servers[master]["port"], rsuff, myconf["extra_connect_param"]) + constr += self.dbconnect_line(dbconfig, self.servers[master]["hostname"], self.servers[master]["port"], rsuff) else: for rep in replicas: if not rep == master: rsuff = "%s%d" % (myconf["readonly_suffix"],repno,) - constr += self.dbconnect_line(myconf["database_list"], self.servers[rep]["hostname"], self.servers[rep]["port"], rsuff, myconf["extra_connect_param"]) + constr += self.dbconnect_line(dbconfig, self.servers[rep]["hostname"], self.servers[rep]["port"], rsuff) repno += 1 else: # only one readonly replica, setting it up with _ro @@ -183,23 +195,17 @@ def dbconnect_list(self, master): replicas.pop(0) if len(replicas) > 0: - constr += self.dbconnect_line(myconf["database_list"], self.servers[replicas[0]]["hostname"], self.servers[replicas[0]]["port"], myconf["readonly_suffix"], myconf["extra_connect_param"]) + constr += self.dbconnect_line(dbconfig, self.servers[replicas[0]]["hostname"], self.servers[replicas[0]]["port"], myconf["readonly_suffix"]) else: # if no replicas, read-only connections should go to the master - constr += self.dbconnect_line(myconf["database_list"], self.servers[master]["hostname"], self.servers[master]["port"], myconf["readonly_suffix"], myconf["extra_connect_param"]) + constr += self.dbconnect_line(dbconfig, self.servers[master]["hostname"], self.servers[master]["port"], myconf["readonly_suffix"]) return constr - def dbconnect_line(self, database_list, hostname, portno, suffix, extra): + def dbconnect_line(self, database_list, hostname, portno, suffix): confout = "" - if extra: - nex = extra - else: - nex = "" - for dbname in database_list: + for dbname,nex in database_list.items(): confout += "%s%s = dbname=%s host=%s port=%s %s \n" % (dbname, suffix, dbname, hostname, portno, nex,) return confout - - \ No newline at end of file From b8c16f7d574f19e5fd91a6e0c10c4260d7a5c48d Mon Sep 17 00:00:00 2001 From: "B. Heath Robinson" Date: Wed, 19 Nov 2014 17:47:09 +0000 Subject: [PATCH 08/13] Add ability to specifiy config in apache env var HANDYREP_CONFIG --- handyrep/daemon/config.py | 3 ++- handyrep/hdaemon.py | 12 ++++++------ handyrep/hdaemon.wsgi | 16 ++++++++++------ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/handyrep/daemon/config.py b/handyrep/daemon/config.py index 1ac0afa..303a4f1 100644 --- a/handyrep/daemon/config.py +++ b/handyrep/daemon/config.py @@ -1,3 +1,4 @@ import os -os.environ['HANDYREP_CONFIG'] = '/srv/handyrep//handyrep/handyrep.conf' \ No newline at end of file +if not os.environ.has_key('HANDYREP_CONFIG'): + os.environ['HANDYREP_CONFIG'] = '/srv/handyrep//handyrep/handyrep.conf' diff --git a/handyrep/hdaemon.py b/handyrep/hdaemon.py index 98b7b4a..8f7f851 100644 --- a/handyrep/hdaemon.py +++ b/handyrep/hdaemon.py @@ -85,13 +85,13 @@ def run_periodic(func): print func, "exiting with return", result +def start(): + startup() -startup() - -for func_name in PERIODIC.keys(): - t = Thread(target=run_periodic, args=(func_name,) ) - t.daemon = True - t.start() + for func_name in PERIODIC.keys(): + t = Thread(target=run_periodic, args=(func_name,) ) + t.daemon = True + t.start() if __name__ == "__main__": app.run(host="0.0.0.0") diff --git a/handyrep/hdaemon.wsgi b/handyrep/hdaemon.wsgi index 43a2ec1..c34ac66 100644 --- a/handyrep/hdaemon.wsgi +++ b/handyrep/hdaemon.wsgi @@ -1,4 +1,5 @@ -from hdaemon import app +import hdaemon +import os class ReverseProxied(object): '''Wrap the application in this middleware and configure the @@ -15,10 +16,10 @@ class ReverseProxied(object): proxy_set_header X-Script-Name /myprefix; } - :param app: the WSGI application + :param app: the hdaemon module so we can get the app and start the daemon ''' - def __init__(self, app): - self.app = app + def __init__(self, hd): + self.hdaemon = hdaemon def __call__(self, environ, start_response): script_name = environ.get('HTTP_X_SCRIPT_NAME', '') @@ -31,7 +32,10 @@ class ReverseProxied(object): scheme = environ.get('HTTP_X_SCHEME', '') if scheme: environ['wsgi.url_scheme'] = scheme - return self.app(environ, start_response) -application = ReverseProxied(app) + os.environ['HANDYREP_CONFIG'] = environ['HANDYREP_CONFIG'] + self.hdaemon.start() + return self.hdaemon.app(environ, start_response) + +application = ReverseProxied(hdaemon) From 6a25e07522545c522e89f685c89002b6189a409b Mon Sep 17 00:00:00 2001 From: Heath Robinson Date: Tue, 3 Feb 2015 12:29:34 -0600 Subject: [PATCH 09/13] Lower version req for ubuntu package --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a31e997..3bb02a3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -psycopg2>=2.5 +psycopg2>=2.4 fabric>=1.7 ConfigObj>=4.6 jinja2>=2.0 From a97ef396ee49fd7dac8280dc80f22ae0b03fac33 Mon Sep 17 00:00:00 2001 From: "B. Heath Robinson" Date: Wed, 4 Feb 2015 16:14:02 -0600 Subject: [PATCH 10/13] Add Flash-WTF --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3bb02a3..2c6a94b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ fabric>=1.7 ConfigObj>=4.6 jinja2>=2.0 flask>=0.8 - +Flask-WTF>=0.9.5 From 66206464fe2382d82df3553e8dad1fc022c543d6 Mon Sep 17 00:00:00 2001 From: "B. Heath Robinson" Date: Thu, 5 Feb 2015 16:20:50 -0600 Subject: [PATCH 11/13] Rename variable --- handyrep/plugins/multi_pgbouncer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/handyrep/plugins/multi_pgbouncer.py b/handyrep/plugins/multi_pgbouncer.py index 6218d78..cff8be7 100644 --- a/handyrep/plugins/multi_pgbouncer.py +++ b/handyrep/plugins/multi_pgbouncer.py @@ -170,8 +170,8 @@ def dbconnect_list(self, master): dbconfig[dbname] = myconf["extra_connect_param"] # add in the handyrep db if the user has forgotten it - if not dbconf.has_key(self.conf["handyrep"]["handyrep_db"]): - dbconf[self.conf["handyrep"]["handyrep_db"]] = myconf["extra_connect_param"] + if not dbconfig.has_key(self.conf["handyrep"]["handyrep_db"]): + dbconfig[self.conf["handyrep"]["handyrep_db"]] = myconf["extra_connect_param"] constr = self.dbconnect_line(dbconfig, self.servers[master]["hostname"], self.servers[master]["port"], "") replicas = self.sorted_replicas() From 0f61a6d7f909eef15bb3b8575b6ba44cf9aaaaea Mon Sep 17 00:00:00 2001 From: "B. Heath Robinson" Date: Wed, 17 Jun 2015 14:45:04 -0500 Subject: [PATCH 12/13] Add some logging --- handyrep/handyrep.py | 3 ++- handyrep/plugins/handyrepplugin.py | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/handyrep/handyrep.py b/handyrep/handyrep.py index 0beb287..ff764db 100644 --- a/handyrep/handyrep.py +++ b/handyrep/handyrep.py @@ -1929,7 +1929,8 @@ def test_ssh_newhost(self, hostname, ssh_key, ssh_user ): command = self.conf["handyrep"]["test_ssh_command"] testit = run(command, warn_only=True, quiet=True) except Exception as ex: - print exstr(ex) + self.log("SSH","Unable to ssh to host %s" % hostname,True) + #print exstr(ex) return False result = testit.succeeded diff --git a/handyrep/plugins/handyrepplugin.py b/handyrep/plugins/handyrepplugin.py index 5389506..4e12e88 100644 --- a/handyrep/plugins/handyrepplugin.py +++ b/handyrep/plugins/handyrepplugin.py @@ -15,6 +15,7 @@ from subprocess import call import re import threading +import traceback class HandyRepPlugin(object): @@ -160,6 +161,7 @@ def push_template(self, servername, templatename, destination, template_params, if new_owner: sudo("chown %s %s" % (new_owner, destination,), quiet=True) except: + self.log('PLUGIN','could not push template %s to server %s - %s' % (templatename,servername, traceback.format_exc()),True) retdict = return_dict(False, "could not push template %s to server %s" % (templatename, servername,)) else: retdict = return_dict(True, "pushed template") @@ -371,4 +373,4 @@ def execute_it(self, cur, statement, params=[]): def exstr(self, errorobj): return exstr(errorobj) - \ No newline at end of file + From 1a6cbc15f79119829e374d8146b50690e00c5266 Mon Sep 17 00:00:00 2001 From: "B. Heath Robinson" Date: Wed, 17 Jun 2015 14:45:31 -0500 Subject: [PATCH 13/13] Allow per database options --- handyrep/plugins/multi_pgbouncer.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/handyrep/plugins/multi_pgbouncer.py b/handyrep/plugins/multi_pgbouncer.py index cff8be7..26e51df 100644 --- a/handyrep/plugins/multi_pgbouncer.py +++ b/handyrep/plugins/multi_pgbouncer.py @@ -161,11 +161,12 @@ def dbconnect_list(self, master): # servers for pgbouncer # build master string first myconf = self.conf["plugins"]["multi_pgbouncer"] + + dbconfig = {} if myconf["databases"]: - dbconfig = myconf["databases"] + dbconfig.update(myconf["databases"]) if myconf["database_list"]: - dbconfig = {} for dbname in myconf["database_list"]: dbconfig[dbname] = myconf["extra_connect_param"]

{{ function.short_description }} {{ function }}

{{ function.short_description }} {{ function }}