forked from openedx-unsupported/configuration
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mongodb_rs_config
137 lines (115 loc) · 4.63 KB
/
mongodb_rs_config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env python
from __future__ import absolute_import
from six.moves import map
DOCUMENTATION = """
---
module: mongodb_rs_config
short_description: Get the configuration of a replica set of a mongo cluster.
description:
- Get the config of the replica set of a mongo cluster. Provides a filtered version of the info from rs.config().
returns primary, secondary, hidden. Each contains a list of the members in that state. Lists
may be empty. Additionally returns the full config document in the config key. Keep in mind that hosts may be
duplicated secondary and hidden since hidden hosts are secondaries.
version_added: "1.9"
author:
- Feanil Patel
- Kevin Falcone
options:
host:
description:
- The hostname or ip of a server in the mongo cluster.
required: false
default: 'localhost'
port:
description:
- The port to connect to mongo on.
required: false
default: 27017
username:
description:
- The username of the mongo user to connect as.
required: false
password:
description:
- The password to use when authenticating.
required: false
auth_database:
description:
- The database to authenticate against.
required: false
"""
EXAMPLES = '''
- name: Get status for the stage cluster
mongodb_rs_config:
host: localhost:27017
username: root
password: password
register: rs_config
'''
# Magic import
from ansible.module_utils.basic import *
try:
from pymongo import MongoClient
from pymongo.errors import OperationFailure
from bson import json_util
except ImportError:
pymongo_found = False
else:
pymongo_found = True
import json
from six.moves.urllib.parse import quote_plus
def main():
arg_spec = dict(
host=dict(required=False, type='str', default="localhost"),
port=dict(required=False, type='int', default=27017),
username=dict(required=False, type='str'),
password=dict(required=False, type='str'),
auth_database=dict(required=False, type='str')
)
module = AnsibleModule(argument_spec=arg_spec, supports_check_mode=False)
if not pymongo_found:
module.fail_json(msg="The python pymongo module is not installed.")
mongo_uri = 'mongodb://'
host = module.params.get('host')
port = module.params.get('port')
username = module.params.get('username')
password = module.params.get('password')
auth_database = module.params.get('auth_database')
if (username and not password) or (password and not username):
module.fail_json(msg="Must provide both username and password or neither.")
if username:
mongo_uri += "{}:{}@".format(*list(map(quote_plus, [username,password])))
mongo_uri += "{}:{}".format(quote_plus(host),port)
if auth_database:
mongo_uri += '/{}'.format(quote_plus(auth_database))
client = MongoClient(mongo_uri)
# This checks to see if you have a replSetName configured
# This generally means that /etc/mongod.conf has been changed
# from the default to use a replica set and mongo has been
# restarted to use it.
try:
repl_set = client.admin.command('getCmdLineOpts')['parsed']['replication']['replSetName']
except (OperationFailure, KeyError):
module.exit_json(changed=False)
if repl_set:
status = client.admin.command("replSetGetStatus")
# Not using `replSetGetConfig` because it's not supported in MongoDB 2.x.
rs_config = client.local.system.replset.find_one()
else:
module.exit_json(changed=False)
# This converts the bson into a python dictionary that ansible's standard
# jsonify function can process and output without throwing errors on bson
# types that don't exist in JSON
status = json.loads(json_util.dumps(status))
rs_config = json.loads(json_util.dumps(rs_config))
# Status contains information about Primary/Secondary, so we iterate that list
# But we want to return config for that host, not status (since this is the config module),
# this is the inner loop of the comprehension, where we match on the hostname (could also
# match on _id).
primary = [ c for m in status['members'] if m['stateStr'] == 'PRIMARY' for c in rs_config['members'] if m['name'] == c['host'] ]
secondary = [ c for m in status['members'] if m['stateStr'] == 'SECONDARY' for c in rs_config['members'] if m['name'] == c['host'] ]
# we're parsing the config directly here, much simpler
hidden = [ m for m in rs_config['members'] if m['hidden'] ]
module.exit_json(changed=False, primary=primary, secondary=secondary, hidden=hidden, config=rs_config)
if __name__ == '__main__':
main()