Skip to content

Commit 6077df7

Browse files
authored
Merge pull request #97 from UnderGreen/mongodb_3_6
MongoDB 3.6 full support
2 parents b5257ff + 67082cc commit 6077df7

18 files changed

Lines changed: 682 additions & 85 deletions

.travis.yml

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,23 @@ sudo: required
66
language: python
77
python:
88
- "2.7"
9-
- "3.6"
109
env:
10+
- >
11+
DISTRIBUTION=ubuntu
12+
DIST_VERSION=16_04-builded
13+
MONGODB_VERSION=3.6
14+
- >
15+
DISTRIBUTION=ubuntu
16+
DIST_VERSION=16_04-builded
17+
MONGODB_VERSION=3.4
18+
- >
19+
DISTRIBUTION=ubuntu
20+
DIST_VERSION=16_04-builded
21+
MONGODB_VERSION=3.2
22+
- >
23+
DISTRIBUTION=ubuntu-upstart
24+
DIST_VERSION=14.04
25+
MONGODB_VERSION=3.6
1126
- >
1227
DISTRIBUTION=ubuntu-upstart
1328
DIST_VERSION=14.04
@@ -16,22 +31,46 @@ env:
1631
DISTRIBUTION=ubuntu-upstart
1732
DIST_VERSION=14.04
1833
MONGODB_VERSION=3.2
34+
- >
35+
DISTRIBUTION=debian
36+
DIST_VERSION=9-builded
37+
MONGODB_VERSION=3.2
38+
- >
39+
DISTRIBUTION=debian
40+
DIST_VERSION=8-builded
41+
MONGODB_VERSION=3.6
42+
- >
43+
DISTRIBUTION=debian
44+
DIST_VERSION=8-builded
45+
MONGODB_VERSION=3.4
46+
- >
47+
DISTRIBUTION=debian
48+
DIST_VERSION=8-builded
49+
MONGODB_VERSION=3.2
1950
- >
2051
DISTRIBUTION=centos
2152
DIST_VERSION=6-builded
22-
MONGODB_VERSION=3.2
53+
MONGODB_VERSION=3.6
2354
- >
2455
DISTRIBUTION=centos
2556
DIST_VERSION=6-builded
2657
MONGODB_VERSION=3.4
2758
- >
2859
DISTRIBUTION=centos
29-
DIST_VERSION=7-builded
60+
DIST_VERSION=6-builded
3061
MONGODB_VERSION=3.2
62+
- >
63+
DISTRIBUTION=centos
64+
DIST_VERSION=7-builded
65+
MONGODB_VERSION=3.6
3166
- >
3267
DISTRIBUTION=centos
3368
DIST_VERSION=7-builded
3469
MONGODB_VERSION=3.4
70+
- >
71+
DISTRIBUTION=centos
72+
DIST_VERSION=7-builded
73+
MONGODB_VERSION=3.2
3574
# - >
3675
# distribution=debian
3776
# version=7

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ Ansible role which manages [MongoDB](http://www.mongodb.org/).
1010

1111
MongoDB support matrix:
1212

13-
| Distribution | MongoDB 2.4 | MongoDB 2.6 | MongoDB 3.0 | MongoDB 3.2 | MongoDB 3.4 |
14-
| ------------ |:-----------:|:-----------:|:-----------:|:-----------:|:-----------:|
15-
| Ubuntu 14.04 | :no_entry: | :white_check_mark: | :white_check_mark: | :white_check_mark:| :x:|
16-
| Ubuntu 16.04 | :no_entry: | :x: | :x: | :x:| :x:|
17-
| Debian 8.x | :no_entry: | :x: | :x: | :x:| :x:|
18-
| Debian 9.x | :no_entry: | :x: | :x: | :x:| :x:|
19-
| RHEL 6.x | :no_entry: | :interrobang: | :interrobang: | :interrobang: | :interrobang: |
20-
| RHEL 7.x | :no_entry: | :interrobang: | :interrobang: | :interrobang: | :interrobang: |
21-
22-
:white_check_mark: - fully tested, should work fine
23-
:interrobang: - will be added testing suite soon
24-
:x: - don't have official support
25-
:no_entry: - does't have support, because used old format of configuration files
13+
| Distribution | MongoDB 2.4 | MongoDB 2.6 | MongoDB 3.0 | MongoDB 3.2 | MongoDB 3.4 | MongoDB 3.6 |
14+
| ------------ |:-----------:|:-----------:|:-----------:|:-----------:|:-----------:|:-----------:|
15+
| Ubuntu 14.04 | :no_entry: | :no_entry: | :no_entry: | :white_check_mark:| :white_check_mark:| :white_check_mark:|
16+
| Ubuntu 16.04 | :no_entry: | :no_entry: | :no_entry: | :white_check_mark:| :white_check_mark:| :white_check_mark:|
17+
| Debian 8.x | :no_entry: | :no_entry: | :no_entry: | :white_check_mark:| :white_check_mark:| :white_check_mark:|
18+
| Debian 9.x | :no_entry: | :no_entry: | :no_entry: | :white_check_mark:| :x:| :x:|
19+
| RHEL 6.x | :no_entry: | :no_entry: | :no_entry: | :white_check_mark: | :white_check_mark: | :white_check_mark:|
20+
| RHEL 7.x | :no_entry: | :no_entry: | :no_entry: | :white_check_mark: | :white_check_mark: | :white_check_mark:|
21+
22+
- :white_check_mark: - fully tested, should works fine
23+
- :interrobang: - maybe works, not tested
24+
- :x: - don't have official support
25+
- :no_entry: - MongoDB has reached EOL
2626

2727
#### Variables
2828

@@ -33,9 +33,9 @@ MongoDB support matrix:
3333
mongodb_package: mongodb-org
3434

3535
# You can control installed version via this param.
36-
# Should be '2.6', '3.0', '3.2' or '3.4'. This role does't support MongoDB < 2.4.
36+
# Should be '3.2', '3.4', '3.6'. This role doesn't support MongoDB < 3.2.
3737
# I will recommend you to use latest version of MongoDB.
38-
mongodb_version: "3.4"
38+
mongodb_version: "3.6"
3939

4040
mongodb_force_wait_for_port: false # When not forced, the role will wait for mongod port to become available only with systemd
4141
mongodb_pymongo_from_pip: true # Install latest PyMongo via PIP or package manager

library/mongodb_replication.py

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@
4545
- The port to connect to
4646
required: false
4747
default: 27017
48+
login_database:
49+
description:
50+
- The database where login credentials are stored
51+
required: false
52+
default: admin
4853
replica_set:
4954
description:
5055
- Replica set to connect to (automatically connects to primary for writes)
@@ -69,6 +74,12 @@
6974
description:
7075
- Whether to use an SSL connection when connecting to the database
7176
default: False
77+
ssl_cert_reqs:
78+
description:
79+
- Specifies whether a certificate is required from the other side of the connection, and whether it will be validated if provided.
80+
required: false
81+
default: "CERT_REQUIRED"
82+
choices: ["CERT_REQUIRED", "CERT_OPTIONAL", "CERT_NONE"]
7283
build_indexes:
7384
description:
7485
- Determines whether the mongod builds indexes on this member.
@@ -146,7 +157,9 @@
146157
sample: "replica"
147158
'''
148159
import ConfigParser
160+
import ssl as ssl_lib
149161
import time
162+
from datetime import datetime as dtdatetime
150163
from distutils.version import LooseVersion
151164
try:
152165
from pymongo.errors import ConnectionFailure
@@ -156,7 +169,6 @@
156169
from pymongo.errors import ServerSelectionTimeoutError
157170
from pymongo import version as PyMongoVersion
158171
from pymongo import MongoClient
159-
from pymongo import MongoReplicaSetClient
160172
except ImportError:
161173
pymongo_found = False
162174
else:
@@ -203,6 +215,7 @@ def check_members(state, module, client, host_name, host_port, host_type):
203215
module.exit_json(changed=False, host_name=host_name, host_port=host_port, host_type=host_type)
204216

205217
def add_host(module, client, host_name, host_port, host_type, timeout=180, **kwargs):
218+
start_time = dtdatetime.now()
206219
while True:
207220
try:
208221
admin_db = client['admin']
@@ -240,12 +253,12 @@ def add_host(module, client, host_name, host_port, host_type, timeout=180, **kwa
240253
admin_db.command('replSetReconfig', cfg)
241254
return
242255
except (OperationFailure, AutoReconnect) as e:
243-
timeout = timeout - 5
244-
if timeout <= 0:
256+
if (dtdatetime.now() - start_time).seconds > timeout:
245257
module.fail_json(msg='reached timeout while waiting for rs.reconfig(): %s' % str(e))
246258
time.sleep(5)
247259

248260
def remove_host(module, client, host_name, timeout=180):
261+
start_time = dtdatetime.now()
249262
while True:
250263
try:
251264
admin_db = client['admin']
@@ -269,8 +282,7 @@ def remove_host(module, client, host_name, timeout=180):
269282
fail_msg = "couldn't find member with hostname: {0} in replica set members list".format(host_name)
270283
module.fail_json(msg=fail_msg)
271284
except (OperationFailure, AutoReconnect) as e:
272-
timeout = timeout - 5
273-
if timeout <= 0:
285+
if (dtdatetime.now() - start_time).seconds > timeout:
274286
module.fail_json(msg='reached timeout while waiting for rs.reconfig(): %s' % str(e))
275287
time.sleep(5)
276288

@@ -289,14 +301,23 @@ def load_mongocnf():
289301

290302
return creds
291303

292-
def wait_for_ok_and_master(module, client, timeout = 60):
304+
def wait_for_ok_and_master(module, connection_params, timeout = 180):
305+
start_time = dtdatetime.now()
293306
while True:
294-
status = client.admin.command('replSetGetStatus', check=False)
295-
if status['ok'] == 1 and status['myState'] == 1:
296-
return
307+
try:
308+
client = MongoClient(**connection_params)
309+
authenticate(client, connection_params["username"], connection_params["password"])
310+
311+
status = client.admin.command('replSetGetStatus', check=False)
312+
if status['ok'] == 1 and status['myState'] == 1:
313+
return
314+
315+
except ServerSelectionTimeoutError:
316+
pass
297317

298-
timeout = timeout - 1
299-
if timeout == 0:
318+
client.close()
319+
320+
if (dtdatetime.now() - start_time).seconds > timeout:
300321
module.fail_json(msg='reached timeout while waiting for rs.status() to become ok=1')
301322

302323
time.sleep(1)
@@ -324,11 +345,13 @@ def main():
324345
login_password=dict(default=None, no_log=True),
325346
login_host=dict(default='localhost'),
326347
login_port=dict(default='27017'),
348+
login_database=dict(default="admin"),
327349
replica_set=dict(default=None),
328350
host_name=dict(default='localhost'),
329351
host_port=dict(default='27017'),
330352
host_type=dict(default='replica', choices=['replica','arbiter']),
331-
ssl=dict(default='false'),
353+
ssl=dict(default=False, type='bool'),
354+
ssl_cert_reqs=dict(default='CERT_REQUIRED', choices=['CERT_NONE', 'CERT_OPTIONAL', 'CERT_REQUIRED']),
332355
build_indexes = dict(type='bool', default='yes'),
333356
hidden = dict(type='bool', default='no'),
334357
priority = dict(default='1.0'),
@@ -339,12 +362,13 @@ def main():
339362
)
340363

341364
if not pymongo_found:
342-
module.fail_json(msg='the python pymongo (>= 2.4) module is required')
365+
module.fail_json(msg='the python pymongo (>= 3.2) module is required')
343366

344367
login_user = module.params['login_user']
345368
login_password = module.params['login_password']
346369
login_host = module.params['login_host']
347370
login_port = module.params['login_port']
371+
login_database = module.params['login_database']
348372
replica_set = module.params['replica_set']
349373
host_name = module.params['host_name']
350374
host_port = module.params['host_port']
@@ -359,29 +383,58 @@ def main():
359383
if replica_set is None:
360384
module.fail_json(msg='replica_set parameter is required')
361385
else:
362-
client = MongoClient(login_host, int(login_port), replicaSet=replica_set,
363-
ssl=ssl, serverSelectionTimeoutMS=5000)
364-
386+
connection_params = {
387+
"host": login_host,
388+
"port": int(login_port),
389+
"username": login_user,
390+
"password": login_password,
391+
"authsource": login_database,
392+
"serverselectiontimeoutms": 5000,
393+
"replicaset": replica_set,
394+
}
395+
396+
if ssl:
397+
connection_params["ssl"] = ssl
398+
connection_params["ssl_cert_reqs"] = getattr(ssl_lib, module.params['ssl_cert_reqs'])
399+
400+
client = MongoClient(**connection_params)
365401
authenticate(client, login_user, login_password)
366402
client['admin'].command('replSetGetStatus')
367403

368404
except ServerSelectionTimeoutError:
369405
try:
370-
client = MongoClient(login_host, int(login_port), ssl=ssl)
406+
connection_params = {
407+
"host": login_host,
408+
"port": int(login_port),
409+
"username": login_user,
410+
"password": login_password,
411+
"authsource": login_database,
412+
"serverselectiontimeoutms": 10000,
413+
}
414+
415+
if ssl:
416+
connection_params["ssl"] = ssl
417+
connection_params["ssl_cert_reqs"] = getattr(ssl_lib, module.params['ssl_cert_reqs'])
418+
419+
client = MongoClient(**connection_params)
371420
authenticate(client, login_user, login_password)
372421
if state == 'present':
373422
new_host = { '_id': 0, 'host': "{0}:{1}".format(host_name, host_port) }
374423
if priority != 1.0: new_host['priority'] = priority
375424
config = { '_id': "{0}".format(replica_set), 'members': [new_host] }
376425
client['admin'].command('replSetInitiate', config)
377-
wait_for_ok_and_master(module, client)
426+
client.close()
427+
wait_for_ok_and_master(module, connection_params)
378428
replica_set_created = True
379429
module.exit_json(changed=True, host_name=host_name, host_port=host_port, host_type=host_type)
380430
except OperationFailure as e:
381431
module.fail_json(msg='Unable to initiate replica set: %s' % str(e))
382432
except ConnectionFailure as e:
383433
module.fail_json(msg='unable to connect to database: %s' % str(e))
384434

435+
# reconnect again
436+
client = MongoClient(**connection_params)
437+
authenticate(client, login_user, login_password)
385438
check_compatibility(module, client)
386439
check_members(state, module, client, host_name, host_port, host_type)
387440

0 commit comments

Comments
 (0)