@ -1,16 +1,18 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (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)
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 @@ short_description: Manage Elasticsearch plugins
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 E S 2. x , the name can be an url or file location
- Name of the plugin to install . In E leasticsearch > = 2.0 , the name can be an URL or file location .
required : True
state :
description :
@ -40,13 +44,15 @@ options:
timeout :
description :
- " Timeout setting: 30s, 1m, 1h... "
- Only valid for Elasticsearch < 5.0 . This option is ignored for Elasticsearch > 5.0 .
required : False
default : 1 m
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 @@ options:
'''
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 @@ PACKAGE_STATE_MAP = dict(
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,21 +134,30 @@ 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 ) )
@ -141,9 +165,6 @@ def install_plugin(module, plugin_bin, plugin_name, version, url, proxy_host, pr
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,6 +195,38 @@ 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 (
@ -180,7 +234,7 @@ def main():
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 )