Files
offline_kubespray/collection/community/mongodb/plugins/modules/mongodb_index.py
ByeonJungHun 360c6eef4a offline 작업
2024-02-19 16:02:29 +09:00

406 lines
12 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2020, Rhys Campbell (@rhysmeister) <rhys.james.campbell@googlemail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = r'''
---
module: mongodb_index
short_description: Creates or drops indexes on MongoDB collections.
description:
- Creates or drops indexes on MongoDB collections.
- Supports multiple index options, i.e. unique, sparse and partial.
- Validates existence of indexes by name only.
author: Rhys Campbell (@rhysmeister)
version_added: "1.0.0"
extends_documentation_fragment:
- community.mongodb.login_options
- community.mongodb.ssl_options
options:
indexes:
description:
- List of indexes to create or drop
type: list
elements: raw
required: yes
replica_set:
description:
- Replica set to connect to (automatically connects to primary for writes).
type: str
notes:
- Requires the pymongo Python package on the remote host, version 2.4.2+.
requirements:
- pymongo
'''
EXAMPLES = r'''
- name: Create a single index on a collection
community.mongodb.mongodb_index:
login_user: admin
login_password: secret
indexes:
- database: mydb
collection: test
keys:
- username: 1
last_login: -1
options:
name: myindex
state: present
- name: Drop an index on a collection
community.mongodb.mongodb_index:
login_user: admin
login_password: secret
indexes:
- database: mydb
collection: test
options:
name: myindex
state: absent
- name: Create multiple indexes
community.mongodb.mongodb_index:
login_user: admin
login_password: secret
indexes:
- database: mydb
collection: test
keys:
- username: 1
last_login: -1
options:
name: myindex
state: present
- database: mydb
collection: test
keys:
- email: 1
last_login: -1
options:
name: myindex2
state: present
- name: Add a unique index
community.mongodb.mongodb_index:
login_port: 27017
login_user: admin
login_password: secret
login_database: "admin"
indexes:
- database: "test"
collection: "rhys"
keys:
username: 1
options:
name: myuniqueindex
unique: true
state: present
- name: Add a ttl index
community.mongodb.mongodb_index:
login_port: 27017
login_user: admin
login_password: secret
login_database: "admin"
indexes:
- database: "test"
collection: "rhys"
keys:
created: 1
options:
name: myttlindex
expireAfterSeconds: 3600
state: present
- name: Add a sparse index
community.mongodb.mongodb_index:
login_port: 27017
login_user: admin
login_password: secret
login_database: "admin"
indexes:
- database: "test"
collection: "rhys"
keys:
last_login: -1
options:
name: mysparseindex
sparse: true
state: present
- name: Add a partial index
community.mongodb.mongodb_index:
login_port: 27017
login_user: admin
login_password: secret
login_database: "admin"
indexes:
- database: "test"
collection: "rhys"
keys:
last_login: -1
options:
name: mypartialindex
partialFilterExpression:
rating:
$gt: 5
state: present
- name: Add a index in the background (background option is deprecated from 4.2+)
community.mongodb.mongodb_index:
login_port: 27017
login_user: admin
login_password: secret
login_database: "admin"
indexes:
- database: "test"
collection: "rhys"
options:
name: idxbackground
keys:
username: -1
backgroud: true
state: present
- name: Check creating 5 index all with multiple options specified
community.mongodb.mongodb_index:
login_port: 27017
login_user: admin
login_password: secret
login_database: "admin"
indexes:
- database: "test"
collection: "indextest"
options:
name: "idx_unq_username"
unique: true
keys:
username: -1
state: present
- database: "test"
collection: "indextest"
options:
name: "idx_last_login"
sparse: true
keys:
last_login: -1
state: present
- database: "test"
collection: "indextest"
options:
name: "myindex"
keys:
first_name: 1
last_name: -1
city: 1
state: present
- database: "test"
collection: partialtest
options:
name: "idx_partialtest"
partialFilterExpression:
rating:
$gt: 5
keys:
rating: -1
title: 1
state: present
- database: "test"
collection: "wideindex"
options:
name: "mywideindex"
keys:
email: -1
username: 1
first_name: 1
last_name: 1
dob: -1
city: 1
last_login: -1
review_count: 1
rating_count: 1
last_post: -1
state: present
'''
RETURN = r'''
indexes_created:
description: List of indexes created.
returned: always
type: list
sample: ["myindex", "myindex2"]
indexes_dropped:
description: List of indexes dropped.
returned: always
type: list
sample: ["myindex", "myindex2"]
changed:
description: Indicates the module has changed something.
returned: When the module has changed something.
type: bool
failed:
description: Indicates the module has failed.
returned: When the module has encountered an error.
type: bool
'''
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.mongodb.plugins.module_utils.mongodb_common import (
missing_required_lib,
mongodb_common_argument_spec,
PYMONGO_IMP_ERR,
pymongo_found,
index_exists,
create_index,
drop_index,
mongo_auth,
get_mongodb_client,
)
def validate_module(module):
'''
Runs validation rules specific the mongodb_index module
'''
required_index_keys = [
"database",
"collection",
"options",
"state",
]
indexes = module.params['indexes']
if len(indexes) == 0:
module.fail_json(msg="One or more indexes must be specified")
if not all(isinstance(i, dict) for i in indexes):
module.fail_json(msg="Indexes must be supplied as dictionaries")
# Ensure keys are present in index spec
for k in required_index_keys:
for i in indexes:
if k not in i.keys():
module.fail_json(msg="Missing required index key {0}".format(k))
# Check index subkeys look correct
for i in indexes:
if not isinstance(i["database"], str):
module.fail_json(msg="database key should be str")
elif not isinstance(i["collection"], str):
module.fail_json(msg="collection key should be str")
elif i["state"] == "present" and "keys" not in i.keys():
module.fail_json(msg="keys must be supplied when state is present")
elif i["state"] == "present" and not isinstance(i["keys"], dict):
module.fail_json(msg="keys key should be dict")
elif not isinstance(i["options"], dict):
module.fail_json(msg="options key should be dict")
elif "name" not in i["options"]:
module.fail_json(msg="The options dict must contain a name field")
elif i["state"] not in ["present", "absent"]:
module.fail_json(msg="state must be one of present or absent")
# ================
# Module execution
#
def main():
argument_spec = mongodb_common_argument_spec()
argument_spec.update(
indexes=dict(type='list', elements='raw', required=True),
replica_set=dict(type='str'),
)
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
required_together=[['login_user', 'login_password']],
)
if not pymongo_found:
module.fail_json(msg=missing_required_lib('pymongo'),
exception=PYMONGO_IMP_ERR)
validate_module(module)
indexes = module.params['indexes']
client = get_mongodb_client(module)
client = mongo_auth(module, client)
# Pre flight checks done
indexes_created = []
indexes_dropped = []
changed = None
for i in indexes:
try:
idx = index_exists(client, i["database"], i["collection"], i["options"]["name"])
except Exception as excep:
module.fail_json(msg="Could not determine index status: {0}".format(str(excep)))
if module.check_mode:
if idx:
if i["state"] == "present":
changed = False
elif i["state"] == "absent":
indexes_dropped.append("{0}.{1}.{2}".format(i["database"],
i["collection"],
i["options"]["name"]))
changed = True
else:
if i["state"] == "present":
indexes_created.append("{0}.{1}.{2}".format(i["database"],
i["collection"],
i["options"]["name"]))
changed = True
elif i["state"] == "absent":
changed = False
else:
if idx:
if i["state"] == "present":
changed = False
elif i["state"] == "absent":
try:
drop_index(client, i["database"], i["collection"],
i["options"]["name"])
indexes_dropped.append("{0}.{1}.{2}".format(i["database"],
i["collection"],
i["options"]["name"]))
changed = True
except Exception as excep:
module.fail_json(msg="Error dropping index: {0}".format(str(excep)))
else:
if i["state"] == "present":
try:
create_index(client=client,
database=i["database"],
collection=i["collection"],
keys=i["keys"],
options=i["options"])
indexes_created.append("{0}.{1}.{2}".format(i["database"],
i["collection"],
i["options"]["name"]))
changed = True
except Exception as excep:
module.fail_json(msg="Error creating index: {0}".format(str(excep)))
elif i["state"] == "absent":
changed = False
module.exit_json(changed=changed,
indexes_created=indexes_created,
indexes_dropped=indexes_dropped)
if __name__ == '__main__':
main()