Update the elasticsearch cookbook

This commit is contained in:
Greg Karékinian
2023-06-29 16:39:09 +02:00
parent 68ce3c4834
commit 7683de09a2
48 changed files with 2016 additions and 2065 deletions

View File

@@ -6,16 +6,32 @@ module ElasticsearchCookbook
instance_name = resource.instance_name
# if we are truly given a specific name to find
name_match = find_exact_resource(run_context, resource_type, resource_name) rescue nil
name_match = begin
find_exact_resource(run_context, resource_type, resource_name)
rescue
nil
end
return name_match if name_match
# first try by instance name attribute
name_instance = find_instance_name_resource(run_context, resource_type, instance_name) rescue nil
name_instance = begin
find_instance_name_resource(run_context, resource_type, instance_name)
rescue
nil
end
return name_instance if name_instance
# otherwise try the defaults
name_default = find_exact_resource(run_context, resource_type, 'default') rescue nil
name_elasticsearch = find_exact_resource(run_context, resource_type, 'elasticsearch') rescue nil
name_default = begin
find_exact_resource(run_context, resource_type, 'default')
rescue
nil
end
name_elasticsearch = begin
find_exact_resource(run_context, resource_type, 'elasticsearch')
rescue
nil
end
# if we found exactly one default name that matched
return name_default if name_default && !name_elasticsearch
@@ -58,58 +74,7 @@ module ElasticsearchCookbook
return results.first
end
nil # falsey
end
def determine_download_url(new_resource, node)
platform_family = node['platform_family']
version_key = 'download_urls'
if Gem::Version.new(new_resource.version) >= Gem::Version.new('7.0.0')
version_key = 'download_urls_v7'
end
url_string = nil
if new_resource.download_url
url_string = new_resource.download_url
elsif new_resource.type == 'tarball'
url_string = node['elasticsearch'][version_key]['tarball']
elsif new_resource.type == 'package' && node['elasticsearch']['download_urls'][platform_family]
url_string = node['elasticsearch'][version_key][platform_family]
end
if url_string && new_resource.version
return format(url_string, new_resource.version)
elsif url_string
return url_string
end
end
def determine_download_checksum(new_resource, node)
platform_family = node['platform_family']
# for the sake of finding correct attribute data, use rhel for amazon too
# See https://github.com/elastic/cookbook-elasticsearch/issues/609
platform_family = 'rhel' if platform_family == 'amazon'
install_type = new_resource.type
version = new_resource.version
if new_resource.download_checksum
new_resource.download_checksum
elsif install_type == 'tarball'
node && version &&
node['elasticsearch'] &&
node['elasticsearch']['checksums'] &&
node['elasticsearch']['checksums'][version] &&
node['elasticsearch']['checksums'][version]['tarball']
elsif install_type == 'package' && node['elasticsearch']['checksums'][version] && node['elasticsearch']['checksums'][version][platform_family]
node && version && platform_family &&
node['elasticsearch'] &&
node['elasticsearch']['checksums'] &&
node['elasticsearch']['checksums'][version] &&
node['elasticsearch']['checksums'][version][platform_family]
end
nil
end
# proxy helper for chef sets JVM 8 proxy options
@@ -134,6 +99,10 @@ module ElasticsearchCookbook
end
end
def es_user
find_es_resource(Chef.run_context, :elasticsearch_user, new_resource)
end
class HashAndMashBlender
attr_accessor :target
def initialize(hash_or_mash_or_whatever)

View File

@@ -1,73 +0,0 @@
# ChefSpec is a tool to unit test cookbooks in conjunction with rspec
# Learn more on the README or at https://github.com/sethvargo/chefspec.
if defined?(ChefSpec)
ChefSpec.define_matcher(:elasticsearch_configure)
ChefSpec.define_matcher(:elasticsearch_install)
ChefSpec.define_matcher(:elasticsearch_plugin)
ChefSpec.define_matcher(:elasticsearch_service)
ChefSpec.define_matcher(:elasticsearch_user)
def create_elasticsearch_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_user, :create, resource_name)
end
def remove_elasticsearch_user(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_user, :remove, resource_name)
end
def install_elasticsearch(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_install, :install, resource_name)
end
def remove_elasticsearch(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_install, :remove, resource_name)
end
def manage_elasticsearch_configure(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_configure, :manage, resource_name)
end
def remove_elasticsearch_configure(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_configure, :remove, resource_name)
end
def configure_elasticsearch_service(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_service, :configure, resource_name)
end
def remove_elasticsearch_service(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_service, :remove, resource_name)
end
def enable_elasticsearch_service(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_service, :enable, resource_name)
end
def disable_elasticsearch_service(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_service, :disable, resource_name)
end
def start_elasticsearch_service(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_service, :start, resource_name)
end
def stop_elasticsearch_service(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_service, :stop, resource_name)
end
def restart_elasticsearch_service(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_service, :restart, resource_name)
end
def status_elasticsearch_service(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_service, :status, resource_name)
end
def install_elasticsearch_plugin(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_plugin, :install, resource_name)
end
def remove_elasticsearch_plugin(resource_name)
ChefSpec::Matchers::ResourceMatcher.new(:elasticsearch_plugin, :remove, resource_name)
end
end

View File

@@ -1,164 +0,0 @@
# Chef Provider for configuring an elasticsearch instance
class ElasticsearchCookbook::ConfigureProvider < Chef::Provider::LWRPBase
include ElasticsearchCookbook::Helpers
provides :elasticsearch_configure
def whyrun_supported?
true # we only use core Chef resources that also support whyrun
end
def action_manage
# lookup existing ES resources
es_user = find_es_resource(Chef.run_context, :elasticsearch_user, new_resource)
es_svc = find_es_resource(Chef.run_context, :elasticsearch_service, new_resource)
es_install = find_es_resource(Chef.run_context, :elasticsearch_install, new_resource)
default_configuration = new_resource.default_configuration.dup
# if a subdir parameter is missing but dir is set, infer the subdir name
# then go and be sure it's also set in the YML hash if it wasn't given there
if new_resource.path_data && default_configuration['path.data'].nil?
default_configuration['path.data'] = new_resource.path_data
end
if new_resource.path_logs && default_configuration['path.logs'].nil?
default_configuration['path.logs'] = new_resource.path_logs
end
# calculation for memory allocation; 50% or 31g, whatever is smaller
unless new_resource.allocated_memory
half = ((node['memory']['total'].to_i * 0.5).floor / 1024)
malloc_str = (half > 30_500 ? '30500m' : "#{half}m")
new_resource.allocated_memory malloc_str
end
# Create ES directories
#
[new_resource.path_conf, "#{new_resource.path_conf}/scripts"].each do |path|
d = directory path do
owner es_user.username
group es_user.groupname
mode '0750'
recursive true
action :nothing
end
d.run_action(:create)
new_resource.updated_by_last_action(true) if d.updated_by_last_action?
end
# Create data path directories
#
data_paths = new_resource.path_data.is_a?(Array) ? new_resource.path_data : new_resource.path_data.split(',')
data_paths = data_paths << new_resource.path_logs
data_paths.each do |path|
d = directory path.strip do
owner es_user.username
group es_user.groupname
mode '0755'
recursive true
action :nothing
end
d.run_action(:create)
new_resource.updated_by_last_action(true) if d.updated_by_last_action?
end
# Create elasticsearch shell variables file
#
# Valid values in /etc/sysconfig/elasticsearch or /etc/default/elasticsearch
# ES_HOME JAVA_HOME ES_PATH_CONF DATA_DIR LOG_DIR PID_DIR ES_JAVA_OPTS
# RESTART_ON_UPGRADE ES_USER ES_GROUP ES_STARTUP_SLEEP_TIME MAX_OPEN_FILES
# MAX_LOCKED_MEMORY MAX_MAP_COUNT
#
# We provide these values as resource attributes/parameters directly
params = {}
params[:ES_HOME] = new_resource.path_home
params[:JAVA_HOME] = new_resource.java_home
params[:ES_PATH_CONF] = new_resource.path_conf
params[:DATA_DIR] = new_resource.path_data
params[:LOG_DIR] = new_resource.path_logs
params[:PID_DIR] = new_resource.path_pid
params[:RESTART_ON_UPGRADE] = new_resource.restart_on_upgrade
params[:ES_USER] = es_user.username if es_install.type == 'tarball'
params[:ES_GROUP] = es_user.groupname if es_install.type == 'tarball'
params[:ES_STARTUP_SLEEP_TIME] = new_resource.startup_sleep_seconds.to_s
params[:MAX_OPEN_FILES] = new_resource.nofile_limit
params[:MAX_LOCKED_MEMORY] = new_resource.memlock_limit
params[:MAX_MAP_COUNT] = new_resource.max_map_count
default_config_name = es_svc.service_name || es_svc.instance_name || new_resource.instance_name || 'elasticsearch'
shell_template = template "elasticsearch.in.sh-#{default_config_name}" do
path %w[rhel amazon].include?(node['platform_family']) ? "/etc/sysconfig/#{default_config_name}" : "/etc/default/#{default_config_name}"
source new_resource.template_elasticsearch_env
cookbook new_resource.cookbook_elasticsearch_env
mode '0644'
variables(params: params)
action :nothing
end
shell_template.run_action(:create)
new_resource.updated_by_last_action(true) if shell_template.updated_by_last_action?
# Create jvm.options file
#
jvm_options_template = template "jvm_options-#{default_config_name}" do
path "#{new_resource.path_conf}/jvm.options"
source new_resource.template_jvm_options
cookbook new_resource.cookbook_jvm_options
owner es_user.username
group es_user.groupname
mode '0644'
variables(jvm_options: [
"-Xms#{new_resource.allocated_memory}",
"-Xmx#{new_resource.allocated_memory}",
new_resource.jvm_options,
].flatten.join("\n"))
action :nothing
end
jvm_options_template.run_action(:create)
new_resource.updated_by_last_action(true) if jvm_options_template.updated_by_last_action?
# Create ES logging file
#
logging_template = template "log4j2_properties-#{default_config_name}" do
path "#{new_resource.path_conf}/log4j2.properties"
source new_resource.template_log4j2_properties
cookbook new_resource.cookbook_log4j2_properties
owner es_user.username
group es_user.groupname
mode '0640'
variables(logging: new_resource.logging)
action :nothing
end
logging_template.run_action(:create)
new_resource.updated_by_last_action(true) if logging_template.updated_by_last_action?
# Create ES elasticsearch.yml file
#
merged_configuration = default_configuration.merge(new_resource.configuration.dup)
# warn if someone is using symbols. we don't support.
found_symbols = merged_configuration.keys.select { |s| s.is_a?(Symbol) }
unless found_symbols.empty?
Chef::Log.warn("Please change the following to strings in order to work with this Elasticsearch cookbook: #{found_symbols.join(',')}")
end
# workaround for https://github.com/elastic/cookbook-elasticsearch/issues/590
config_vars = ElasticsearchCookbook::HashAndMashBlender.new(merged_configuration).to_hash
yml_template = template "elasticsearch.yml-#{default_config_name}" do
path "#{new_resource.path_conf}/elasticsearch.yml"
source new_resource.template_elasticsearch_yml
cookbook new_resource.cookbook_elasticsearch_yml
owner es_user.username
group es_user.groupname
mode '0640'
helpers(ElasticsearchCookbook::Helpers)
variables(config: config_vars)
action :nothing
end
yml_template.run_action(:create)
new_resource.updated_by_last_action(true) if yml_template.updated_by_last_action?
end
end

View File

@@ -1,238 +0,0 @@
# Chef Provider for installing or removing Elasticsearch from package or tarball
# downloaded from elasticsearch.org and installed by package manager or ark resource
class ElasticsearchCookbook::InstallProvider < Chef::Provider::LWRPBase
include ElasticsearchCookbook::Helpers
include Chef::DSL::IncludeRecipe
provides :elasticsearch_install
def whyrun_supported?
true # we only use core Chef resources that also support whyrun
end
def action_install
if new_resource.type == 'tarball'
install_tarball_wrapper_action
elsif new_resource.type == 'package'
install_package_wrapper_action
elsif new_resource.type == 'repository'
install_repo_wrapper_action
else
raise "#{install_type} is not a valid install type"
end
end
def action_remove
if new_resource.type == 'tarball'
remove_tarball_wrapper_action
elsif new_resource.type == 'package'
remove_package_wrapper_action
elsif new_resource.type == 'repository'
remove_repo_wrapper_action
else
raise "#{install_type} is not a valid install type"
end
end
protected
def install_repo_wrapper_action
es_user = find_es_resource(Chef.run_context, :elasticsearch_user, new_resource)
unless es_user && es_user.username == 'elasticsearch' && es_user.groupname == 'elasticsearch'
raise 'Custom usernames/group names is not supported in Elasticsearch 6+ repository installation'
end
if new_resource.enable_repository_actions
if node['platform_family'] == 'debian'
apt_r = apt_repo_resource
apt_r.run_action(:add)
new_resource.updated_by_last_action(true) if apt_r.updated_by_last_action?
else
yr_r = yum_repo_resource
yr_r.run_action(:create)
new_resource.updated_by_last_action(true) if yr_r.updated_by_last_action?
end
end
if !new_resource.version.nil? && %w[rhel amazon].include?(node['platform_family']) && !new_resource.version.include?('-')
# NB: yum repo packages are broken in Chef if you don't specify a release
# https://github.com/chef/chef/issues/4103
new_resource.version = "#{new_resource.version}-1"
end
pkg_r = package 'elasticsearch' do
options new_resource.package_options
version new_resource.version
action :nothing
end
pkg_r.run_action(:install)
new_resource.updated_by_last_action(true) if pkg_r.updated_by_last_action?
end
def remove_repo_wrapper_action
if new_resource.enable_repository_actions
if node['platform_family'] == 'debian'
apt_r = apt_repo_resource
apt_r.run_action(:remove)
new_resource.updated_by_last_action(true) if apt_r.updated_by_last_action?
else
yr_r = yum_repo_resource
yr_r.run_action(:delete)
new_resource.updated_by_last_action(true) if yr_r.updated_by_last_action?
end
end
pkg_r = package 'elasticsearch' do
options new_resource.package_options
version new_resource.version
action :nothing
end
pkg_r.run_action(:remove)
new_resource.updated_by_last_action(true) if pkg_r.updated_by_last_action?
end
def install_package_wrapper_action
es_user = find_es_resource(Chef.run_context, :elasticsearch_user, new_resource)
unless es_user && es_user.username == 'elasticsearch' && es_user.groupname == 'elasticsearch'
raise 'Custom usernames/group names is not supported in Elasticsearch 6+ package installation'
end
found_download_url = determine_download_url(new_resource, node)
unless found_download_url
raise 'Could not determine download url for package on this platform'
end
filename = found_download_url.split('/').last
checksum = determine_download_checksum(new_resource, node)
package_options = new_resource.package_options
unless checksum
Chef::Log.warn("No checksum was provided for #{found_download_url}, this may download a new package on every chef run!")
end
remote_file_r = remote_file "#{Chef::Config[:file_cache_path]}/#{filename}" do
source found_download_url
checksum checksum
mode '0644'
action :nothing
end
remote_file_r.run_action(:create)
new_resource.updated_by_last_action(true) if remote_file_r.updated_by_last_action?
pkg_r = if node['platform_family'] == 'debian'
dpkg_package "#{Chef::Config[:file_cache_path]}/#{filename}" do
options package_options
action :nothing
end
else
package "#{Chef::Config[:file_cache_path]}/#{filename}" do
options package_options
action :nothing
end
end
pkg_r.run_action(:install)
new_resource.updated_by_last_action(true) if pkg_r.updated_by_last_action?
end
def remove_package_wrapper_action
package_url = determine_download_url(new_resource, node)
filename = package_url.split('/').last
pkg_r = if node['platform_family'] == 'debian'
dpkg_package "#{Chef::Config[:file_cache_path]}/#{filename}" do
action :nothing
end
else
package "#{Chef::Config[:file_cache_path]}/#{filename}" do
action :nothing
end
end
pkg_r.run_action(:remove)
new_resource.updated_by_last_action(true) if pkg_r.updated_by_last_action?
end
def install_tarball_wrapper_action
include_recipe 'ark'
es_user = find_es_resource(Chef.run_context, :elasticsearch_user, new_resource)
found_download_url = determine_download_url(new_resource, node)
unless found_download_url
raise 'Could not determine download url for tarball on this platform'
end
ark_r = ark 'elasticsearch' do
url found_download_url
owner es_user.username
group es_user.groupname
version new_resource.version
has_binaries ['bin/elasticsearch', 'bin/elasticsearch-plugin']
checksum determine_download_checksum(new_resource, node)
prefix_root new_resource.dir
prefix_home new_resource.dir
not_if do
link = "#{new_resource.dir}/elasticsearch"
target = "#{new_resource.dir}/elasticsearch-#{new_resource.version}"
binary = "#{target}/bin/elasticsearch"
::File.directory?(link) && ::File.symlink?(link) && ::File.readlink(link) == target && ::File.exist?(binary)
end
action :nothing
end
ark_r.run_action(:install)
new_resource.updated_by_last_action(true) if ark_r.updated_by_last_action?
# destroy the sample config directory for tarball installs, or it will
# take precedence beyond the default stuff in /etc/elasticsearch and within
# /etc/sysconfig or /etc/default
sample_r = directory "#{new_resource.dir}/elasticsearch/config" do
action :nothing
recursive true
end
sample_r.run_action(:delete)
new_resource.updated_by_last_action(true) if sample_r.updated_by_last_action?
end
def remove_tarball_wrapper_action
# remove the symlink to this version
link_r = link "#{new_resource.dir}/elasticsearch" do
only_if do
link = "#{new_resource.dir}/elasticsearch"
target = "#{new_resource.dir}/elasticsearch-#{new_resource.version}"
::File.directory?(link) && ::File.symlink?(link) && ::File.readlink(link) == target
end
action :nothing
end
link_r.run_action(:delete)
new_resource.updated_by_last_action(true) if link_r.updated_by_last_action?
# remove the specific version
d_r = directory "#{new_resource.dir}/elasticsearch-#{new_resource.version}" do
recursive true
action :nothing
end
d_r.run_action(:delete)
new_resource.updated_by_last_action(true) if d_r.updated_by_last_action?
end
def yum_repo_resource
yum_repository "elastic-#{new_resource.version.to_i}.x" do
baseurl "https://artifacts.elastic.co/packages/#{new_resource.version.to_i}.x/yum"
gpgkey 'https://artifacts.elastic.co/GPG-KEY-elasticsearch'
action :nothing # :add, remove
end
end
def apt_repo_resource
apt_repository "elastic-#{new_resource.version.to_i}.x" do
uri "https://artifacts.elastic.co/packages/#{new_resource.version.to_i}.x/apt"
key 'https://artifacts.elastic.co/GPG-KEY-elasticsearch'
components ['main']
distribution 'stable'
action :nothing # :create, :delete
end
end
end

View File

@@ -1,108 +0,0 @@
# Chef Provider for installing an elasticsearch plugin
class ElasticsearchCookbook::PluginProvider < Chef::Provider::LWRPBase
include ElasticsearchCookbook::Helpers
include Chef::Mixin::ShellOut
provides :elasticsearch_plugin
def whyrun_supported?
true # we only use core Chef resources that also support whyrun, or guard
end
def action_install
return if plugin_exists(new_resource.plugin_name)
# since install can take a URL argument instead
url_or_name = new_resource.url || new_resource.plugin_name
manage_plugin("install #{url_or_name}")
end # action
def action_remove
return unless plugin_exists(new_resource.plugin_name)
manage_plugin("remove #{new_resource.plugin_name}")
end # action
def manage_plugin(arguments)
es_user = find_es_resource(Chef.run_context, :elasticsearch_user, new_resource)
es_install = find_es_resource(Chef.run_context, :elasticsearch_install, new_resource)
es_conf = find_es_resource(Chef.run_context, :elasticsearch_configure, new_resource)
assert_state_is_valid(es_user, es_install, es_conf) unless whyrun_mode?
# shell_out! automatically raises on error, logs command output
# required for package installs that show up with parent dir owned by root
plugin_dir_exists = ::File.exist?(es_conf.path_plugins)
unless plugin_dir_exists
cmd_str = "mkdir -p #{es_conf.path_plugins}"
if whyrun_mode?
Chef::Log.info("Would run command: #{cmd_str}")
else
shell_out_as_user!(cmd_str, Chef.run_context)
new_resource.updated_by_last_action(true)
end
end
unless plugin_exists(new_resource.plugin_name)
cmd_str = "#{es_conf.path_bin}/elasticsearch-plugin #{arguments.chomp(' ')} #{new_resource.options}".chomp(' ')
if whyrun_mode?
Chef::Log.info("Would run command: #{cmd_str}")
else
command_array = cmd_str.split(' ')
shell_out_as_user!(command_array, Chef.run_context)
new_resource.updated_by_last_action(true)
end
end
end
def plugin_exists(name)
es_conf = find_es_resource(Chef.run_context, :elasticsearch_configure, new_resource)
path = es_conf.path_plugins
Dir.entries(path).any? do |plugin|
next if plugin =~ /^\./
name == plugin
end
rescue
false
end
def assert_state_is_valid(_es_user, _es_install, es_conf)
unless es_conf.path_plugins # we do not check existence (may not exist if no plugins installed)
raise "Could not determine the plugin directory (#{es_conf.path_plugins}). Please check elasticsearch_configure[#{es_conf.name}]."
end
unless es_conf.path_bin && ::File.exist?(es_conf.path_bin)
raise "Could not determine the binary directory (#{es_conf.path_bin}). Please check elasticsearch_configure[#{es_conf.name}]."
end
true
end
def shell_out_as_user!(command, run_ctx)
es_install = find_es_resource(run_ctx, :elasticsearch_install, new_resource)
es_conf = find_es_resource(run_ctx, :elasticsearch_configure, new_resource)
es_svc = find_es_resource(run_ctx, :elasticsearch_service, new_resource)
# we need to figure out the env file path to set environment for plugins
default_config_name = es_svc.service_name || es_svc.instance_name || es_conf.instance_name || 'elasticsearch'
include_file_resource = find_exact_resource(run_ctx, :template, "elasticsearch.in.sh-#{default_config_name}")
env = { 'ES_INCLUDE' => include_file_resource.path }
# Add HTTP Proxy vars unless explicitly told not to
if new_resource.chef_proxy
env['ES_JAVA_OPTS'] = "#{ENV['ES_JAVA_OPTS']} #{get_java_proxy_arguments}"
end
# See this link for an explanation:
# https://www.elastic.co/guide/en/elasticsearch/plugins/2.1/plugin-management.html
if es_install.type == 'package' || es_install.type == 'repository'
# package installations should install plugins as root
shell_out!(command, :env => env, :timeout => 1200)
else
# non-package installations should install plugins as the ES user
es_user = find_es_resource(run_ctx, :elasticsearch_user, new_resource)
shell_out!(command, user: es_user.username, group: es_user.groupname, :env => env, :timeout => 1200)
end
end
end # provider

View File

@@ -1,140 +0,0 @@
# Chef Provider for configuring an elasticsearch service in the init system
class ElasticsearchCookbook::ServiceProvider < Chef::Provider::LWRPBase
provides :elasticsearch_service
include ElasticsearchCookbook::Helpers
def whyrun_supported?
true # we only use core Chef resources that also support whyrun
end
def action_remove
raise "#{new_resource} remove not currently implemented"
end
def action_configure
es_user = find_es_resource(Chef.run_context, :elasticsearch_user, new_resource)
es_install = find_es_resource(Chef.run_context, :elasticsearch_install, new_resource)
es_conf = find_es_resource(Chef.run_context, :elasticsearch_configure, new_resource)
default_config_name = new_resource.service_name || new_resource.instance_name || es_conf.instance_name || 'elasticsearch'
d_r = directory "#{es_conf.path_pid}-#{default_config_name}" do
path es_conf.path_pid
owner es_user.username
group es_user.groupname
mode '0755'
recursive true
action :nothing
end
d_r.run_action(:create)
new_resource.updated_by_last_action(true) if d_r.updated_by_last_action?
# Create service for init and systemd
#
if new_resource.init_source
init_r = template "/etc/init.d/#{new_resource.service_name}" do
source new_resource.init_source
cookbook new_resource.init_cookbook
owner 'root'
mode '0755'
variables(
# we need to include something about #{progname} fixed in here.
program_name: new_resource.service_name,
install_type: es_install.type
)
only_if { ::File.exist?('/etc/init.d') }
action :nothing
end
init_r.run_action(:create)
new_resource.updated_by_last_action(true) if init_r.updated_by_last_action?
end
if new_resource.systemd_source
systemd_parent_r = directory "/usr/lib/systemd/system-#{default_config_name}" do
path '/usr/lib/systemd/system'
action :nothing
only_if { ::File.exist?('/usr/lib/systemd') }
end
systemd_parent_r.run_action(:create)
new_resource.updated_by_last_action(true) if systemd_parent_r.updated_by_last_action?
default_conf_dir = %w[rhel amazon].include?(node['platform_family']) ? '/etc/sysconfig' : '/etc/default'
systemd_r = template "/usr/lib/systemd/system/#{new_resource.service_name}.service" do
source new_resource.systemd_source
cookbook new_resource.systemd_cookbook
owner 'root'
mode '0644'
variables(
# we need to include something about #{progname} fixed in here.
program_name: new_resource.service_name,
default_dir: default_conf_dir,
path_home: es_conf.path_home,
es_user: es_user.username,
es_group: es_user.groupname,
nofile_limit: es_conf.nofile_limit,
install_type: es_install.type
)
only_if 'which systemctl'
action :nothing
end
systemd_r.run_action(:create)
# special case here -- must reload unit files if we modified one
if systemd_r.updated_by_last_action?
new_resource.updated_by_last_action(systemd_r.updated_by_last_action?)
reload_r = execute "reload-systemd-#{new_resource.service_name}" do
command 'systemctl daemon-reload'
action :nothing
only_if 'which systemctl'
end
reload_r.run_action(:run)
end
end
# flatten in an array here, in case the service_actions are a symbol vs. array
[new_resource.service_actions].flatten.each do |act|
passthrough_action(act)
end
end
# Passthrough actions to service[service_name]
#
def action_enable
passthrough_action(:enable)
end
def action_disable
passthrough_action(:disable)
end
def action_start
passthrough_action(:start)
end
def action_stop
passthrough_action(:stop)
end
def action_restart
passthrough_action(:restart)
end
def action_status
passthrough_action(:status)
end
def passthrough_action(action)
svc_r = lookup_service_resource
svc_r.run_action(action)
new_resource.updated_by_last_action(true) if svc_r.updated_by_last_action?
end
def lookup_service_resource
rc = Chef.run_context.resource_collection
rc.find("service[#{new_resource.service_name}]")
rescue
service new_resource.service_name do
supports status: true, restart: true
action :nothing
end
end
end

View File

@@ -1,48 +0,0 @@
# Chef Provider for creating a user and group for Elasticsearch
class ElasticsearchCookbook::UserProvider < Chef::Provider::LWRPBase
include ElasticsearchCookbook::Helpers
provides :elasticsearch_user
def whyrun_supported?
true # we only use core Chef resources that also support whyrun
end
def action_create
group_r = group new_resource.groupname do
gid new_resource.gid
action :nothing
system true
end
group_r.run_action(:create)
new_resource.updated_by_last_action(true) if group_r.updated_by_last_action?
user_r = user new_resource.username do
comment new_resource.comment
shell new_resource.shell
uid new_resource.uid
gid new_resource.groupname
manage_home false
action :nothing
system true
end
user_r.run_action(:create)
new_resource.updated_by_last_action(true) if user_r.updated_by_last_action?
end
def action_remove
# delete user before deleting the group
user_r = user new_resource.username do
action :nothing
end
user_r.run_action(:remove)
new_resource.updated_by_last_action(true) if user_r.updated_by_last_action?
group_r = group new_resource.groupname do
action :nothing
end
group_r.run_action(:remove)
new_resource.updated_by_last_action(true) if group_r.updated_by_last_action?
end
end

View File

@@ -1,92 +0,0 @@
# Chef Resource for configuring an Elasticsearch node
class ElasticsearchCookbook::ConfigureResource < Chef::Resource::LWRPBase
resource_name :elasticsearch_configure
provides :elasticsearch_configure
actions(:manage, :remove)
default_action :manage
# this is what helps the various resources find each other
attribute(:instance_name, kind_of: String, default: nil)
# if you override one of these, you should probably override them all
attribute(:path_home, kind_of: String, default: '/usr/share/elasticsearch')
attribute(:path_conf, kind_of: String, default: '/etc/elasticsearch')
attribute(:path_data, kind_of: String, default: '/var/lib/elasticsearch')
attribute(:path_logs, kind_of: String, default: '/var/log/elasticsearch')
attribute(:path_pid, kind_of: String, default: '/var/run/elasticsearch')
attribute(:path_plugins, kind_of: String, default: '/usr/share/elasticsearch/plugins')
attribute(:path_bin, kind_of: String, default: '/usr/share/elasticsearch/bin')
attribute(:template_elasticsearch_env, kind_of: String, default: 'elasticsearch.in.sh.erb')
attribute(:cookbook_elasticsearch_env, kind_of: String, default: 'elasticsearch')
attribute(:template_jvm_options, kind_of: String, default: 'jvm_options.erb')
attribute(:cookbook_jvm_options, kind_of: String, default: 'elasticsearch')
attribute(:template_elasticsearch_yml, kind_of: String, default: 'elasticsearch.yml.erb')
attribute(:cookbook_elasticsearch_yml, kind_of: String, default: 'elasticsearch')
attribute(:template_log4j2_properties, kind_of: String, default: 'log4j2.properties.erb')
attribute(:cookbook_log4j2_properties, kind_of: String, default: 'elasticsearch')
attribute(:logging, kind_of: Hash, default: {}.freeze)
attribute(:java_home, kind_of: String, default: nil)
# other settings in /etc/default or /etc/sysconfig
attribute(:memlock_limit, kind_of: String, default: 'unlimited')
attribute(:max_map_count, kind_of: String, default: '262144')
attribute(:nofile_limit, kind_of: String, default: '65536')
attribute(:startup_sleep_seconds, kind_of: [String, Integer], default: 5)
attribute(:restart_on_upgrade, kind_of: [TrueClass, FalseClass], default: false)
# Calculations for this are done in the provider, as we can't do them in the
# resource definition. default is 50% of RAM or 31GB, which ever is smaller.
attribute(:allocated_memory, kind_of: String)
attribute(:jvm_options, kind_of: Array, default:
%w(
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly
-XX:+AlwaysPreTouch
-server
-Xss1m
-Djava.awt.headless=true
-Dfile.encoding=UTF-8
-Djna.nosys=true
-XX:-OmitStackTraceInFastThrow
-Dio.netty.noUnsafe=true
-Dio.netty.noKeySetOptimization=true
-Dio.netty.recycler.maxCapacityPerThread=0
-Dlog4j.shutdownHookEnabled=false
-Dlog4j2.disable.jmx=true
-XX:+HeapDumpOnOutOfMemoryError
).freeze)
# These are the default settings. Most of the time, you want to override
# the `configuration` attribute below. If you do override the defaults, you
# must supply ALL needed defaults, and don't use nil as a value in the hash.
attribute(:default_configuration, kind_of: Hash, default: {
# === NAMING
'cluster.name' => 'elasticsearch',
# can't access node.name, so expect to have to set set this
'node.name' => Chef::Config[:node_name],
# if omitted or nil, these will be populated from attributes above
'path.data' => nil, # see path_data above
'path.logs' => nil, # see path_logs above
# Refer to ES documentation on how to configure these to a
# specific node role/type instead of using the defaults
#
# 'node.data' => ?,
# 'node.master' => ?,
}.freeze)
# These settings are merged with the `default_configuration` attribute,
# allowing you to override and set specific settings. Unless you intend to
# wipe out all default settings, your configuration items should go here.
#
attribute(:configuration, kind_of: Hash, default: {}.freeze)
end

View File

@@ -1,31 +0,0 @@
# Chef Resource for installing or removing Elasticsearch from package or source
class ElasticsearchCookbook::InstallResource < Chef::Resource::LWRPBase
resource_name :elasticsearch_install
provides :elasticsearch_install
actions(:install, :remove)
default_action :install
# this is what helps the various resources find each other
attribute(:instance_name, kind_of: String)
# if this version parameter is not set by the caller, we look at
# `attributes/default.rb` for a default value to use, or we raise
attribute(:version, kind_of: String, default: '7.4.2')
# we allow a string or symbol for this value
attribute(:type, kind_of: String, equal_to: %w(package tarball repository), default: 'repository')
# these use `attributes/default.rb` for default values per platform and install type
attribute(:download_url, kind_of: String)
attribute(:download_checksum, kind_of: String) # sha256
# where to install?
attribute(:dir, kind_of: String, default: '/usr/share')
# attributes used by the package-flavor provider
attribute(:package_options, kind_of: String)
# attributes for the repository-option install
attribute(:enable_repository_actions, kind_of: [TrueClass, FalseClass], default: true)
end

View File

@@ -1,19 +0,0 @@
# Chef Resource for installing an elasticsearch plugin
class ElasticsearchCookbook::PluginResource < Chef::Resource::LWRPBase
resource_name :elasticsearch_plugin
provides :elasticsearch_plugin
include ElasticsearchCookbook::Helpers
actions(:install, :remove)
default_action :install
# if the name or url are different from the resource name
attribute(:plugin_name, kind_of: String, name_attribute: true)
attribute(:url, kind_of: String, default: nil)
attribute(:chef_proxy, kind_of: [TrueClass, FalseClass], default: false)
attribute(:options, kind_of: String, default: '')
# this is what helps the various resources find each other
attribute(:instance_name, kind_of: String, default: nil)
end

View File

@@ -1,28 +0,0 @@
# Chef Resource for declaring a service for Elasticsearch
class ElasticsearchCookbook::ServiceResource < Chef::Resource::LWRPBase
resource_name :elasticsearch_service
provides :elasticsearch_service
actions(
:configure, :remove, # our custom actions
:enable, :disable, :start, :stop, :restart, :status # passthrough to service resource
)
default_action :configure
# this is what helps the various resources find each other
attribute(:instance_name, kind_of: String, default: nil)
attribute(:service_name, kind_of: String, name_attribute: true)
attribute(:args, kind_of: String, default: '-d')
# service actions
attribute(:service_actions, kind_of: [Symbol, String, Array], default: [:enable, :start].freeze)
# allow overridable init script
attribute(:init_source, kind_of: String, default: 'initscript.erb')
attribute(:init_cookbook, kind_of: String, default: 'elasticsearch')
# allow overridable systemd unit
attribute(:systemd_source, kind_of: String, default: 'systemd_unit.erb')
attribute(:systemd_cookbook, kind_of: String, default: 'elasticsearch')
end

View File

@@ -1,19 +0,0 @@
# Chef Resource for declaring a user and group for Elasticsearch
class ElasticsearchCookbook::UserResource < Chef::Resource::LWRPBase
resource_name :elasticsearch_user
provides :elasticsearch_user
actions(:create, :remove)
default_action :create
# this is what helps the various resources find each other
attribute(:instance_name, kind_of: String, default: nil)
attribute(:username, kind_of: String, name_attribute: true) # default to resource name
attribute(:uid, kind_of: Integer)
attribute(:shell, kind_of: String, default: '/bin/bash')
attribute(:comment, kind_of: String, default: 'Elasticsearch User')
attribute(:groupname, kind_of: String, name_attribute: true) # default to resource name
attribute(:gid, kind_of: Integer)
end

View File

@@ -0,0 +1,220 @@
module ElasticsearchCookbook
module VersionHelpers
def default_download_url(version)
platform_family = node['platform_family']
machine = node['kernel']['machine']
case platform_family
when 'debian'
arch = machine.include?('x86_64') ? 'amd64' : 'arm64'
file_type = 'deb'
when 'rhel', 'fedora', 'amazon'
arch = machine.include?('x86_64') ? 'x86_64' : 'aarch64'
file_type = 'rpm'
else
raise "Unsupported platform family: #{platform_family}"
end
base_url = 'https://artifacts.elastic.co/downloads/elasticsearch'
"#{base_url}/elasticsearch-#{version}-#{arch}.#{file_type}"
end
def checksum_platform
platform_family = node['platform_family']
arch = if arm?
platform_family == 'debian' ? 'arm64' : 'aarch64'
else
'x86_64'
end
"#{platform_family == 'debian' ? 'debian' : 'rpm'}_#{arch}"
end
def default_download_checksum(version)
case version
when '6.5.0'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '6.5.1'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '6.5.2'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => '9cb0997dc6d2be16c988c0ee43ccafd19a8b2e757326af84f4cead40f74c614f',
}
when '6.5.3'
{
'rpm_x86_64' => '2f3eb7682e06211061bea90a0314a515f0c4ef683f45c8e57bfb1dfb14679c3a',
'debian_x86_64' => '38b30461201fe8d126d124f04d961e7c037bea7a6fb9ca485c08e681d8d30456',
}
when '6.5.4'
{
'rpm_x86_64' => 'aa4006f754bd1a0bfaa338ba40d93a1762917c1862951577c62b1f073026b5ba',
'debian_x86_64' => 'c0a062ffb45f989cd3091c66f62605178c41c3735991d95506a6986a90924833',
}
when '6.6.0'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '6.6.1'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '6.6.2'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '6.7.0'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '6.7.1'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '6.7.2'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '6.8.2'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '6.8.3'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '6.8.4'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '6.8.5'
{
'rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '6.8.6'
{
'rpm_x86_64' => '4880396d1a78046efe4a6ec45c1cc2f1f9f0d328466aa32355e95f9834d9d0af',
'debian_x86_64' => '82dce29bb3c9108f44e936c3fc6200ce7264bb1a27c1a1cc6dde39b6eac03487',
}
when '7.0.1'
{
'x86_64rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_arm64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '7.1.0'
{
'debian_arm64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'x86_64rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
}
when '7.1.1'
{
'x86_64rpm_x86_64' => 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
'debian_arm64' => '2ef15cb7e37d32b93c51ad537959831bd72cac2627f255d22cc574cec5de6aef',
}
when '7.2.0'
{
'debian_x86_64' => '1ff7b88c4bc38438a67719df499b17d4f7082a77eda89f39016f83414554ea95',
'rpm_x86_64' => 'a854decb443631a0031a9492c1d5acbed00222381cb63cba68ae6d5deee3994c',
}
when '7.2.1'
{
'debian_x86_64' => '41f507b83fc49a3da5109afd18cc626ec5458acf567f00a80ac3f1c34b6d4b7f',
'rpm_x86_64' => '96fdac0a8e6c74182d920b39e3f4830b722731a646126222c189e12a95302e6e',
}
when '7.3.0'
{
'debian_x86_64' => '72ae24cf0f5d97a307f35d116a41e1165e80f58f08b0ca4e6de3ec5228f06f9c',
'rpm_x86_64' => 'f49dc809cf48369b70546f13dfb28b43e1a07387b681ca786c794762d52847ca',
}
when '7.3.1'
{
'debian_x86_64' => '570af7456603fd103408ed61ccec4473302976d46e1ff845b74a881122977e02',
'rpm_x86_64' => '240f93d16da4c20d2cc377b7c6a61dbf4fb9634d74829ccb5f7cd42c023bc967',
}
when '7.3.2'
{
'debian_x86_64' => '690e98653b3dc50ec5f8e65c480ec41c8c4db0d2c63b5ed3f25fef53d6aaaa55',
'rpm_x86_64' => 'bdada0a4c7b5574c41726154212b6b25373e2b4d7d2a64e24238b206ad422ecd',
}
when '7.4.0'
{
'debian_x86_64' => '3edf17d9d63a08a0f7eb7d9727a1737e1c770277f64fe44342115e62f752cc51',
'rpm_x86_64' => '1bfae41734c77af3bc66084ac0cc04add1190f9311b045d3c184ea7b3e688334',
}
when '7.4.1'
{
'debian_x86_64' => '55a92288e81856e9bb6c36c0f7149b24cf36432527ca809fc48e25775b0cf584',
'rpm_x86_64' => '8ec30fbd95235cb15d0f27cd40f75a43f640f5832e2ee2d44fe8d2983cd5724f',
}
when '7.4.2'
{
'debian_x86_64' => '514a8e21e173481edb9130ebbf33f15209b467df5c2222632d63c4527c16abc6',
'rpm_x86_64' => 'af616eed2cd30411f400dee0c993eb8fccd55e510548697d7cc0eb178ac4adec',
}
when '7.5.0'
{
'debian_x86_64' => '5b167d15461049f6aa58a96d805c9bcd297ad19467392eea125ce91c5eaaf908',
'rpm_x86_64' => 'a8e802c74c3163272fb7119a9d23c1e8f7bbe76e6502a3fcc30709705bc57f4a',
}
when '7.5.1'
{
'debian_x86_64' => 'e566a88e15d8f85cf793c8f971b51eeae6465a0aa73f968ae4b1ee6aa71e4c20',
'rpm_x86_64' => 'e6202bba2bd8644d23dcbef9ad7780c847dfe4ee699d3dc1804f6f62eed59c2d',
}
when '7.16.3'
{
'debian_x86_64' => '03992d97930b734155981076b3cd250c22742f3876f5f135f374940d1cb3ae2e',
'debian_arm64' => 'c383e5b45eb070e1b6d53b9dc56218634794e2e0b27ea42a7d4a12650eec2b70',
'rpm_aarch64' => 'f833e86db87240bcdc822ea40fc6103f019c35bafcfd7ac6063ef01d5b588e1c',
'rpm_x86_64' => '9edf142b9a25b9000a9bf8638bc0590916f367b66e4abb3ce80d8f00f9de0c9c',
}
when '7.17.8'
{
'debian_x86_64' => 'd4875477129214519f6150aaf35374103f075886913307d6ed7c138d04ae6fa1',
'debian_arm64' => '7dd69704b8d6d71aa58bb05f86d63fb34c00f2fcabdff244e9dab37226ca48af',
'rpm_aarch64' => 'bb151d40c7979e5c5c6b9b1a227d494bb463642af938a6b21ae46a4eae767c74',
'rpm_x86_64' => 'd1d1cf15143029c658224d39ebf174f8da802bb26800cd88f974ad2a0ee16484',
}
when '7.17.9'
{
'debian_x86_64' => '7832e13c0b67239370058b729d321af1a12f0b329c0a3828c57d2fd4a9cb6555',
'debian_arm64' => 'ec7064982bd3601280478b5d1ea01b8b8d95cbaaffad441e7bef194c53e8cccd',
'rpm_aarch64' => '16a6e97440b0a4542d9d69168287fe143d40db138e9a3fd3e6348e60abe77175',
'rpm_x86_64' => '751beebbe28ebefcd451796c1075208421b109bdae752383122142fd00a04559',
}
when '8.6.1'
{
'debian_x86_64' => 'a4ea8a7409a9c32752688f03f1df628624fa48a1c38bc5d0eee21883d5b34083',
'debian_arm64' => '84fbd0d36e98aff028eac5027e4bcc2cc8b84bf63dc175fc72e4ea3649c5c8b7',
'rpm_aarch64' => '39e80fe8cc3b864601848e008cf8a0b45b76076408abac093bedc14d0c1328bf',
'rpm_x86_64' => '939daa9480693df658d75bd38c75c2cbf5876e31ff74a543ef8a9d45a81ac728',
}
when '8.6.2'
{
'debian_x86_64' => '8bd0b859e7fa7df8d9e632120c327530f088c5b564cd3b5538eda1b92a181676',
'debian_arm64' => '6e0088c9ac8c2d51f3d60360607f344b6511feaf5d0f3931a4c9d81448757ba9',
'rpm_aarch64' => 'f20a70195e807e1b2981ec37960df8fffef5412f89936b0834d9e8d64d2c8cc1',
'rpm_x86_64' => '5fc28cdfd3aeeeb746778ca873ce47d9836eb6d26746a562b98650c655bb8a3b',
}
else
raise "Unsupported version #{version}"
end
end
end
end