forked from ansible/ansible
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update elasticsearch_plugin.py (ansible#28936)
* Update elasticsearch_plugin.py Change module to work with Elasticsearch 2.x and 5.x automatically. Update examples and docs. Supersedes ansible#21989 * Check system paths for elasticsearch-plugin binary Use get_bin_path from basic.py for searching paths. * Create a copy of PLUGIN_BIN_PATHS rather than modifying the global * Use provided plugin_bin path first before trying other places Change global PLUGIN_BIN_PATHS to a tuple
- Loading branch information
Showing
2 changed files
with
90 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,18 @@ | ||
#!/usr/bin/python | ||
# -*- coding: utf-8 -*- | ||
|
||
# (c) 2015, Mathew Davies <[email protected]> | ||
# (c) 2017, Sam Doran <[email protected]> | ||
# 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 | ||
|
||
|
||
ANSIBLE_METADATA = {'metadata_version': '1.1', | ||
'status': ['preview'], | ||
'supported_by': 'community'} | ||
ANSIBLE_METADATA = { | ||
'metadata_version': '1.1', | ||
'status': ['preview'], | ||
'supported_by': 'community' | ||
} | ||
|
||
|
||
DOCUMENTATION = ''' | ||
|
@@ -20,11 +22,13 @@ | |
description: | ||
- Manages Elasticsearch plugins. | ||
version_added: "2.0" | ||
author: Mathew Davies (@ThePixelDeveloper) | ||
author: | ||
- Mathew Davies (@ThePixelDeveloper) | ||
- Sam Doran (@samdoran) | ||
options: | ||
name: | ||
description: | ||
- Name of the plugin to install. In ES 2.x, the name can be an url or file location | ||
- Name of the plugin to install. In Eleasticsearch >= 2.0, the name can be an URL or file location. | ||
required: True | ||
state: | ||
description: | ||
|
@@ -40,13 +44,15 @@ | |
timeout: | ||
description: | ||
- "Timeout setting: 30s, 1m, 1h..." | ||
- Only valid for Elasticsearch < 5.0. This option is ignored for Elasticsearch > 5.0. | ||
required: False | ||
default: 1m | ||
plugin_bin: | ||
description: | ||
- Location of the plugin binary | ||
- Location of the plugin binary. If this file is not found, the default plugin binaries will be used. | ||
- The default changed in Ansible 2.4 to None. | ||
required: False | ||
default: /usr/share/elasticsearch/bin/plugin | ||
default: None | ||
plugin_dir: | ||
description: | ||
- Your configured plugin directory specified in Elasticsearch | ||
|
@@ -73,21 +79,25 @@ | |
''' | ||
|
||
EXAMPLES = ''' | ||
# Install Elasticsearch head plugin | ||
# Install Elasticsearch Head plugin in Elasticsearch 2.x | ||
- elasticsearch_plugin: | ||
state: present | ||
name: mobz/elasticsearch-head | ||
state: present | ||
# Install specific version of a plugin | ||
# Install a specific version of Elasticsearch Head in Elasticsearch 2.x | ||
- elasticsearch_plugin: | ||
state: present | ||
name: com.github.kzwang/elasticsearch-image | ||
version: '1.2.0' | ||
name: mobz/elasticsearch-head | ||
versino: 2.0.0 | ||
# Uninstall Elasticsearch head plugin | ||
# Uninstall Elasticsearch head plugin in Elasticsearch 2.x | ||
- elasticsearch_plugin: | ||
state: absent | ||
name: mobz/elasticsearch-head | ||
state: absent | ||
# Install a specific plugin in Elasticsearch >= 5.0 | ||
- elasticsearch_plugin: | ||
name: analysis-icu | ||
state: present | ||
''' | ||
|
||
import os | ||
|
@@ -100,6 +110,11 @@ | |
absent="remove" | ||
) | ||
|
||
PLUGIN_BIN_PATHS = tuple([ | ||
'/usr/share/elasticsearch/bin/elasticsearch-plugin', | ||
'/usr/share/elasticsearch/bin/plugin' | ||
]) | ||
|
||
|
||
def parse_plugin_repo(string): | ||
elements = string.split("/") | ||
|
@@ -119,31 +134,37 @@ def parse_plugin_repo(string): | |
|
||
return repo | ||
|
||
|
||
def is_plugin_present(plugin_dir, working_dir): | ||
return os.path.isdir(os.path.join(working_dir, plugin_dir)) | ||
|
||
|
||
def parse_error(string): | ||
reason = "reason: " | ||
reason = "ERROR: " | ||
try: | ||
return string[string.index(reason) + len(reason):].strip() | ||
except ValueError: | ||
return string | ||
|
||
|
||
def install_plugin(module, plugin_bin, plugin_name, version, url, proxy_host, proxy_port, timeout): | ||
cmd_args = [plugin_bin, PACKAGE_STATE_MAP["present"], plugin_name] | ||
|
||
if version: | ||
plugin_name = plugin_name + '/' + version | ||
# Timeout and version are only valid for plugin, not elasticsearch-plugin | ||
if os.path.basename(plugin_bin) == 'plugin': | ||
if timeout: | ||
cmd_args.append("--timeout %s" % timeout) | ||
|
||
if version: | ||
plugin_name = plugin_name + '/' + version | ||
cmd_args[2] = plugin_name | ||
|
||
if proxy_host and proxy_port: | ||
cmd_args.append("-DproxyHost=%s -DproxyPort=%s" % (proxy_host, proxy_port)) | ||
|
||
if url: | ||
cmd_args.append("--url %s" % url) | ||
|
||
if timeout: | ||
cmd_args.append("--timeout %s" % timeout) | ||
|
||
cmd = " ".join(cmd_args) | ||
|
||
if module.check_mode: | ||
|
@@ -153,10 +174,11 @@ def install_plugin(module, plugin_bin, plugin_name, version, url, proxy_host, pr | |
|
||
if rc != 0: | ||
reason = parse_error(out) | ||
module.fail_json(msg=reason) | ||
module.fail_json(msg='Is %s a valid plugin name?' % plugin_name, err=reason) | ||
|
||
return True, cmd, out, err | ||
|
||
|
||
def remove_plugin(module, plugin_bin, plugin_name): | ||
cmd_args = [plugin_bin, PACKAGE_STATE_MAP["absent"], parse_plugin_repo(plugin_name)] | ||
|
||
|
@@ -173,14 +195,46 @@ def remove_plugin(module, plugin_bin, plugin_name): | |
|
||
return True, cmd, out, err | ||
|
||
|
||
def get_plugin_bin(module, plugin_bin): | ||
# Use the plugin_bin that was supplied first before trying other options | ||
if plugin_bin: | ||
if os.path.isfile(plugin_bin): | ||
valid_plugin_bin = plugin_bin | ||
|
||
else: | ||
# Add the plugin_bin passed into the module to the top of the list of paths to test, | ||
# testing for that binary name first before falling back to the default paths. | ||
bin_paths = list(PLUGIN_BIN_PATHS) | ||
if plugin_bin and plugin_bin not in bin_paths: | ||
bin_paths.insert(0, plugin_bin) | ||
|
||
# Get separate lists of dirs and binary names from the full paths to the | ||
# plugin binaries. | ||
plugin_dirs = list(set([os.path.dirname(x) for x in bin_paths])) | ||
plugin_bins = list(set([os.path.basename(x) for x in bin_paths])) | ||
|
||
# Check for the binary names in the default system paths as well as the path | ||
# specified in the module arguments. | ||
for bin_file in plugin_bins: | ||
valid_plugin_bin = module.get_bin_path(bin_file, opt_dirs=plugin_dirs) | ||
if valid_plugin_bin: | ||
break | ||
|
||
if not valid_plugin_bin: | ||
module.fail_json(msg='%s does not exist and no other valid plugin installers were found. Make sure Elasticsearch is installed.' % plugin_bin) | ||
|
||
return valid_plugin_bin | ||
|
||
|
||
def main(): | ||
module = AnsibleModule( | ||
argument_spec=dict( | ||
name=dict(required=True), | ||
state=dict(default="present", choices=PACKAGE_STATE_MAP.keys()), | ||
url=dict(default=None), | ||
timeout=dict(default="1m"), | ||
plugin_bin=dict(default="/usr/share/elasticsearch/bin/plugin", type="path"), | ||
plugin_bin=dict(type="path"), | ||
plugin_dir=dict(default="/usr/share/elasticsearch/plugins/", type="path"), | ||
proxy_host=dict(default=None), | ||
proxy_port=dict(default=None), | ||
|
@@ -189,15 +243,18 @@ def main(): | |
supports_check_mode=True | ||
) | ||
|
||
name = module.params["name"] | ||
state = module.params["state"] | ||
url = module.params["url"] | ||
timeout = module.params["timeout"] | ||
plugin_bin = module.params["plugin_bin"] | ||
plugin_dir = module.params["plugin_dir"] | ||
proxy_host = module.params["proxy_host"] | ||
proxy_port = module.params["proxy_port"] | ||
version = module.params["version"] | ||
name = module.params["name"] | ||
state = module.params["state"] | ||
url = module.params["url"] | ||
timeout = module.params["timeout"] | ||
plugin_bin = module.params["plugin_bin"] | ||
plugin_dir = module.params["plugin_dir"] | ||
proxy_host = module.params["proxy_host"] | ||
proxy_port = module.params["proxy_port"] | ||
version = module.params["version"] | ||
|
||
# Search provided path and system paths for valid binary | ||
plugin_bin = get_plugin_bin(module, plugin_bin) | ||
|
||
present = is_plugin_present(parse_plugin_repo(name), plugin_dir) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters