Fix replication module

This commit is contained in:
Sergei Antipov 2018-02-26 15:35:36 +07:00
parent 0e7c080a30
commit b03ff7bf65
2 changed files with 28 additions and 19 deletions

View File

@ -159,6 +159,7 @@ host_type:
import ConfigParser import ConfigParser
import ssl as ssl_lib import ssl as ssl_lib
import time import time
from datetime import datetime as dtdatetime
from distutils.version import LooseVersion from distutils.version import LooseVersion
try: try:
from pymongo.errors import ConnectionFailure from pymongo.errors import ConnectionFailure
@ -168,7 +169,6 @@ try:
from pymongo.errors import ServerSelectionTimeoutError from pymongo.errors import ServerSelectionTimeoutError
from pymongo import version as PyMongoVersion from pymongo import version as PyMongoVersion
from pymongo import MongoClient from pymongo import MongoClient
from pymongo import MongoReplicaSetClient
except ImportError: except ImportError:
pymongo_found = False pymongo_found = False
else: else:
@ -215,6 +215,7 @@ def check_members(state, module, client, host_name, host_port, host_type):
module.exit_json(changed=False, host_name=host_name, host_port=host_port, host_type=host_type) module.exit_json(changed=False, host_name=host_name, host_port=host_port, host_type=host_type)
def add_host(module, client, host_name, host_port, host_type, timeout=180, **kwargs): def add_host(module, client, host_name, host_port, host_type, timeout=180, **kwargs):
start_time = dtdatetime.now()
while True: while True:
try: try:
admin_db = client['admin'] admin_db = client['admin']
@ -252,12 +253,12 @@ def add_host(module, client, host_name, host_port, host_type, timeout=180, **kwa
admin_db.command('replSetReconfig', cfg) admin_db.command('replSetReconfig', cfg)
return return
except (OperationFailure, AutoReconnect) as e: except (OperationFailure, AutoReconnect) as e:
timeout = timeout - 5 if (dtdatetime.now() - start_time).seconds > timeout:
if timeout <= 0:
module.fail_json(msg='reached timeout while waiting for rs.reconfig(): %s' % str(e)) module.fail_json(msg='reached timeout while waiting for rs.reconfig(): %s' % str(e))
time.sleep(5) time.sleep(5)
def remove_host(module, client, host_name, timeout=180): def remove_host(module, client, host_name, timeout=180):
start_time = dtdatetime.now()
while True: while True:
try: try:
admin_db = client['admin'] admin_db = client['admin']
@ -281,8 +282,7 @@ def remove_host(module, client, host_name, timeout=180):
fail_msg = "couldn't find member with hostname: {0} in replica set members list".format(host_name) fail_msg = "couldn't find member with hostname: {0} in replica set members list".format(host_name)
module.fail_json(msg=fail_msg) module.fail_json(msg=fail_msg)
except (OperationFailure, AutoReconnect) as e: except (OperationFailure, AutoReconnect) as e:
timeout = timeout - 5 if (dtdatetime.now() - start_time).seconds > timeout:
if timeout <= 0:
module.fail_json(msg='reached timeout while waiting for rs.reconfig(): %s' % str(e)) module.fail_json(msg='reached timeout while waiting for rs.reconfig(): %s' % str(e))
time.sleep(5) time.sleep(5)
@ -301,14 +301,23 @@ def load_mongocnf():
return creds return creds
def wait_for_ok_and_master(module, client, timeout = 60): def wait_for_ok_and_master(module, connection_params, timeout = 180):
start_time = dtdatetime.now()
while True: while True:
status = client.admin.command('replSetGetStatus', check=False) try:
if status['ok'] == 1 and status['myState'] == 1: client = MongoClient(**connection_params)
return authenticate(client, connection_params["username"], connection_params["password"])
timeout = timeout - 1 status = client.admin.command('replSetGetStatus', check=False)
if timeout == 0: if status['ok'] == 1 and status['myState'] == 1:
return
except ServerSelectionTimeoutError:
pass
client.close()
if (dtdatetime.now() - start_time).seconds > timeout:
module.fail_json(msg='reached timeout while waiting for rs.status() to become ok=1') module.fail_json(msg='reached timeout while waiting for rs.status() to become ok=1')
time.sleep(1) time.sleep(1)
@ -353,7 +362,7 @@ def main():
) )
if not pymongo_found: if not pymongo_found:
module.fail_json(msg='the python pymongo (>= 2.4) module is required') module.fail_json(msg='the python pymongo (>= 3.2) module is required')
login_user = module.params['login_user'] login_user = module.params['login_user']
login_password = module.params['login_password'] login_password = module.params['login_password']
@ -400,7 +409,7 @@ def main():
"username": login_user, "username": login_user,
"password": login_password, "password": login_password,
"authsource": login_database, "authsource": login_database,
"serverselectiontimeoutms": 30000, "serverselectiontimeoutms": 10000,
} }
if ssl: if ssl:
@ -414,7 +423,8 @@ def main():
if priority != 1.0: new_host['priority'] = priority if priority != 1.0: new_host['priority'] = priority
config = { '_id': "{0}".format(replica_set), 'members': [new_host] } config = { '_id': "{0}".format(replica_set), 'members': [new_host] }
client['admin'].command('replSetInitiate', config) client['admin'].command('replSetInitiate', config)
wait_for_ok_and_master(module, client) client.close()
wait_for_ok_and_master(module, connection_params)
replica_set_created = True replica_set_created = True
module.exit_json(changed=True, host_name=host_name, host_port=host_port, host_type=host_type) module.exit_json(changed=True, host_name=host_name, host_port=host_port, host_type=host_type)
except OperationFailure as e: except OperationFailure as e:
@ -422,6 +432,9 @@ def main():
except ConnectionFailure as e: except ConnectionFailure as e:
module.fail_json(msg='unable to connect to database: %s' % str(e)) module.fail_json(msg='unable to connect to database: %s' % str(e))
# reconnect again
client = MongoClient(**connection_params)
authenticate(client, login_user, login_password)
check_compatibility(module, client) check_compatibility(module, client)
check_members(state, module, client, host_name, host_port, host_type) check_members(state, module, client, host_name, host_port, host_type)

View File

@ -1,5 +1,5 @@
--- ---
- name: Move back mongod.conf - name: Use different mongod.conf for auth initialization
template: src=mongod_init.conf.j2 dest=/etc/mongod.conf owner=root group=root mode=0644 template: src=mongod_init.conf.j2 dest=/etc/mongod.conf owner=root group=root mode=0644
- name: Restart mongodb service - name: Restart mongodb service
@ -77,7 +77,3 @@
- name: Wait MongoDB port is listening - name: Wait MongoDB port is listening
wait_for: host="{{ item }}" port="{{ mongodb_net_port }}" delay=5 state=started wait_for: host="{{ item }}" port="{{ mongodb_net_port }}" delay=5 state=started
with_items: "{{ mongodb_net_bindip.split(',') | map('replace', '0.0.0.0', '127.0.0.1') | list }}" with_items: "{{ mongodb_net_bindip.split(',') | map('replace', '0.0.0.0', '127.0.0.1') | list }}"
- name: stop mongodb if was not started
shell: "kill {{ pidof_mongod.stdout }}"
when: mongodb_manage_service == false and pidof_mongod.rc == 0