Update elasticsearch_plugin.py (#28936)
* Update elasticsearch_plugin.py Change module to work with Elasticsearch 2.x and 5.x automatically. Update examples and docs. Supersedes #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
This commit is contained in:
parent
c9f2b931db
commit
a5ee865634
2 changed files with 91 additions and 35 deletions
|
@ -1,16 +1,18 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# (c) 2015, Mathew Davies <thepixeldeveloper@googlemail.com>
|
# (c) 2015, Mathew Davies <thepixeldeveloper@googlemail.com>
|
||||||
|
# (c) 2017, Sam Doran <sdoran@redhat.com>
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
# 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
|
from __future__ import absolute_import, division, print_function
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
ANSIBLE_METADATA = {
|
||||||
'status': ['preview'],
|
'metadata_version': '1.1',
|
||||||
'supported_by': 'community'}
|
'status': ['preview'],
|
||||||
|
'supported_by': 'community'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
|
@ -20,11 +22,13 @@ short_description: Manage Elasticsearch plugins
|
||||||
description:
|
description:
|
||||||
- Manages Elasticsearch plugins.
|
- Manages Elasticsearch plugins.
|
||||||
version_added: "2.0"
|
version_added: "2.0"
|
||||||
author: Mathew Davies (@ThePixelDeveloper)
|
author:
|
||||||
|
- Mathew Davies (@ThePixelDeveloper)
|
||||||
|
- Sam Doran (@samdoran)
|
||||||
options:
|
options:
|
||||||
name:
|
name:
|
||||||
description:
|
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
|
required: True
|
||||||
state:
|
state:
|
||||||
description:
|
description:
|
||||||
|
@ -40,13 +44,15 @@ options:
|
||||||
timeout:
|
timeout:
|
||||||
description:
|
description:
|
||||||
- "Timeout setting: 30s, 1m, 1h..."
|
- "Timeout setting: 30s, 1m, 1h..."
|
||||||
|
- Only valid for Elasticsearch < 5.0. This option is ignored for Elasticsearch > 5.0.
|
||||||
required: False
|
required: False
|
||||||
default: 1m
|
default: 1m
|
||||||
plugin_bin:
|
plugin_bin:
|
||||||
description:
|
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
|
required: False
|
||||||
default: /usr/share/elasticsearch/bin/plugin
|
default: None
|
||||||
plugin_dir:
|
plugin_dir:
|
||||||
description:
|
description:
|
||||||
- Your configured plugin directory specified in Elasticsearch
|
- Your configured plugin directory specified in Elasticsearch
|
||||||
|
@ -73,21 +79,25 @@ options:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
# Install Elasticsearch head plugin
|
# Install Elasticsearch Head plugin in Elasticsearch 2.x
|
||||||
- elasticsearch_plugin:
|
- elasticsearch_plugin:
|
||||||
state: present
|
|
||||||
name: mobz/elasticsearch-head
|
name: mobz/elasticsearch-head
|
||||||
|
|
||||||
# Install specific version of a plugin
|
|
||||||
- elasticsearch_plugin:
|
|
||||||
state: present
|
state: present
|
||||||
name: com.github.kzwang/elasticsearch-image
|
|
||||||
version: '1.2.0'
|
|
||||||
|
|
||||||
# Uninstall Elasticsearch head plugin
|
# Install a specific version of Elasticsearch Head in Elasticsearch 2.x
|
||||||
- elasticsearch_plugin:
|
- elasticsearch_plugin:
|
||||||
|
name: mobz/elasticsearch-head
|
||||||
|
versino: 2.0.0
|
||||||
|
|
||||||
|
# Uninstall Elasticsearch head plugin in Elasticsearch 2.x
|
||||||
|
- elasticsearch_plugin:
|
||||||
|
name: mobz/elasticsearch-head
|
||||||
state: absent
|
state: absent
|
||||||
name: mobz/elasticsearch-head
|
|
||||||
|
# Install a specific plugin in Elasticsearch >= 5.0
|
||||||
|
- elasticsearch_plugin:
|
||||||
|
name: analysis-icu
|
||||||
|
state: present
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
@ -100,6 +110,11 @@ PACKAGE_STATE_MAP = dict(
|
||||||
absent="remove"
|
absent="remove"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
PLUGIN_BIN_PATHS = tuple([
|
||||||
|
'/usr/share/elasticsearch/bin/elasticsearch-plugin',
|
||||||
|
'/usr/share/elasticsearch/bin/plugin'
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def parse_plugin_repo(string):
|
def parse_plugin_repo(string):
|
||||||
elements = string.split("/")
|
elements = string.split("/")
|
||||||
|
@ -119,21 +134,30 @@ def parse_plugin_repo(string):
|
||||||
|
|
||||||
return repo
|
return repo
|
||||||
|
|
||||||
|
|
||||||
def is_plugin_present(plugin_dir, working_dir):
|
def is_plugin_present(plugin_dir, working_dir):
|
||||||
return os.path.isdir(os.path.join(working_dir, plugin_dir))
|
return os.path.isdir(os.path.join(working_dir, plugin_dir))
|
||||||
|
|
||||||
|
|
||||||
def parse_error(string):
|
def parse_error(string):
|
||||||
reason = "reason: "
|
reason = "ERROR: "
|
||||||
try:
|
try:
|
||||||
return string[string.index(reason) + len(reason):].strip()
|
return string[string.index(reason) + len(reason):].strip()
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return string
|
return string
|
||||||
|
|
||||||
|
|
||||||
def install_plugin(module, plugin_bin, plugin_name, version, url, proxy_host, proxy_port, timeout):
|
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]
|
cmd_args = [plugin_bin, PACKAGE_STATE_MAP["present"], plugin_name]
|
||||||
|
|
||||||
if version:
|
# Timeout and version are only valid for plugin, not elasticsearch-plugin
|
||||||
plugin_name = plugin_name + '/' + version
|
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:
|
if proxy_host and proxy_port:
|
||||||
cmd_args.append("-DproxyHost=%s -DproxyPort=%s" % (proxy_host, proxy_port))
|
cmd_args.append("-DproxyHost=%s -DproxyPort=%s" % (proxy_host, proxy_port))
|
||||||
|
@ -141,9 +165,6 @@ def install_plugin(module, plugin_bin, plugin_name, version, url, proxy_host, pr
|
||||||
if url:
|
if url:
|
||||||
cmd_args.append("--url %s" % url)
|
cmd_args.append("--url %s" % url)
|
||||||
|
|
||||||
if timeout:
|
|
||||||
cmd_args.append("--timeout %s" % timeout)
|
|
||||||
|
|
||||||
cmd = " ".join(cmd_args)
|
cmd = " ".join(cmd_args)
|
||||||
|
|
||||||
if module.check_mode:
|
if module.check_mode:
|
||||||
|
@ -153,10 +174,11 @@ def install_plugin(module, plugin_bin, plugin_name, version, url, proxy_host, pr
|
||||||
|
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
reason = parse_error(out)
|
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
|
return True, cmd, out, err
|
||||||
|
|
||||||
|
|
||||||
def remove_plugin(module, plugin_bin, plugin_name):
|
def remove_plugin(module, plugin_bin, plugin_name):
|
||||||
cmd_args = [plugin_bin, PACKAGE_STATE_MAP["absent"], parse_plugin_repo(plugin_name)]
|
cmd_args = [plugin_bin, PACKAGE_STATE_MAP["absent"], parse_plugin_repo(plugin_name)]
|
||||||
|
|
||||||
|
@ -173,6 +195,38 @@ def remove_plugin(module, plugin_bin, plugin_name):
|
||||||
|
|
||||||
return True, cmd, out, err
|
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():
|
def main():
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
|
@ -180,7 +234,7 @@ def main():
|
||||||
state=dict(default="present", choices=PACKAGE_STATE_MAP.keys()),
|
state=dict(default="present", choices=PACKAGE_STATE_MAP.keys()),
|
||||||
url=dict(default=None),
|
url=dict(default=None),
|
||||||
timeout=dict(default="1m"),
|
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"),
|
plugin_dir=dict(default="/usr/share/elasticsearch/plugins/", type="path"),
|
||||||
proxy_host=dict(default=None),
|
proxy_host=dict(default=None),
|
||||||
proxy_port=dict(default=None),
|
proxy_port=dict(default=None),
|
||||||
|
@ -189,15 +243,18 @@ def main():
|
||||||
supports_check_mode=True
|
supports_check_mode=True
|
||||||
)
|
)
|
||||||
|
|
||||||
name = module.params["name"]
|
name = module.params["name"]
|
||||||
state = module.params["state"]
|
state = module.params["state"]
|
||||||
url = module.params["url"]
|
url = module.params["url"]
|
||||||
timeout = module.params["timeout"]
|
timeout = module.params["timeout"]
|
||||||
plugin_bin = module.params["plugin_bin"]
|
plugin_bin = module.params["plugin_bin"]
|
||||||
plugin_dir = module.params["plugin_dir"]
|
plugin_dir = module.params["plugin_dir"]
|
||||||
proxy_host = module.params["proxy_host"]
|
proxy_host = module.params["proxy_host"]
|
||||||
proxy_port = module.params["proxy_port"]
|
proxy_port = module.params["proxy_port"]
|
||||||
version = module.params["version"]
|
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)
|
present = is_plugin_present(parse_plugin_repo(name), plugin_dir)
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,6 @@ lib/ansible/modules/clustering/consul_kv.py
|
||||||
lib/ansible/modules/clustering/consul_session.py
|
lib/ansible/modules/clustering/consul_session.py
|
||||||
lib/ansible/modules/clustering/kubernetes.py
|
lib/ansible/modules/clustering/kubernetes.py
|
||||||
lib/ansible/modules/clustering/pacemaker_cluster.py
|
lib/ansible/modules/clustering/pacemaker_cluster.py
|
||||||
lib/ansible/modules/database/misc/elasticsearch_plugin.py
|
|
||||||
lib/ansible/modules/database/misc/kibana_plugin.py
|
lib/ansible/modules/database/misc/kibana_plugin.py
|
||||||
lib/ansible/modules/database/misc/redis.py
|
lib/ansible/modules/database/misc/redis.py
|
||||||
lib/ansible/modules/database/misc/riak.py
|
lib/ansible/modules/database/misc/riak.py
|
||||||
|
|
Loading…
Reference in a new issue