О языке рецептов DSL
Язык рецептов DSL — это Ruby DSL, который в основном используется для объявления ресурсов в рамках рецепта. Язык рецептов DSL также помогает обеспечить, чтобы рецепты взаимодействовали с узлами (и свойствами узлов) желаемым образом. Большинство методов в языке рецептов DSL используются для поиска конкретного параметра и затем сообщают Chef Infra Client о действии(ях), которые нужно выполнить, в зависимости от того, присутствует ли этот параметр на узле.
Поскольку язык рецептов DSL — это Ruby DSL, всё, что можно сделать с помощью Ruby, можно также сделать в рецепте или пользовательском ресурсе, включая инструкции if и case, используя метод Ruby include?, включая рецепты в рецепты и проверяя зависимости. Смотрите Руководство по Ruby для получения дополнительной информации о встроенных возможностях Ruby.
Включение рецептов
Рецепт может включать один (или несколько) рецептов из кулинарных книг, используя метод include_recipe. Когда рецепт включается, ресурсы, найденные в этом рецепте, будут вставлены (в том же самом порядке) в той точке, где находится ключевое слово include_recipe.
Синтаксис включения рецепта выглядит так:
include_recipe 'recipe'
Например:
include_recipe 'apache2::mod_ssl'
В рецепте можно включить несколько рецептов. Например:
include_recipe 'cookbook::setup'
include_recipe 'cookbook::install'
include_recipe 'cookbook::configure'
Если конкретный рецепт включён более одного раза с помощью метода include_recipe или где-либо ещё в списке запуска напрямую, будет обработана только первая запись, а последующие включения будут проигнорированы.
Перезагрузка атрибутов
Атрибуты иногда зависят от действий, выполняемых внутри рецептов, поэтому может потребоваться перезагрузить заданный атрибут внутри рецепта. Например:
ruby_block 'some_code' do
block do
node.from_file(run_context.resolve_attribute('COOKBOOK_NAME', 'ATTR_FILE'))
end
action :nothing
end
Методы языка рецептов DSL
Язык рецептов DSL предоставляет поддержку использования атрибутов, пакетов данных (и зашифрованных данных), результатов поиска в рецепте, а также четыре вспомогательных метода, которые могут быть использованы для проверки платформы узла из рецепта, чтобы убедиться, что конкретные действия выполняются для конкретных платформ. Вспомогательные методы:
platform?platform_family?value_for_platformvalue_for_platform_family
attribute?
Используйте метод attribute?, чтобы убедиться, что определённые действия выполняются только при наличии определённого атрибута узла. Метод attribute? вернёт true, если один из перечисленных атрибутов узла соответствует атрибуту узла, обнаруженному Ohai во время каждого запуска Chef Infra Client.
Синтаксис метода attribute? следующий:
attribute?('name_of_attribute')
Например:
if node.attribute?('ipaddress')
# the node has an ipaddress
end
имя_кулинарной_книги
Используйте метод cookbook_name для возвращения имени кулинарной книги.
Синтаксис метода cookbook_name следующий:
cookbook_name
Этот метод часто используется как часть записи в журнал. Например:
Chef::Log.info('I am a message from the #{recipe_name} recipe in the #{cookbook_name} cookbook.')
пакет_данных
Пакеты данных хранят глобальные переменные в формате JSON. Пакеты данных индексируются для поиска и могут быть загружены кулинарной книгой или использованы во время поиска.
Используйте метод data_bag для получения списка содержимого пакета данных.
Синтаксис метода data_bag следующий:
data_bag(bag_name)
Примеры
Следующий пример показывает, как метод data_bag можно использовать в рецепте.
Получить пакет данных и затем проитерироваться по каждому элементу пакета данных
data_bag('users') #=> ['sandy', 'jill']
Проитерируйтесь по содержимому пакета данных, чтобы получить соответствующий data_bag_item:
data_bag('users').each do |user|
data_bag_item('users', user)
end
id для каждого элемента пакета данных будет возвращено в виде строки.
элемент_пакета_данных
Пакеты данных хранят глобальные переменные в формате JSON. Пакеты данных индексируются для поиска и могут быть загружены кулинарной книгой или использованы во время поиска.
Метод data_bag_item можно использовать в рецепте для получения содержимого элемента пакета данных.
Синтаксис метода data_bag_item следующий:
data_bag_item(bag_name, item, secret)
где secret — секрет, используемый для загрузки зашифрованного пакета данных. Если secret не указан, Chef Infra Client ищет секрет по пути, указанному настройкой encrypted_data_bag_secret в файле client.rb.
Примеры
Следующие примеры показывают, как метод data_bag_item можно использовать в рецепте.
Получить пакет данных и затем проитерироваться по каждому элементу пакета данных
data_bag('users') #=> ['sandy', 'jill']
Проитерируйтесь по содержимому пакета данных, чтобы получить соответствующий data_bag_item:
data_bag('users').each do |user|
data_bag_item('users', user)
end
id для каждого элемента пакета данных будет возвращено в виде строки.
Использование содержимого пакета данных в рецепте
Следующий пример показывает, как использовать методы data_bag и data_bag_item в рецепте, также используя пакет данных с именем sea-power:
package 'sea-power' do
action :install
end
directory node['sea-power']['base_path'] do
# attributes for owner, group, mode
end
gale_warnings = data_bag('sea-power').map do |viking_north|
data_bag_item('sea-power', viking_north)['source']
end
template '/etc/seattle/power.list' do
source 'seattle-power.erb'
# attributes for owner, group, mode
variables(
:base_path => node['sea-power']['base_path'],
# more variables
:repo_location => gale_warnings
)
end
Для более полной версии предыдущего примера см. рецепт по умолчанию в кулинарной книге сообщества https://github.com/hw-cookbooks/apt-mirror.
объявить_ресурс
Используйте метод declare_resource для создания ресурса и добавления его в коллекцию ресурсов.
Синтаксис метода declare_resource следующий:
declare_resource(:resource_type, 'resource_name', resource_attrs_block)
где:
-
:resource_type— тип ресурса, такой как:file(для ресурса file),:template(для ресурса template) и так далее. Любой ресурс, доступный в Chef, может быть объявлен. -
resource_name— свойство, которое является стандартным именем ресурса, как правило, строка, которая отображается в блокеresource 'name' doресурса (но не всегда); см. раздел Синтаксис для объявляемого ресурса для проверки свойства стандартного имени. -
resource_attrs_block— блок, в котором объявляются свойства созданного ресурса.
Например:
declare_resource(:file, '/x/y.txy', caller[0]) do
action :delete
end
эквивалентно:
file '/x/y.txt' do
action :delete
end
удалить_ресурс
Используйте метод delete_resource, чтобы найти ресурс в коллекции ресурсов и удалить его.
Синтаксис метода delete_resource следующий:
delete_resource(:resource_type, 'resource_name')
где:
-
:resource_type— тип ресурса, такой как:file(для ресурса file),:template(для ресурса template) и так далее. Любой ресурс, доступный в Chef, может быть объявлен. -
resource_name— свойство, которое является стандартным именем ресурса, как правило, строка, которая отображается в блокеresource 'name' doресурса (но не всегда); см. раздел Синтаксис для объявляемого ресурса для проверки свойства стандартного имени.
Например:
delete_resource(:template, '/x/y.erb')
удалить_ресурс!
Используйте метод delete_resource!, чтобы найти ресурс в коллекции ресурсов и удалить его. Если ресурс не найден, возвращается исключение.
Синтаксис метода delete_resource! следующий:
delete_resource!(:resource_type, 'resource_name')
где:
-
:resource_type— тип ресурса, такой как:file(для ресурса file),:template(для ресурса template) и так далее. Любой ресурс, доступный в Chef, может быть объявлен. -
resource_name— свойство, которое является стандартным именем ресурса, как правило, строка, которая отображается в блокеresource 'name' doресурса (но не всегда); см. раздел Синтаксис для объявляемого ресурса для проверки свойства стандартного имени.
Например:
delete_resource!(:file, '/x/file.txt')
изменить_ресурс
Используйте метод edit_resource для:
- Поиск ресурса в коллекции ресурсов и его изменения.
- Определение блока ресурса. Если блок ресурса с тем же именем существует в коллекции ресурсов, он будет обновлён содержимым блока ресурса, определённого методом
edit_resource. Если блок ресурса не существует в коллекции ресурсов, он будет создан.
Синтаксис метода edit_resource следующий:
edit_resource(:resource_type, 'resource_name', resource_attrs_block)
где:
-
:resource_type— тип ресурса, такой как:file(для ресурса file),:template(для ресурса template) и так далее. Любой ресурс, доступный в Chef, может быть объявлен. -
resource_name— свойство, которое является стандартным именем ресурса, как правило, строка, которая отображается в блокеresource 'name' doресурса (но не всегда); см. раздел Синтаксис для объявляемого ресурса для проверки свойства стандартного имени. -
resource_attrs_block— блок, в котором объявляются свойства созданного ресурса.
Например:
edit_resource(:template, '/x/y.txy') do
cookbook 'cookbook_name'
end
и блок ресурса:
edit_resource(:template, '/etc/aliases') do
source 'aliases.erb'
cookbook 'aliases'
variables({:aliases => {} })
notifies :run, 'execute[newaliases]'
end
изменить_ресурс!
Используйте метод edit_resource! для:
- Поиск ресурса в коллекции ресурсов и его изменения.
- Определение блока ресурса. Если ресурс с тем же именем существует в коллекции ресурсов, его свойства будут обновлены содержимым блока ресурса, определённого методом
edit_resource.
В обоих случаях, если ресурс не найден, возвращается исключение.
Синтаксис метода edit_resource! следующий:
edit_resource!(:resource_type, 'resource_name')
где:
-
:resource_type— это тип ресурса, например,:file(для ресурса file),:template(для ресурса template) и так далее. Любой ресурс, доступный в Chef, может быть объявлен. -
resource_name— свойство, которое является значением по умолчанию для имени ресурса, обычно строка, которая появляется в блокеresource 'name' doресурса (но не всегда); см. раздел Синтаксис для объявления ресурса, чтобы проверить свойство имени по умолчанию. -
resource_attrs_block— блок, в котором объявляются свойства экземпляризованного ресурса.
Например:
edit_resource!(:file, '/x/y.rst')
find_resource
Используйте метод find_resource для:
- Поиска ресурса в коллекции ресурсов.
- Определения блока ресурса. Если блок ресурса с тем же именем существует в коллекции ресурсов, он будет возвращён. Если блок ресурса не существует в коллекции ресурсов, он будет создан.
Синтаксис метода find_resource:
find_resource(:resource_type, 'resource_name')
где:
-
:resource_type— это тип ресурса, например,:file(для ресурса file),:template(для ресурса template) и так далее. Любой ресурс, доступный в Chef, может быть объявлен. -
resource_name— свойство, являющееся значением по умолчанию для имени ресурса, обычно строка, которая появляется в блокеresource 'name' doресурса (но не всегда); см. раздел Синтаксис для объявления ресурса, чтобы проверить свойство имени по умолчанию.
Например:
find_resource(:template, '/x/y.txy')
и блок ресурса:
find_resource(:template, '/etc/seapower') do
source 'seapower.erb'
cookbook 'seapower'
variables({:seapower => {} })
notifies :run, 'execute[newseapower]'
end
find_resource!
Используйте метод find_resource! для поиска ресурса в коллекции ресурсов. Если ресурс не найден, возвращается исключение.
Синтаксис метода find_resource!:
find_resource!(:resource_type, 'resource_name')
где:
-
:resource_type— это тип ресурса, например,:file(для ресурса file),:template(для ресурса template) и так далее. Любой ресурс, доступный в Chef, может быть объявлен. -
resource_name— свойство, являющееся значением по умолчанию для имени ресурса, обычно строка, которая появляется в блокеresource 'name' doресурса (но не всегда); см. раздел Синтаксис для объявления ресурса, чтобы проверить свойство имени по умолчанию.
Например:
find_resource!(:template, '/x/y.erb')
platform?
Используйте метод platform? для обеспечения запуска определённых действий для конкретной платформы. Метод platform? вернёт true, если один из перечисленных параметров соответствует атрибуту node['platform'], обнаруженному Ohai во время каждого выполнения Chef Infra Client.
Синтаксис метода platform?:
platform?('parameter', 'parameter')
где:
-
parameter— список значений, разделённых запятыми, каждый из которых указывает на платформу, например, Red Hat, CentOS или Fedora -
Метод
platform?обычно используется со следующим:if,elsifилиcaseоператором, содержащим код Ruby, специфичный для платформы, если она обнаружена
Параметры
Следующие параметры могут быть использованы с этим методом:
| Параметр | Платформы |
|---|---|
aix |
AIX. Все варианты платформы AIX возвращают aix. |
amazon |
Amazon Linux |
arch |
Arch Linux |
debian |
Debian |
fedora |
Fedora |
freebsd |
FreeBSD. Все варианты платформы FreeBSD возвращают freebsd. |
gentoo |
Gentoo |
mac_os_x |
macOS |
netbsd |
NetBSD. Все варианты платформы NetBSD возвращают netbsd. |
openbsd |
OpenBSD. Все варианты платформы OpenBSD возвращают openbsd. |
opensuseleap |
openSUSE leap |
slackware |
Slackware |
solaris |
Solaris. Для платформ, относящихся к Solaris, метод platform_family не поддерживает семейство платформ Solaris и вернёт значение по умолчанию platform_family = platform. Например, если платформа OmniOS, значение platform_family равно omnios, если платформа SmartOS, значение platform_family равно smartos, и так далее. Все варианты платформы Solaris возвращают solaris. |
suse |
SUSE Enterprise Linux Server. |
ubuntu |
Ubuntu Linux. |
windows |
Microsoft Windows. Все варианты платформы Microsoft Windows возвращают windows. |
Примечание
node['platform'].Например:
platform?('debian')
или:
platform?('redhat', 'debian')
Примеры
Следующий пример демонстрирует, как метод platform? может быть использован в рецепте.
Использование оператора if с методом platform рецепта DSL
Следующий пример демонстрирует, как оператор if может быть использован с методом platform? в Recipe DSL для запуска кода, специфичного для Microsoft Windows. Код определён с помощью ресурса ruby_block:
# the following code sample comes from the ``client`` recipe
# in the following cookbook: https://github.com/chef-cookbooks/mysql
if platform?('windows')
ruby_block 'copy libmysql.dll into ruby path' do
block do
require 'fileutils'
FileUtils.cp "#{node['mysql']['client']['lib_dir']}\\libmysql.dll",
node['mysql']['client']['ruby_dir']
end
not_if { ::File.exist?("#{node['mysql']['client']['ruby_dir']}\\libmysql.dll") }
end
end
platform_family?
Используйте метод platform_family? для обеспечения запуска определённых действий для конкретной семейства платформ. Метод platform_family? вернёт true, если один из перечисленных параметров соответствует атрибуту node['platform_family'], обнаруженному Ohai во время каждого выполнения Chef Infra Client.
Синтаксис метода platform_family?:
platform_family?('parameter', 'parameter')
где:
-
'parameter'— список значений, разделённых запятыми, каждый из которых указывает на семейство платформ, например, Debian или Red Hat Enterprise Linux -
Метод
platform_family?обычно используется со следующим:if,elsifилиcaseоператором, содержащим код Ruby, специфичный для семейства платформ, если оно обнаружено
Например:
if platform_family?('rhel')
# do RHEL things
end
или:
if platform_family?('debian', 'rhel')
# do things on debian and rhel families
end
Например:
platform_family?('gentoo')
или:
platform_family?('slackware', 'suse', 'arch')
Примечание
platform_family? будет по умолчанию равно platform?, когда platform_family? не определён явно.Примеры
Следующие примеры демонстрируют, как метод platform_family? может быть использован в рецепте.
Использование определённой бинарной программы для определённой платформы
Следующий пример демонстрирует использование метода platform_family? в Recipe DSL для создания переменной, которая может быть использована с другими ресурсами в том же рецепте. В этом примере platform_family? используется для обеспечения использования определённой бинарной программы для определённой платформы перед использованием ресурса remote_file для загрузки файла из удалённого расположения, а затем использованием ресурса execute для установки этого файла путём выполнения команды.
if platform_family?('rhel')
pip_binary = '/usr/bin/pip'
else
pip_binary = '/usr/local/bin/pip'
end
remote_file "#{Chef::Config[:file_cache_path]}/distribute_setup.py" do
source 'http://python-distribute.org/distribute_setup.py'
mode '0755'
not_if { ::File.exist?(pip_binary) }
end
execute 'install-pip' do
cwd Chef::Config[:file_cache_path]
command <<-EOF
# command for installing Python goes here
EOF
not_if { ::File.exist?(pip_binary) }
end
где команда для установки Python может выглядеть примерно так:
#{node['python']['binary']} distribute_setup.py
#{::File.dirname(pip_binary)}/easy_install pip
reboot_pending?
Используйте метод reboot_pending? для проверки, требуется ли перезагрузка узла или ожидается перезагрузка. reboot_pending? возвращает true, когда узлу требуется перезагрузка.
Синтаксис метода reboot_pending?:
reboot_pending?
recipe_name
Используйте метод recipe_name для возвращения имени рецепта.
Синтаксис метода recipe_name:
recipe_name
Этот метод часто используется в качестве части записи в журнал. Например:
Chef::Log.info('I am a message from the #{recipe_name} recipe in the #{cookbook_name} cookbook.')
resources
Используйте метод resources для поиска ресурса в коллекции ресурсов. Метод resources возвращает значение для ресурса, который он находит в коллекции ресурсов. Предпочтительный синтаксис метода resources:
resources('resource_type[resource_name]')
но также можно использовать следующий синтаксис:
resources(:resource_type => 'resource_name')
где в обоих подходах resource_type — имя ресурса, а resource_name — имя ресурса, который может быть настроен Chef Infra Client.
Метод resources может быть использован для изменения ресурса позднее в рецепте. Например:
file '/etc/hosts' do
content '127.0.0.1 localhost.localdomain localhost'
end
и затем позже в том же рецепте или где-либо ещё:
f = resources('file[/etc/hosts]')
f.mode '0644'
где file — тип ресурса, /etc/hosts — имя, а f.mode используется для установки свойства mode для ресурса file.
search
Индексы поиска позволяют выполнять запросы к любому типу данных, индексируемому сервером Chef Infra Server, включая пакеты данных (и элементы пакетов данных), среды, узлы и роли. Определенный синтаксис запроса поддерживает шаблоны поиска, такие как точное соответствие, подстановочные знаки, диапазон и приблизительное соответствие. Поиск — это полнотекстовый запрос, который можно выполнить из нескольких мест, включая рецепт, с помощью подкоманды search в knife, метода search в DSL-синтаксисе рецептов, поля поиска в консоли управления Chef и с помощью конечных точек /search или /search/INDEX API сервера Chef Infra Server. Двигатель поиска основан на Elasticsearch и работает на сервере Chef Infra Server.
Используйте метод search для выполнения запроса поиска на сервере Chef Infra Server внутри рецепта.
Синтаксис метода search выглядит следующим образом:
search(:index, 'query')
где:
-
:index— это имя индекса на сервере Chef Infra Server, по которому будет выполняться запрос поиска::client,:data_bag_name,:environment,:nodeи:role -
'query'— это допустимый запрос поиска по объекту на сервере Chef Infra Server (подробности о построении запроса см. ниже).
Например, использование результатов запроса поиска в переменной:
webservers = search(:node, 'role:webserver')
а затем использование результатов этого запроса для заполнения шаблона:
template '/tmp/list_of_webservers' do
source 'list_of_webservers.erb'
variables(:webservers => webservers)
end
:filter_result
Используйте :filter_result в качестве части запроса поиска для фильтрации выходных данных поиска на основе шаблона, заданного в виде хэша. Будут возвращены только атрибуты из хэша.
Синтаксис метода search, использующего :filter_result, выглядит следующим образом:
search(:index, 'query',
filter_result: { 'foo' => [ 'abc' ],
'bar' => [ '123' ],
'baz' => %w(sea power),
}
).each do |result|
puts result['foo']
puts result['bar']
puts result['baz']
end
где:
-
:index— это имя индекса на сервере Chef Infra Server, по которому будет выполняться запрос поиска::client,:data_bag_name,:environment,:nodeи:role -
'query'— это допустимый запрос поиска по объекту на сервере Chef -
:filter_resultопределяет хэш значений, которые должны быть возвращены
Например:
search(:node, 'role:web',
filter_result: { 'name' => [ 'name' ],
'ip' => [ 'ipaddress' ],
'kernel_version' => %w(kernel version),
}
).each do |result|
puts result['name']
puts result['ip']
puts result['kernel_version']
end
Синтаксис запроса
Запрос поиска состоит из двух частей: ключа и шаблона поиска. Запрос поиска имеет следующий синтаксис:
key:search_pattern
где key — это имя поля, которое находится в JSON-описании индексируемого объекта на сервере Chef Infra Server (роль, узел, клиент Chef, среда или пакет данных), а search_pattern определяет, что будет искаться, используя один из следующих шаблонов поиска: точное соответствие, подстановочные знаки, диапазон или приблизительное соответствие. И key, и search_pattern чувствительны к регистру; key имеет ограниченную поддержку подстановочных знаков с несколькими символами, используя звездочку («*») (и только если она не является первым символом).
Ключи
Пара имя/описание поля доступна в JSON-объекте. Используйте имя поля при поиске этой информации в JSON-объекте. Можно искать любое поле, которое существует в любом JSON-описании любой роли, узла, клиента Chef, среды или пакета данных.
Вложенные поля
Вложенное поле появляется глубже в структуре JSON-данных. Например, информация о сетевом интерфейсе может быть на нескольких уровнях вложенности: node['network']['interfaces']['en1']. Когда вложенные поля присутствуют в структуре JSON, Chef Infra Client извлекает эти вложенные поля на верхнем уровне, сворачивая их в составные поля, которые поддерживают шаблоны поиска с подстановочными знаками.
Сочетание подстановочных знаков с шаблонами соответствия диапазонам и запросами с подстановочными знаками позволяет выполнять очень мощные поиски, например, используя часть поставщика MAC-адреса, чтобы найти все узлы, которые имеют сетевую карту, изготовленную указанным поставщиком.
Рассмотрим следующий фрагмент JSON-данных:
{"network":
[
//snipped...
"interfaces",
{"en1": {
"number": "1",
"flags": [
"UP",
"BROADCAST",
"SMART",
"RUNNING",
"SIMPLEX",
"MULTICAST"
],
"addresses": {
"fe80::fa1e:dfff:fed8:63a2": {
"scope": "Link",
"prefixlen": "64",
"family": "inet6"
},
"f8:1e:df:d8:63:a2": {
"family": "lladdr"
},
"192.0.2.0": {
"netmask": "255.255.255.0",
"broadcast": "192.168.0.255",
"family": "inet"
}
},
"mtu": "1500",
"media": {
"supported": {
"autoselect": {
"options": [
]
}
},
"selected": {
"autoselect": {
"options": [
]
}
}
},
"type": "en",
"status": "active",
"encapsulation": "Ethernet"
},
//snipped...
Перед индексированием этих данных на сервере Chef Infra Server вложенные поля извлекаются на верхний уровень, примерно так:
"broadcast" => "192.168.0.255",
"flags" => ["UP", "BROADCAST", "SMART", "RUNNING", "SIMPLEX", "MULTICAST"]
"mtu" => "1500"
что позволяет выполнять такие поиски, чтобы найти данные, присутствующие в этом узле:
node "broadcast:192.168.0.*"
или:
node "mtu:1500"
или:
node "flags:UP"
Эти данные также сжимаются в различные составные поля, которые следуют той же структуре, что и JSON-иерархия, и используют символы нижнего подчеркивания (_) для разделения уровней данных, примерно так:
# ...snip...
"network_interfaces_en1_addresses_192.0.2.0_broadcast" => "192.168.0.255",
"network_interfaces_en1_addresses_fe80::fa1e:tldr_family" => "inet6",
"network_interfaces_en1_addresses" => ["fe80::fa1e:tldr","f8:1e:df:tldr","192.0.2.0"]
# ...snip...
что позволяет выполнять такие поиски, чтобы найти данные, присутствующие в этом узле:
node "network_interfaces_en1_addresses:192.0.2.0"
Эта сжатая структура данных также поддерживает использование составных полей с подстановочными знаками, которые позволяют искать, опуская уровни в структуре JSON-данных, не важные для запроса поиска. В следующем примере звездочка (*) используется для показа, где может находиться подстановочный знак при поиске вложенного поля:
"network_interfaces_*_flags" => ["UP", "BROADCAST", "SMART", "RUNNING", "SIMPLEX", "MULTICAST"]
"network_interfaces_*_addresses" => ["fe80::fa1e:dfff:fed8:63a2", "192.0.2.0", "f8:1e:df:d8:63:a2"]
"network_interfaces_en0_media_*" => ["autoselect", "none", "1000baseT", "10baseT/UTP", "100baseTX"]
"network_interfaces_en1_*" => ["1", "UP", "BROADCAST", "SMART", "RUNNING", "SIMPLEX", "MULTICAST",
"fe80::fa1e:dfff:fed8:63a2", "f8:1e:df:d8:63:a2", "192.0.2.0",
"1500", "supported", "selected", "en", "active", "Ethernet"]
Для каждого из приведенных выше примеров с подстановочными знаками возможные значения показаны в скобках. При выполнении запроса поиска синтаксис запроса для подстановочных знаков заключается в простом пропуске имени узла (при сохранении символов нижнего подчеркивания), примерно так:
network_interfaces__flags
Этот запрос будет искать в узле flags внутри JSON-структуры для каждого из UP, BROADCAST, SMART, RUNNING, SIMPLEX и MULTICAST.
Шаблоны
Шаблон поиска — это способ уточнения результатов поиска, возвращая все, что соответствует какому-то типу неполного запроса поиска. Существует четыре типа шаблонов поиска, которые можно использовать при поиске в индексах поиска на сервере Chef Infra Server: точное соответствие, подстановочные знаки, диапазон и приблизительное соответствие.
Точное соответствие
Шаблон поиска точного соответствия используется для поиска ключа с именем, которое точно соответствует запросу поиска. Если имя ключа содержит пробелы, в шаблоне поиска должны использоваться кавычки, чтобы гарантировать, что запрос поиска найдет ключ. Весь запрос также должен быть заключен в кавычки, чтобы предотвратить его интерпретацию Ruby или командной оболочкой. Лучший способ гарантировать, что кавычки используются последовательно, — это заключить весь запрос в одинарные кавычки (' ') и шаблон поиска в двойные кавычки (" ").
Поиск с подстановочными знаками
Шаблон поиска с подстановочными знаками используется для запроса совпадений подстрок, которые заменяют ноль (или более) символов в шаблоне поиска на все, что может соответствовать замененному символу. Существует два типа поиска с подстановочными знаками:
- Вопросительный знак (
?) может быть использован для замены ровно одного символа (при условии, что этот символ не является первым символом в шаблоне поиска) - Звездочка (
*) может быть использована для замены любого количества символов (включая ноль)
Поиск по диапазону
Шаблон поиска по диапазону используется для запроса значений, которые находятся в диапазоне, определенном верхними и нижними границами. Шаблон поиска по диапазону может включать или исключать границы. Используйте квадратные скобки («[ ]») для обозначения включительных границ и фигурные скобки («{ }») для обозначения исключительных границ со следующим синтаксисом:
boundary TO boundary
где TO обязательно (и должно быть написано с большой буквы).
Поиск с приблизительным соответствием
Шаблон поиска с приблизительным соответствием используется для поиска на основе близости двух строк символов. (Необязательное) целое число может быть использовано как часть запроса поиска для более точного определения близости. Шаблон поиска с приблизительным соответствием имеет следующий синтаксис:
"search_query"~edit_distance
где search_query — это строка, которая будет использоваться во время поиска, а edit_distance — это близость. Тильда («~») используется для разделения расстояния редактирования от запроса поиска.
Операторы
Оператор может использоваться для обеспечения включения определенных терминов в результаты, исключения их из результатов или исключения их даже при соответствии другим аспектам запроса. Поиски могут использовать следующие операторы:
| Оператор | Описание |
|---|---|
AND |
Используйте для поиска совпадения, когда оба термина существуют. |
OR |
Используйте для поиска совпадения, если существует любой из терминов. |
NOT |
Используйте для исключения термина после NOT из результатов поиска. |
Специальные символы
Специальный символ может использоваться для уточнения запроса поиска и повышения точности результатов поиска. В синтаксисе запроса можно включать следующие символы, но каждое вхождение специального символа должно быть экранировано обратной косой чертой (\), а также (/) должно быть экранировано от Elasticsearch:
+ - && | | ! ( ) { } [ ] ^ " ~ * ? : \ /
Например:
\(1\+1\)\:2
Примеры
Следующие примеры показывают, как метод search можно использовать в рецепте.
Использование метода рецепта поиска для поиска пользователей
Следующий пример показывает, как использовать метод search в DSL-синтаксисе рецепта для поиска пользователей:
# the following code sample comes from the openvpn cookbook: https://github.com/chef-cookbooks/openvpn
search("users", "*:*") do |u|
execute "generate-openvpn-#{u['id']}" do
command "./pkitool #{u['id']}"
cwd '/etc/openvpn/easy-rsa'
environment(
'EASY_RSA' => '/etc/openvpn/easy-rsa',
'KEY_CONFIG' => '/etc/openvpn/easy-rsa/openssl.cnf',
'KEY_DIR' => node['openvpn']['key_dir'],
'CA_EXPIRE' => node['openvpn']['key']['ca_expire'].to_s,
'KEY_EXPIRE' => node['openvpn']['key']['expire'].to_s,
'KEY_SIZE' => node['openvpn']['key']['size'].to_s,
'KEY_COUNTRY' => node['openvpn']['key']['country'],
'KEY_PROVINCE' => node['openvpn']['key']['province'],
'KEY_CITY' => node['openvpn']['key']['city'],
'KEY_ORG' => node['openvpn']['key']['org'],
'KEY_EMAIL' => node['openvpn']['key']['email']
)
not_if { File.exist?("#{node['openvpn']['key_dir']}/#{u['id']}.crt") }
end
%w{ conf ovpn }.each do |ext|
template "#{node['openvpn']['key_dir']}/#{u['id']}.#{ext}" do
source 'client.conf.erb'
variables :username => u['id']
end
end
execute "create-openvpn-tar-#{u['id']}" do
cwd node['openvpn']['key_dir']
command <<-EOH
tar zcf #{u['id']}.tar.gz \
ca.crt #{u['id']}.crt #{u['id']}.key \
#{u['id']}.conf #{u['id']}.ovpn \
EOH
not_if { File.exist?("#{node['openvpn']['key_dir']}/#{u['id']}.tar.gz") }
end
end
где
- поиск будет использовать оба ресурса execute, если не выполнены условия, заданные командами
not_if - свойство
environmentsв первом ресурсе execute используется для определения значений, которые появляются как переменные в конфигурации OpenVPN - ресурс template указывает клиенту Chef, какой шаблон использовать
shell_out
Метод shell_out может быть использован для выполнения команды на узле и вывода результата в консоль, когда уровень ведения журнала установлен в debug.
Синтаксис метода shell_out выглядит следующим образом:
shell_out(command_args)
где command_args — это команда, которая выполняется на узле.
shell_out!
Метод shell_out! может быть использован для выполнения команды на узле, вывода результата в консоль, когда уровень ведения журнала установлен в debug, и выдачи ошибки, когда метод возвращает false.
Синтаксис метода shell_out! выглядит следующим образом:
shell_out!(command_args)
где command_args — это команда, которая выполняется на узле. Этот метод вернёт true или false.
метка, помеченная?, непомеченная
Метка — это пользовательское описание, которое применяется к узлу. Применённая метка может быть полезна при управлении узлами с помощью knife или при создании рецептов, обеспечивая альтернативные методы группирования похожих типов информации.
Метки могут быть добавлены и удалены. Можно проверить, есть ли у машины определённая метка. Чтобы использовать метки в рецепте, просто добавьте следующее:
tag('mytag')
Чтобы проверить, помечена ли машина, добавьте следующее:
tagged?('mytag')
чтобы вернуть true или false. tagged? также может использовать массив в качестве аргумента.
Чтобы удалить метку:
untag('mytag')
Например:
tag('machine')
if tagged?('machine')
Chef::Log.info("Hey I'm #{node['tags']}")
end
untag('machine')
unless tagged?('machine')
Chef::Log.info('I am not tagged')
end
Вернёт что-то вроде этого:
[Thu, 22 Jul 2010 18:01:45 +0000] INFO: Hey I'm machine
[Thu, 22 Jul 2010 18:01:45 +0000] INFO: I has no tagz
value_for_platform
Используйте метод value_for_platform в рецепте, чтобы выбрать значение на основе атрибутов node['platform'] и node['platform_version']. Эти значения обнаруживаются Ohai во время каждого выполнения Chef Infra Client.
Синтаксис метода value_for_platform следующий:
value_for_platform( ['platform', ...] => { 'version' => 'value' } )
где:
-
'platform', ...— это список платформ, разделённый запятыми, например Red Hat, openSUSE или Fedora -
versionуказывает версию этой платформы - Ограничения версий —
>,<,>=,<=,~>— могут быть использованы сversion; если два ограничения версий совпадают, генерируется исключение; точное совпадение всегда имеет приоритет перед совпадением, полученным из ограничения версии -
valueуказывает значение, которое будет использоваться, если платформа узла соответствует методуvalue_for_platform
Когда каждое значение имеет только одну платформу, используйте следующий синтаксис:
value_for_platform(
'platform' => { 'version' => 'value' },
'platform' => { 'version' => 'value' },
'platform' => 'value'
)
Когда каждое значение имеет более одной платформы, синтаксис изменяется на:
value_for_platform(
['platform', 'platform', ... ] => {
'version' => 'value'
},
)
Операторы
Можно использовать следующие операторы:
| Оператор | Описание |
|---|---|
= |
равно |
> |
больше |
< |
меньше |
>= |
больше или равно; также известно как «оптимистично больше», или «оптимистичный» |
<= |
меньше или равно |
~> |
приблизительно больше; также известно как «пессимистично больше», или «пессимистичный» |
Примеры
Следующий пример установит package_name в httpd для платформы Red Hat и в apache2 для платформы Debian:
package_name = value_for_platform(
['centos', 'redhat', 'suse', 'fedora' ] => {
'default' => 'httpd'
},
['ubuntu', 'debian'] => {
'default' => 'apache2'
}
)
Следующий пример установит package в apache-couchdb для платформ OpenBSD, dev-db/couchdb для платформ Gentoo и couchdb для всех остальных платформ:
package = value_for_platform(
'openbsd' => { 'default' => 'apache-couchdb' },
'gentoo' => { 'default' => 'dev-db/couchdb' },
'default' => 'couchdb'
)
Следующий пример демонстрирует использование ограничений версий для задания значения на основе версии:
value_for_platform(
'os1' => { '< 1.0' => 'less than 1.0',
'~> 2.0' => 'version 2.x',
'>= 3.0' => 'greater than or equal to version 3.0',
'3.0.1' => '3.0.1 will always use this value' }
)
value_for_platform_family
Используйте метод value_for_platform_family в рецепте, чтобы выбрать значение на основе атрибута node['platform_family']. Это значение обнаруживается Ohai во время каждого выполнения Chef Infra Client.
Синтаксис метода value_for_platform_family следующий:
value_for_platform_family( 'platform_family' => 'value', ... )
где:
-
'platform_family' => 'value', ...— это список платформ, разделённый запятыми, например Fedora, openSUSE или Red Hat Enterprise Linux -
valueуказывает значение, которое будет использоваться, если семейство платформ узла соответствует методуvalue_for_platform_family
Когда каждое значение имеет только одну платформу, используйте следующий синтаксис:
value_for_platform_family(
'platform_family' => 'value',
'platform_family' => 'value',
'platform_family' => 'value'
)
Когда каждое значение имеет более одной платформы, синтаксис изменяется на:
value_for_platform_family(
['platform_family', 'platform_family', 'platform_family', 'platform_family' ] => 'value',
['platform_family', 'platform_family'] => 'value',
'default' => 'value'
)
Следующий пример установит package в httpd-devel для платформ Red Hat Enterprise Linux, Fedora и openSUSE и в apache2-dev для платформы Debian:
package = value_for_platform_family(
['rhel', 'fedora', 'suse'] => 'httpd-devel',
'debian' => 'apache2-dev'
)
with_run_context
Используйте метод with_run_context для определения блока с указателем на местоположение в иерархии run_context. Ресурсы в рецептах всегда выполняются в корне иерархии run_context, тогда как пользовательские ресурсы и блоки уведомлений всегда создают дочернюю иерархию run_context, содержащую их подресурсы.
Синтаксис метода with_run_context следующий:
with_run_context :type do
# some arbitrary pure Ruby stuff goes here
end
где :type может быть одним из следующих:
-
:rootвыполняет блок как часть корневой иерархииrun_context -
:parentвыполняет блок как часть родительского процесса в иерархииrun_context
Например:
action :run do
with_run_context :root do
edit_resource(:my_thing, "accumulated state") do
action :nothing
my_array_property << accumulate_some_stuff
end
end
log "kick it off" do
notifies :run, "my_thing[accumulated state]", :delayed
end
end
Платформа Windows
В Recipe DSL есть шесть методов для проверки реестра во время выполнения Chef Infra Client на платформе Microsoft Windows — registry_data_exists?, registry_get_subkeys, registry_get_values, registry_has_subkeys?, registry_key_exists? и registry_value_exists? — эти вспомогательные функции обеспечивают идемпотентность ресурса powershell_script.
Примечание
key_exists?, value_exists?, data_exists?, get_values, has_subkeys? и затем get_subkeys.registry_data_exists?
Используйте метод registry_data_exists?, чтобы узнать, содержит ли ключ реестра Microsoft Windows указанные данные указанного типа в значении.
Примечание
Этот метод может быть использован в рецептах и внутри блоков not_if и only_if в ресурсах. Этот метод не предназначен для создания или изменения ключа реестра. Если требуется изменить ключ реестра, используйте ресурс registry_key.
Синтаксис метода registry_data_exists? следующий:
registry_data_exists?(
KEY_PATH,
{ name: 'NAME', type: TYPE, data: DATA },
ARCHITECTURE
)
где:
-
KEY_PATH— это путь к значению ключа реестра. Путь должен включать раздел реестра, который можно указать либо полным именем, либо 3- или 4-буквенным сокращением. Например, какHKLM\SECURITY, так иHKEY_LOCAL_MACHINE\SECURITYявляются допустимыми и эквивалентными. Допустимые разделы:HKEY_LOCAL_MACHINE,HKLM,HKEY_CURRENT_CONFIG,HKCC,HKEY_CLASSES_ROOT,HKCR,HKEY_USERS,HKU,HKEY_CURRENT_USERиHKCU. -
{ name: 'NAME', type: TYPE, data: DATA }— это хеш, содержащий ожидаемое имя, тип и данные значения ключа реестра -
type:представляет доступные значения для ключей реестра в Microsoft Windows. Используйте:binaryдля REG_BINARY,:stringдля REG_SZ,:multi_stringдля REG_MULTI_SZ,:expand_stringдля REG_EXPAND_SZ,:dwordдля REG_DWORD,:dword_big_endianдля REG_DWORD_BIG_ENDIAN или:qwordдля REG_QWORD. -
ARCHITECTURE— одно из следующих значений::x86_64,:i386или:machine. Установите в:i386, чтобы читать или писать 32-битные ключи реестра на 64-битных машинах под управлением Microsoft Windows. Установите в:x86_64, чтобы принудительно записать в 64-битное расположение реестра, однако Chef Infra Client возвращает исключение, если:x86_64используется на 32-битной машине. Установите в:machine, чтобы Chef Infra Client мог использовать соответствующее расположение ключа на основе архитектуры вашего узла. Значение по умолчанию::machine.
Этот метод вернёт true или false.
registry_get_subkeys
Используйте метод registry_get_subkeys, чтобы получить список значений ключей реестра, которые присутствуют для ключа реестра Microsoft Windows.
Примечание
Этот метод может быть использован в рецептах и внутри блоков not_if и only_if в ресурсах. Этот метод не предназначен для создания или изменения ключа реестра. Если требуется изменить ключ реестра, используйте ресурс registry_key.
Синтаксис метода registry_get_subkeys следующий:
subkey_array = registry_get_subkeys(KEY_PATH, ARCHITECTURE)
где:
-
KEY_PATH— это путь к ключу реестра. Путь должен включать раздел реестра, который можно указать либо полным именем, либо сокращением из 3 или 4 букв. Например, обаHKLM\SECURITYиHKEY_LOCAL_MACHINE\SECURITYявляются допустимыми и эквивалентными. Следующие разделы реестра допустимы:HKEY_LOCAL_MACHINE,HKLM,HKEY_CURRENT_CONFIG,HKCC,HKEY_CLASSES_ROOT,HKCR,HKEY_USERS,HKU,HKEY_CURRENT_USERиHKCU. -
ARCHITECTURE— одно из следующих значений::x86_64,:i386или:machine. Установите значение:i386для чтения или записи 32-битных ключей реестра на 64-битных машинах под управлением Microsoft Windows. Установите значение:x86_64, чтобы принудительно записать в 64-битное местоположение реестра, однако Chef Infra Client возвращает исключение, если:x86_64используется на 32-битной машине. Установите значение:machine, чтобы разрешить Chef Infra Client использовать соответствующее расположение ключа на основе архитектуры узла. Значение по умолчанию::machine.
Это возвращает массив значений ключа реестра.
registry_get_values
Используйте метод registry_get_values для получения значений ключа реестра Майкрософт Windows (имя, тип и данные) для ключа реестра Майкрософт Windows.
Примечание
Этот метод можно использовать в рецептах и внутри блоков not_if и only_if в ресурсах. Этот метод не предназначен для создания или изменения ключа реестра. Если необходимо изменить ключ реестра, используйте ресурс registry_key.
Синтаксис метода registry_get_values следующий:
subkey_array = registry_get_values(KEY_PATH, ARCHITECTURE)
где:
-
KEY_PATH— это путь к ключу реестра. Путь должен включать раздел реестра, который можно указать либо полным именем, либо сокращением из 3 или 4 букв. Например, обаHKLM\SECURITYиHKEY_LOCAL_MACHINE\SECURITYявляются допустимыми и эквивалентными. Следующие разделы реестра допустимы:HKEY_LOCAL_MACHINE,HKLM,HKEY_CURRENT_CONFIG,HKCC,HKEY_CLASSES_ROOT,HKCR,HKEY_USERS,HKU,HKEY_CURRENT_USERиHKCU. -
ARCHITECTURE— одно из следующих значений::x86_64,:i386или:machine. Установите значение:i386для чтения или записи 32-битных ключей реестра на 64-битных машинах под управлением Microsoft Windows. Установите значение:x86_64, чтобы принудительно записать в 64-битное местоположение реестра, однако Chef Infra Client возвращает исключение, если:x86_64используется на 32-битной машине. Установите значение:machine, чтобы разрешить Chef Infra Client использовать соответствующее расположение ключа на основе архитектуры узла. Значение по умолчанию::machine.
Это возвращает массив значений ключа реестра.
registry_has_subkeys?
Используйте метод registry_has_subkeys?, чтобы узнать, содержит ли ключ реестра Майкрософт Windows одно (или несколько) значение(й).
Примечание
Этот метод можно использовать в рецептах и внутри блоков not_if и only_if в ресурсах. Этот метод не предназначен для создания или изменения ключа реестра. Если необходимо изменить ключ реестра, используйте ресурс registry_key.
Синтаксис метода registry_has_subkeys? следующий:
registry_has_subkeys?(KEY_PATH, ARCHITECTURE)
где:
-
KEY_PATH— это путь к ключу реестра. Путь должен включать раздел реестра, который можно указать либо полным именем, либо сокращением из 3 или 4 букв. Например, обаHKLM\SECURITYиHKEY_LOCAL_MACHINE\SECURITYявляются допустимыми и эквивалентными. Следующие разделы реестра допустимы:HKEY_LOCAL_MACHINE,HKLM,HKEY_CURRENT_CONFIG,HKCC,HKEY_CLASSES_ROOT,HKCR,HKEY_USERS,HKU,HKEY_CURRENT_USERиHKCU. -
ARCHITECTURE— одно из следующих значений::x86_64,:i386или:machine. Установите значение:i386для чтения или записи 32-битных ключей реестра на 64-битных машинах под управлением Microsoft Windows. Установите значение:x86_64, чтобы принудительно записать в 64-битное местоположение реестра, однако Chef Infra Client возвращает исключение, если:x86_64используется на 32-битной машине. Установите значение:machine, чтобы разрешить Chef Infra Client использовать соответствующее расположение ключа на основе архитектуры узла. Значение по умолчанию::machine.
Этот метод вернёт true или false.
registry_key_exists?
Используйте метод registry_key_exists?, чтобы узнать, существует ли ключ реестра Майкрософт Windows по указанному пути.
Примечание
Этот метод можно использовать в рецептах и внутри блоков not_if и only_if в ресурсах. Этот метод не предназначен для создания или изменения ключа реестра. Если необходимо изменить ключ реестра, используйте ресурс registry_key.
Синтаксис метода registry_key_exists? следующий:
registry_key_exists?(KEY_PATH, ARCHITECTURE)
где:
-
KEY_PATH— это путь к ключу реестра. Путь должен включать раздел реестра, который можно указать либо полным именем, либо сокращением из 3 или 4 букв. Например, обаHKLM\SECURITYиHKEY_LOCAL_MACHINE\SECURITYявляются допустимыми и эквивалентными. Следующие разделы реестра допустимы:HKEY_LOCAL_MACHINE,HKLM,HKEY_CURRENT_CONFIG,HKCC,HKEY_CLASSES_ROOT,HKCR,HKEY_USERS,HKU,HKEY_CURRENT_USERиHKCU. -
ARCHITECTURE— одно из следующих значений::x86_64,:i386или:machine. Установите значение:i386для чтения или записи 32-битных ключей реестра на 64-битных машинах под управлением Microsoft Windows. Установите значение:x86_64, чтобы принудительно записать в 64-битное местоположение реестра, однако Chef Infra Client возвращает исключение, если:x86_64используется на 32-битной машине. Установите значение:machine, чтобы разрешить Chef Infra Client использовать соответствующее расположение ключа на основе архитектуры узла. Значение по умолчанию::machine.
Этот метод вернёт true или false. (Любые значения ключа реестра, связанные с этим ключом реестра, игнорируются.)
registry_value_exists?
Используйте метод registry_value_exists?, чтобы узнать, существует ли значение ключа реестра. Используйте registry_data_exists? для проверки типа и данных значения ключа реестра.
Примечание
Этот метод можно использовать в рецептах и внутри блоков not_if и only_if в ресурсах. Этот метод не предназначен для создания или изменения ключа реестра. Если необходимо изменить ключ реестра, используйте ресурс registry_key.
Синтаксис метода registry_dvalue_exists? следующий:
registry_value_exists?(
KEY_PATH,
{ name: 'NAME' },
ARCHITECTURE
)
где:
-
KEY_PATH— это путь к ключу реестра. Путь должен включать раздел реестра, который можно указать либо полным именем, либо сокращением из 3 или 4 букв. Например, обаHKLM\SECURITYиHKEY_LOCAL_MACHINE\SECURITYявляются допустимыми и эквивалентными. Следующие разделы реестра допустимы:HKEY_LOCAL_MACHINE,HKLM,HKEY_CURRENT_CONFIG,HKCC,HKEY_CLASSES_ROOT,HKCR,HKEY_USERS,HKU,HKEY_CURRENT_USERиHKCU. -
{ name: 'NAME' }— это хэш, содержащий имя значения ключа реестра; если указаныtype:или:value, они игнорируются. -
type:представляет значения, доступные для ключей реестра в Microsoft Windows. Используйте:binaryдля REG_BINARY,:stringдля REG_SZ,:multi_stringдля REG_MULTI_SZ,:expand_stringдля REG_EXPAND_SZ,:dwordдля REG_DWORD,:dword_big_endianдля REG_DWORD_BIG_ENDIAN или:qwordдля REG_QWORD. -
ARCHITECTURE— одно из следующих значений::x86_64,:i386или:machine. Установите значение:i386для чтения или записи 32-битных ключей реестра на 64-битных машинах под управлением Microsoft Windows. Установите значение:x86_64, чтобы принудительно записать в 64-битное местоположение реестра, однако Chef Infra Client возвращает исключение, если:x86_64используется на 32-битной машине. Установите значение:machine, чтобы разрешить Chef Infra Client использовать соответствующее расположение ключа на основе архитектуры узла. Значение по умолчанию::machine.
Этот метод вернёт true или false.
Записи журнала
Chef::Log будет печатать записи журнала в стандартный логирующий механизм, настроенный для машины, на которой выполняется Chef Infra Client. (Чтобы создать запись журнала, встроенную в коллекцию ресурсов, используйте ресурс log вместо Chef::Log.)
Поддерживаются следующие уровни журналов:
| Уровень журнала | Синтаксис |
|---|---|
| Критический | Chef::Log.fatal('string') |
| Ошибка | Chef::Log.error('string') |
| Предупреждение | Chef::Log.warn('string') |
| Информация | Chef::Log.info('string') |
| Отладка | Chef::Log.debug('string') |
Примечание
Скобки необязательны, например, Chef::Log.info 'string' можно использовать вместо Chef::Log.info('string').
Следующие примеры показывают использование записей журнала Chef::Log в рецепте.
Следующий пример показывает серию критических записей журнала Chef::Log:
unless node['splunk']['upgrade_enabled']
Chef::Log.fatal('The chef-splunk::upgrade recipe was added to the node,')
Chef::Log.fatal('but the attribute `node["splunk"]["upgrade_enabled"]` was not set.')
Chef::Log.fatal('I am bailing here so this node does not upgrade.')
raise
end
service 'splunk_stop' do
service_name 'splunk'
supports status: true
action :stop
end
if node['splunk']['is_server']
splunk_package = 'splunk'
url_type = 'server'
else
splunk_package = 'splunkforwarder'
url_type = 'forwarder'
end
splunk_installer splunk_package do
url node['splunk']['upgrade']["#{url_type}_url"]
end
if node['splunk']['accept_license']
execute 'splunk-unattended-upgrade' do
command "#{splunk_cmd} start --accept-license --answer-yes"
end
else
Chef::Log.fatal('You did not accept the license (set node["splunk"]["accept_license"] to true)')
Chef::Log.fatal('Splunk is stopped and cannot be restarted until the license is accepted!')
raise
end
Полный рецепт — это рецепт из кулинарной книги chef-splunk, поддерживаемой компанией Chef.
Следующий пример демонстрирует использование нескольких типов записей Chef::Log:
...
begin
aws = Chef::DataBagItem.load(:aws, :main)
Chef::Log.info("Loaded AWS information from DataBagItem aws[#{aws['id']}]")
rescue
Chef::Log.fatal("Could not find the 'main' item in the 'aws' data bag")
raise
end
...
Полный рецепт находится в рецепте из кулинарной книги database, поддерживаемой компанией Chef.
© Chef Software, Inc.
Licensed under the Creative Commons Attribution 3.0 Unported License.
The Chef™ Mark and Chef Logo are either registered trademarks/service marks or trademarks/servicemarks of Chef, in the United States and other countries and are used with Chef Inc's permission.
We are not affiliated with, endorsed or sponsored by Chef Inc.
https://docs.chef.io/dsl_recipe/