Spec-Zone.ru › Chef 18

Ресурс шаблона

Эта страница сгенерирована из исходного кода клиента Chef Infra. Чтобы предложить изменения, отредактируйте файл template.rb и отправьте запрос на вытягивание в репозиторий Chef Infra Client.

Все страницы ресурсов Infra


Шаблон кулинарной книги — это шаблон Embedded Ruby (ERB), который используется для динамического генерирования статических текстовых файлов. Шаблоны могут содержать выражения и операторы Ruby и представляют собой прекрасный способ управления конфигурационными файлами. Используйте ресурс template, чтобы добавить шаблоны кулинарной книги в рецепты; поместите соответствующий файл шаблона Embedded Ruby (ERB) в каталог кулинарной книги /templates.

Используйте ресурс template для управления содержимым файла с помощью шаблона Embedded Ruby (ERB), переносимого из подкаталога COOKBOOK_NAME/templates/ в указанный путь на узле, на котором запущен Chef Infra Client. Этот ресурс включает действия и свойства из ресурса file. Файлы шаблонов, управляемые ресурсом template, следуют тем же правилам специфичности файлов, что и ресурсы remote_file и file.

Синтаксис


Блок ресурса template обычно объявляет расположение, в котором должен быть создан файл, исходный шаблон, который будет использоваться для создания файла, и разрешения, необходимые для этого файла. Например:

template '/etc/motd' do
  source 'motd.erb'
  owner 'root'
  group 'root'
  mode '0755'
end

где:

  • '/etc/motd' указывает расположение, в котором создается файл
  • 'motd.erb' указывает имя шаблона, который существует в папке /templates кулинарной книги
  • owner, group и mode определяют разрешения

Полный синтаксис всех свойств, доступных для ресурса template, выглядит следующим образом:

template 'name' do
  atomic_update              true, false
  backup                     false, Integer
  cookbook                   String
  force_unlink               true, false
  group                      String, Integer
  helper(:method)            Method { String } # see Helpers below
  helpers(module)            Module # see Helpers below
  inherits                   true, false
  local                      true, false
  manage_symlink_source      true, false
  mode                       String, Integer
  owner                      String, Integer
  path                       String # defaults to 'name' if not specified
  rights                     Hash
  sensitive                  true, false
  source                     String, Array
  variables                  Hash
  verify                     String, Block
  action                     Symbol # defaults to :create if not specified
end

где:

  • template — это ресурс
  • name — это имя блока ресурса, как правило, путь к расположению, в котором создается файл, и также имя управляемого файла. Например: /var/www/html/index.html, где /var/www/html/ — это полный путь к расположению, а index.html — это имя файла
  • source — это файл шаблона, который будет использоваться для создания файла на узле, например: index.html.erb; файл шаблона находится в каталоге /templates кулинарной книги
  • action определяет действия, которые Chef Infra Client предпримет для приведения узла в нужное состояние
  • atomic_update, backup, cookbook, force_unlink, group, helper, helpers, inherits, local, manage_symlink_source, mode, owner, path, rights, source, variables и verify — это свойства этого ресурса с указанным типом Ruby. Более подробную информацию обо всех свойствах, которые можно использовать с этим ресурсом, см. в разделе «Свойства».

Действия


Ресурс template имеет следующие действия:

:create
По умолчанию. Создать файл. Если файл уже существует (но не соответствует шаблону), обновить этот файл в соответствии с шаблоном.
:create_if_missing
Создать файл только в том случае, если он не существует. Если файл существует, ничего не происходит.
:delete
Удалить файл.
:nothing
Этот блок ресурса не действует, пока не получит уведомление от другого ресурса о выполнении действия. После уведомления этот блок ресурса либо выполняется немедленно, либо добавляется в очередь для выполнения в конце выполнения Chef Infra Client.
:touch
Отметить файл. Это обновляет временные метки доступа (atime) и изменения файла (mtime). (Это действие может быть использовано с этим ресурсом, но обычно используется только с ресурсом file.)

Свойства


Ресурс template имеет следующие свойства:

atomic_update
Тип Ruby: true, false

Выполнять атомные обновления файлов на основе каждого ресурса. Установите в true для атомных обновлений файлов. Установите в false для неатомных обновлений файлов. Эта настройка переопределяет file_atomic_update, которая является глобальной настройкой, находящейся в файле client.rb.

backup
Тип Ruby: Целое число, false | Значение по умолчанию: 5

Количество резервных копий, которые будут сохранены в /var/chef/backup (для платформ на основе UNIX и Linux) или C:/chef/backup (для платформы Microsoft Windows). Установите в false, чтобы не сохранять резервные копии.

cookbook
Тип Ruby: Строка

Кулинарная книга, в которой находится файл (если он не находится в текущей кулинарной книге). Значение по умолчанию — текущая кулинарная книга.

force_unlink
Тип Ruby: true, false | Значение по умолчанию: false

Как Chef Infra Client обрабатывает определённые ситуации, когда целевой файл оказывается не файлом. Например, когда целевой файл является символической ссылкой. Установите в true, чтобы Chef Infra Client удалил целевой файл, который не является файлом, и заменил его указанным файлом. Установите в false, чтобы Chef Infra Client выдал ошибку.

group
Тип Ruby: Целое число, строка

Строка или идентификатор, которые идентифицируют владельца группы по имени группы или SID, включая полные имена групп, такие как domain\group или group@domain. Если это значение не указано, существующие группы остаются неизменными, а новые назначения групп используют стандартную группу POSIX (если она доступна).

helper
Тип Ruby: Метод | Значение по умолчанию: {}

Определить встроенный вспомогательный метод. Например: helper(:hello_world) { "hello world" } или helper(:app) { node["app"] } или helper(:app_conf) { |setting| node["app"][setting] }.

helpers
Тип Ruby: Модуль | Значение по умолчанию: []

Определить встроенный вспомогательный модуль или модуль в библиотеке. Например, встроенный модуль: helpers do, за которым следует блок кода Ruby. А для модуля библиотеки: helpers(MyHelperModule).

inherits
Тип Ruby: true, false | Значение по умолчанию: true

Только для Microsoft Windows. Наследует ли файл права из родительского каталога.

local
Тип Ruby: true, false | Значение по умолчанию: false

Загрузить шаблон из локального пути. По умолчанию Chef Infra Client загружает шаблоны из каталога кулинарной книги /templates. Когда это свойство установлено в true, используйте свойство source для указания пути к шаблону на локальном узле.

manage_symlink_source
Тип Ruby: true, false | Значение по умолчанию: true

(с предупреждением)

Изменить поведение ресурса файла, если он указывает на символическую ссылку. Когда это значение установлено в true, Chef Infra Client будет управлять разрешениями символической ссылки или заменит символическую ссылку обычным файлом, если у ресурса есть содержимое. Когда это значение установлено в false, Chef будет следовать символической ссылке и будет управлять разрешениями и содержимым целевого файла символической ссылки.

Поведение по умолчанию — true, но выводится предупреждение, что значение по умолчанию будет изменено на false в будущей версии; явное задание этого значения в true или false подавляет это предупреждение.

mode
Тип Ruby: Целое число, строка

Цитируемая строка из 3-5 символов, которая определяет восьмеричный режим. Например: '755', '0755' или 00755. Если mode не указано, и если файл уже существует, используется существующий режим файла. Если mode не указано, файл не существует и указано действие :create, Chef Infra Client предполагает значение маски '0777', а затем применяет маску umask для системы, в которой должен быть создан файл, к значению mask. Например, если umask в системе равен '022', Chef Infra Client использует значение по умолчанию '0755'.

Поведение отличается в зависимости от платформы.

Системы на базе UNIX и Linux: цитируемая строка из 3-5 символов, определяющая восьмеричный режим, передаваемый в chmod. Например: '755', '0755' или 00755. Если значение указано как строка в кавычках, оно работает точно так же, как если бы была передана команда chmod. Если значение указано как целое число, добавьте ноль (0) к значению, чтобы убедиться, что оно интерпретируется как восьмеричное число. Например, для назначения прав чтения, записи и выполнения для всех пользователей используйте '0777' или '777'; для тех же прав плюс бит sticky используйте 01777 или '1777'.

Microsoft Windows: цитируемая строка из 3-5 символов, определяющая восьмеричный режим, который преобразуется в права для безопасности Microsoft Windows. Например: '755', '0755' или 00755. Разрешены значения до '0777' (без бита sticky), которые означают то же самое в Microsoft Windows, что и в UNIX, где 4 равно GENERIC_READ, 2 равно GENERIC_WRITE, а 1 равно GENERIC_EXECUTE. Это свойство не может использоваться для установки :full_control. Это свойство не оказывает никакого влияния, если не указано, но когда оно и rights указаны оба, эффекты суммируются.

owner
Тип Ruby: Целое число, Строка

Строка или идентификатор, определяющий владельца группы по имени пользователя или SID, включая полные имена пользователей, такие как domain\user или user@domain. Если это значение не указано, существующие владельцы остаются неизменными, а новые назначения владельца используют текущего пользователя (при необходимости).

path
Тип Ruby: Строка | Значение по умолчанию: The resource block's name

Полный путь к файлу, включая имя файла и его расширение.

Microsoft Windows: Путь, начинающийся с прямой черты (/), указывает на корень текущего каталога, в котором работает процесс Chef Infra Client. Этот путь может отличаться от системы к системе. Поэтому использование пути, начинающегося с прямой черты (/), не рекомендуется.

rights
Тип Ruby: Целое число, Строка

Только Microsoft Windows. Разрешения для пользователей и групп в среде Microsoft Windows. Например: rights <permissions>, <principal>, <options>, где <permissions> указывает права, предоставленные субъекту, <principal> — имя группы или пользователя, а <options> — хеш с одним (или несколькими) дополнительными правами.

source
Тип Ruby: Строка, Массив

Расположение файла шаблона. По умолчанию Chef Infra Client ищет файл шаблона в каталоге /templates кулинарной книги. Когда свойство local установлено в true, используйте для указания пути к шаблону на локальном узле. Это свойство также может использоваться для распределения определенных файлов на определенные платформы. Подробнее см. «Специфичность файла» ниже. Значение по умолчанию: name блока ресурса. Подробнее см. раздел «Синтаксис» выше.

variables
Тип Ruby: Хеш

Хеш переменных, передаваемых в файл шаблона Ruby.

Свойство variables ресурса шаблона может использоваться для ссылки на частичный файл шаблона с помощью хеша. Например:

template '/file/name.txt' do
  variables partials: {
    'partial_name_1.txt.erb' => 'message',
    'partial_name_2.txt.erb' => 'message',
    'partial_name_3.txt.erb' => 'message',
  }
end

где каждый из частичных файлов шаблонов затем может быть объединен с помощью обычных шаблонов Ruby в файле шаблона, например:

<% @partials.each  do |partial, message| %>
  Here is <%= partial %>
  <%= render partial, :variables => {:message => message} %>
<% end %>
verify
Тип Ruby: Строка, Блок

Блок или строка, возвращающие true или false. Строка, когда true выполняется как системная команда.

Блок — это произвольный код Ruby, определённый в блоке ресурса с помощью свойства verify. Когда блок true, Chef Infra Client продолжит обновление файла по мере необходимости.

Например, это должно вернуть true:

template '/tmp/baz' do
  verify { 1 == 1 }
end

Это должно вернуть true:

template '/etc/nginx.conf' do
  verify 'nginx -t -c %{path}'
end

Это должно вернуть true:

template '/tmp/bar' do
  verify { 1 == 1}
end

А это должно вернуть true:

template '/tmp/foo' do
  verify do |path|
    true
  end
end

В то время как это должно вернуть false:

template '/tmp/turtle' do
  verify '/usr/bin/false'
end

Если строка или блок возвращают false, выполнение Chef Infra Client прекратится, и будет возвращено сообщение об ошибке.

Атомарные обновления файлов

Атомарные обновления используются с ресурсами на основе файлов, чтобы гарантировать, что обновления файлов могут выполняться при обновлении двоичного файла или при недостатке места на диске.

Атомарные обновления включены по умолчанию. Их можно управлять глобально с помощью параметра file_atomic_update в файле client.rb. Их можно управлять на уровне каждого ресурса с помощью свойства atomic_update, доступного для ресурсов cookbook_file, file, remote_file и template.

Примечание

На некоторых платформах и после перемещения файла в нужное место Chef Infra Client может изменить разрешения файлов для поддержки функций, специфичных для этих платформ. На платформах с включенным SELinux Chef Infra Client исправит контексты безопасности после перемещения файла в нужное место, выполнив команду restorecon. На платформе Microsoft Windows Chef Infra Client создаст файлы таким образом, чтобы наследование списков управления доступом работало как ожидается.

Безопасность файлов Windows

Для поддержки безопасности Microsoft Windows ресурсы template, file, remote_file, cookbook_file, directory и remote_directory поддерживают использование наследования и списков управления доступом (ACL) в рецептах. Списки управления доступом (ACL)

Свойство rights может использоваться в рецепте для управления списками управления доступом (ACL), которые позволяют предоставлять права нескольким пользователям и группам. Свойство rights можно использовать любое количество раз; Chef Infra Client применит их к файлу или каталогу по мере необходимости. Синтаксис свойства rights следующий:

rights permission, principal, option_type => value

где

permission

Используется для указания прав, предоставляемых principal. Возможные значения: :read, :write, read_execute, :modify, :full_control или целое число.

Целые числа, используемые для разрешений, должны соответствовать следующему списку FileSystemRights Enum полям.

These permissions are cumulative. If `:write` is specified, then it
includes `:read`. If `:full_control` is specified, then it includes
both `:write` and `:read`.

(For those who know the Microsoft Windows API: `:read` corresponds
to `GENERIC_READ`; `:write` corresponds to `GENERIC_WRITE`;
`:read_execute` corresponds to `GENERIC_READ` and `GENERIC_EXECUTE`;
`:modify` corresponds to `GENERIC_WRITE`, `GENERIC_READ`,
`GENERIC_EXECUTE`, and `DELETE`; `:full_control` corresponds to
`GENERIC_ALL`, which allows a user to change the owner and other
metadata about a file.)
principal

Используется для указания группы или пользователя. Субъект может быть указан либо по имени, либо по SID. При использовании имени это идентично тому, что вводится в поле входа для Microsoft Windows, например user_name, domain\user_name или user_name@fully_qualified_domain_name. При использовании SID вы можете использовать либо стандартное строковое представление SID (S-R-I-S-S), либо одно из констант строк SDDL. Chef Infra Client не нужно знать, является ли субъект пользователем или группой.

option_type

Хеш, содержащий дополнительные параметры прав. Например, права на каталог, которые применяются только к первому уровню дочерних элементов, могут выглядеть примерно так: rights :write, 'domain\group_name', :one_level_deep => true. Возможные типы опций:

Тип опции Описание
:applies_to_children Указывает, как права применяются к дочерним элементам. Возможные значения: true для наследования как дочерних каталогов, так и файлов; false для отказа от наследования любых дочерних каталогов или файлов; :containers_only для наследования только дочерних каталогов (и не файлов); :objects_only для рекурсивного наследования файлов (и не дочерних каталогов).
:applies_to_self Указывает, применяется ли разрешение к родительскому каталогу. Возможные значения: true для применения к родительскому каталогу или файлу и его дочерним элементам; false для применения только к дочерним каталогам и файлам.
:one_level_deep Указывает глубину, до которой будут применяться разрешения. Возможные значения: true для применения только к первому уровню дочерних элементов; false для применения ко всем дочерним элементам.

Например:

resource 'x.txt' do
  rights :read, 'S-1-1-0'
  rights :write, 'domain\group'
  rights :full_control, 'group_name_or_user_name'
  rights :full_control, 'user_name', applies_to_children: true
end

или:

rights :read, %w(Administrators Everyone)
rights :full_control, 'Users', applies_to_children: true
rights :write, 'Sally', applies_to_children: :containers_only, applies_to_self: false, one_level_deep: true

Некоторые другие важные моменты при использовании атрибута rights:

  • Остаются только унаследованные права. Все существующие явные права на объект удаляются и заменяются.
  • Если права не указаны, ничего не изменится. Chef Infra Client не очищает права на файл или каталог, если права не указаны.
  • Изменение унаследованных прав может быть ресурсоемким. Microsoft Windows будет рекурсивно распространять права на все дочерние элементы из-за наследования. Это нормальная особенность Microsoft Windows, поэтому рассмотрите частоту, с которой этот тип действия необходим, и примите меры по контролю такого действия, если производительность является основным фактором.

Используйте свойство deny_rights, чтобы запретить определённые права определённым пользователям. Порядок не зависит от использования свойства rights. Например, неважно, помещены ли права для всех перед или после deny_rights :read, ['Julian', 'Lewis'], и Джулиан, и Левис не смогут прочитать документ. Например:

resource 'x.txt' do
  rights :read, 'Everyone'
  rights :write, 'domain\group'
  rights :full_control, 'group_name_or_user_name'
  rights :full_control, 'user_name', applies_to_children: true
  deny_rights :read, %w(Julian Lewis)
end

или:

deny_rights :full_control, ['Sally']
Наследование

По умолчанию файл или каталог наследуют права из родительского каталога. В большинстве случаев это предпочтительное поведение, но иногда необходимо принять меры для более точного управления правами. Свойство inherits можно использовать, чтобы явно указать Chef Infra Client применять (или не применять) унаследованные права из родительского каталога.

Например, следующий пример задаёт права для каталога:

directory 'C:\mordor' do
  rights :read, 'MORDOR\Minions'
  rights :full_control, 'MORDOR\Sauron'
end

а затем следующий пример показывает, как использовать наследование, чтобы запретить доступ к дочернему каталогу:

directory 'C:\mordor\mount_doom' do
  rights :full_control, 'MORDOR\Sauron'
  inherits false # Sauron is the only person who should have any sort of access
end

Если вместо этого использовать разрешение deny_rights, что-то может пройти незамеченным, если не будут запрещены все пользователи и группы.

Ещё один пример также показывает, как указать права для каталога:

directory 'C:\mordor' do
  rights :read, 'MORDOR\Minions'
  rights :full_control, 'MORDOR\Sauron'
  rights :write, 'SHIRE\Frodo' # Who put that there I didn't put that there
end

но затем не использовать свойство inherits, чтобы запретить эти права в дочернем каталоге:

directory 'C:\mordor\mount_doom' do
  deny_rights :read, 'MORDOR\Minions' # Oops, not specific enough
end

Поскольку свойство inherits не указано, Chef Infra Client по умолчанию установит его в true, что гарантирует сохранение настроек безопасности существующих файлов без изменений.

Использование шаблонов

Для использования шаблона необходимо сделать два шага:

  1. В рецепт должен быть добавлен ресурс шаблона
  2. В кулинарную книгу должен быть добавлен шаблон Embedded Ruby (ERB)

Например, следующие настройки файла шаблона и ресурса шаблона можно использовать для управления файлом конфигурации с именем /etc/sudoers. В кулинарной книге, использующей sudo, в /recipes/default.rb можно добавить следующий ресурс:

template '/etc/sudoers' do
  source 'sudoers.erb'
  mode '0440'
  owner 'root'
  group 'root'
  variables(sudoers_groups: node['authorization']['sudo']['groups'],
            sudoers_users: node['authorization']['sudo']['users'])
end

И затем создайте шаблон, который называется sudoers.erb, и сохраните его в templates/default/sudoers.erb:

#
# /etc/sudoers
#
# Generated by Chef for <%= node['fqdn'] %>
#

Defaults        !lecture,tty_tickets,!fqdn

# User privilege specification
root          ALL=(ALL) ALL

<% @sudoers_users.each  do |user| -%>
<%= user %>   ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL
<% end -%>
# Members of the sysadmin group may gain root privileges
%sysadmin     ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL
<% @sudoers_groups.each do |group| -%>
# Members of the group '<%= group %>' may gain root privileges
<%= group %> ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL
<% end -%>

И затем задайте атрибуты по умолчанию в attributes/default.rb:

default['authorization']['sudo']['groups'] = %w(sysadmin wheel admin)
default['authorization']['sudo']['users'] = %w(jerry greg)

Уточнение шаблона по файлам

Кулинарная книга часто разрабатывается для работы на многих платформах и часто требует распространения определённого шаблона на определённую платформу. Кулинарную книгу можно разработать так, чтобы она поддерживала распространение шаблонов по платформам, обеспечивая при этом, что правильный шаблон оказывается на каждой системе.

Шаблон уточнения шаблона зависит от двух вещей: пути поиска и источника. Используется первый совпадающий шаблон:

  1. /host-$fqdn/$source
  2. /$platform-$platform_version/$source
  3. /$platform/$source
  4. /default/$source
  5. /$source

Примечание

Чтобы указать определённую версию Windows, используйте номер версии операционной системы. Например, шаблон в templates/windows-6.3 будет развернут на системах, установленных с Windows 8.1.

Используйте массив с свойством source, чтобы определить явный путь поиска. Например:

template '/test' do
  source ["#{node.chef_environment}.erb", 'default.erb']
end

Следующий пример эмулирует весь шаблон уточнения файлов, определив его как явный путь:

template '/test' do
  source %W(
    host-#{node['fqdn']}/test.erb
#{node['platform']}-#{node['platform_version']}/test.erb
#{node['platform']}/test.erb
    default/test.erb
  )
end

Кулинарная книга может иметь структуру каталогов /templates, которая выглядит так:

/templates/
  windows-10
  windows-6.3
  windows
  default

и ресурс, который выглядит примерно так:

template 'C:\path\to\file\text_file.txt' do
  source 'text_file.txt'
  mode '0755'
  owner 'root'
  group 'root'
end

Этот ресурс будет сопоставлен в том же порядке, что и структура каталогов /templates. Для узла под названием host-node-desktop, на котором запущена Windows 8.1, вторым элементом будет совпадающий элемент и расположение:

/templates
  windows-10/text_file.txt
  windows-6.3/text_file.txt
  windows/text_file.txt
  default/text_file.txt

Вспомогательные функции

Вспомогательная функция — это метод или модуль, который можно использовать для расширения шаблона. Существует три подхода:

  • Метод встраиваемой вспомогательной функции
  • Модуль встроенной вспомогательной функции
  • Модуль библиотеки кулинарной книги

Используйте атрибут helper в рецепте для определения метода встроенной вспомогательной функции. Используйте атрибут helpers для определения модуля встроенной вспомогательной функции или модуля библиотеки кулинарной книги.

Встроенные методы

Метод вспомогательной функции шаблона всегда определяется встроенно для каждого ресурса. Простой пример:

template '/path' do
  helper(:hello_world) { 'hello world' }
end

Другой способ определения встроенного метода вспомогательной функции заключается в ссылке на объект узла, чтобы повторяющиеся вызовы одного (или нескольких) атрибутов кулинарной книги выполнялись эффективно:

template '/path' do
  helper(:app) { node['app'] }
end

Встроенный метод вспомогательной функции также может принимать аргументы:

template '/path' do
  helper(:app_conf) { |setting| node['app'][setting] }
end

После объявления шаблон может использовать методы вспомогательных функций для построения файла. Например:

Say hello: <%= hello_world %>

или:

node['app']['listen_port'] is: <%= app['listen_port'] %>

или:

node['app']['log_location'] is: <%= app_conf('log_location') %>

Встроенные модули

Модуль вспомогательной функции шаблона можно определить встроенно для каждого ресурса. Этот подход может быть полезен, когда шаблон требует более сложной информации. Например:

template '/path' do
  helpers do
    def hello_world
      'hello world'
    end

    def app
      node['app']
    end

    def app_conf(setting)
      node['app']['setting']
    end
  end
end

где методы hello_world, app и app_conf(setting) составляют модуль, который расширяет шаблон.

Модули библиотек

Модуль вспомогательной функции шаблона можно определить в библиотеке. Это полезно, когда расширения нужно повторно использовать в рецептах или упростить управление кодом, который в противном случае определялся бы встроенно в каждом рецепте.

template '/path/to/template.erb' do
  helpers(MyHelperModule)
end

Нотация узла

Названия папок в каталогах кулинарной книги должны буквально соответствовать нотации узла, используемой для сопоставления уточнения шаблона. Например, если узел называется foo.example.com, то папка должна называться host-foo.example.com.

Частичные шаблоны

Шаблон может быть построен таким образом, чтобы он мог содержать ссылки на один (или несколько) меньших файлов шаблонов. (Эти меньшие файлы шаблонов также называются частичными.) К частичному файлу можно обратиться из файла шаблона одним из следующих способов:

  • Используя метод render в файле шаблона
  • Используя ресурс шаблон и свойство variables.

Метод render

Используйте метод render в шаблоне для ссылки на файл частичного шаблона:

<%= render 'partial_name.txt.erb', :option => {} %>

где partial_name — имя файла частичного шаблона, а :option — один (или несколько) из следующих:

Вариант Описание
:cookbook По умолчанию предполагается, что файл частичного шаблона находится в кулинарной книге, которая содержит шаблон верхнего уровня. Используйте этот вариант, чтобы указать путь к другой кулинарной книге
:local Указывает, что имя файла частичного шаблона должно интерпретироваться как путь к файлу в локальной файловой системе или ищется в кулинарной книге с использованием обычных правил для файлов шаблонов. Установите значение true, чтобы интерпретировать как путь к файлу в локальной файловой системе, и false, чтобы использовать обычные правила для файлов шаблонов
:source По умолчанию файл частичного шаблона идентифицируется по его имени файла. Используйте этот вариант, чтобы указать другое имя или локальный путь для использования (вместо имени файла частичного шаблона)
:variables Хэш variable_name => value, который будет доступен для файла частичного шаблона. При использовании этого варианта все переменные, определённые в шаблоне верхнего уровня, необходимые для частичного шаблона, должны быть определены явно с помощью этого параметра

Например:

<%= render 'simple.txt.erb', :variables => {:user => Etc.getlogin }, :local => true %>

Частота передачи

Клиент Chef Infra кеширует шаблон при его первом запросе. При каждом последующем запросе этого шаблона клиент Chef Infra сравнивает этот запрос с шаблоном, расположенным на сервере Chef Infra. Если шаблоны одинаковые, передача не происходит.

Переменные

Шаблон встраиваемого Ruby (ERB) позволяет встраивать код Ruby в текстовый файл в специально отформатированных тегах. Код Ruby можно встраивать с помощью выражений и операторов. Выражение ограничено <%= и %>. Например:
<%= "my name is #{$ruby}" %>

Оператор ограничен модификатором, таким как if, elsif и else. Например:

if false
# this won't happen
elsif nil
      # this won't either
    end

Использование выражения Ruby является наиболее распространённым подходом к определению переменных шаблона, потому что именно так все переменные, отправленные в шаблон, ссылаются. Всякий раз, когда шаблон должен использовать each, if или end, используйте оператор Ruby.

При рендеринге шаблона клиент Chef Infra оценивает выражения и операторы Ruby. Оцениваются переменные, перечисленные в параметре variables ресурса шаблон и в объекте узла. Клиент Chef Infra затем передаёт эти переменные шаблону, где они будут доступны как переменные экземпляра внутри шаблона. К объекту узла можно обратиться так, как будто он является частью рецепта, используя тот же синтаксис.

Например, простой ресурс шаблона, такой как этот:

node['fqdn'] = 'latte'
template '/tmp/foo' do
  source 'foo.erb'
  variables(x_men: 'are keen')
end

И простой шаблон встраиваемого Ruby (ERB), такой как этот:

The node <%= node[:fqdn] %> thinks the x-men <%= @x_men %>

Выведет что-то вроде:

The node latte thinks the x-men are keen

Хотя это очень простой пример, полные возможности Ruby можно использовать для решения даже самых сложных и требовательных задач с шаблонами.


Общие функции ресурсов


Ресурсы Chef включают общие свойства, уведомления и защитные механизмы ресурсов.

Общие свойства

Следующие свойства общие для всех ресурсов:

compile_time

Тип Ruby: true, false | Значение по умолчанию: false

Управляет фазой, в которой ресурс выполняется на узле. Установите значение true, чтобы запустить во время построения коллекции ресурсов (compile phase). Установите значение false, чтобы запустить во время настройки узла клиентом Chef Infra (converge phase).

ignore_failure

Тип Ruby: true, false, :quiet | Значение по умолчанию: false

Продолжить выполнение рецепта, если ресурс завершится неудачно по любой причине. :quiet не будет отображать полный стек вызовов, и рецепт продолжит выполнение, если ресурс завершится неудачно.

retries

Тип Ruby: Целое число | Значение по умолчанию: 0

Количество попыток перехватить исключения и повторить ресурс.

retry_delay

Тип Ruby: Целое число | Значение по умолчанию: 2

Задержка в секундах между попытками повтора.

sensitive

Тип Ruby: true, false | Значение по умолчанию: false

Обеспечить, чтобы чувствительные данные ресурсов не регистрировались клиентом Chef Infra.

Уведомления

notifies

Тип Ruby: Символ, 'Chef::Resource[String]'

Ресурс может уведомить другой ресурс о выполнении действий при изменении его состояния. Укажите 'resource[name]', :action, который должен выполнить этот ресурс, и :timer для этого действия. Ресурс может уведомить больше одного ресурса; используйте оператор notifies для каждого ресурса, который необходимо уведомить.

Если указанный ресурс не существует, генерируется ошибка. В отличие от subscribes, ошибка не будет возникать, если исходный ресурс не найден.

Таймер указывает момент во время выполнения клиента Chef Infra, в котором выполняется уведомление. Доступны следующие таймеры:

:before

Указывает, что действие над уведомлённым ресурсом должно быть выполнено до обработки блока ресурсов, в котором расположено уведомление.

:delayed

По умолчанию. Указывает, что уведомление должно быть помещено в очередь и затем выполнено в конце выполнения Chef Infra Client.

:immediate, :immediately

Указывает, что уведомление должно быть выполнено немедленно для каждого уведомлённого ресурса.

Синтаксис для notifies:

notifies :action, 'resource[name]', :timer
subscribes

Тип Ruby: Символ, 'Chef::Resource[String]'

Ресурс может следить за другим ресурсом и выполнять действие, если состояние отслеживаемого ресурса изменится. Укажите 'resource[name]', :action, которое должно быть выполнено, и :timer для этого действия.

Обратите внимание, что subscribes не применяет указанное действие к ресурсу, за которым он следит — например:

file '/etc/nginx/ssl/example.crt' do
  mode '0600'
  owner 'root'
end

service 'nginx' do
  subscribes :reload, 'file[/etc/nginx/ssl/example.crt]', :immediately
end

В этом случае свойство subscribes перезагружает сервис nginx всякий раз, когда файл сертификата, расположенный в /etc/nginx/ssl/example.crt, обновляется. subscribes не вносит никаких изменений в сам файл сертификата, а лишь следит за изменениями файла и выполняет действие :reload для своего ресурса (в данном примере nginx) при обнаружении изменений.

Если другой ресурс не существует, подписка не вызовет ошибку. Это отличается от более строгих семантик notifies, которые вызовут ошибку, если другой ресурс не существует.

Таймер указывает момент во время выполнения Chef Infra Client, в котором выполняется уведомление. Доступны следующие таймеры:

:before

Указывает, что действие над уведомлённым ресурсом должно быть выполнено до обработки блока ресурсов, в котором расположено уведомление.

:delayed

По умолчанию. Указывает, что уведомление должно быть помещено в очередь и затем выполнено в конце выполнения Chef Infra Client.

:immediate, :immediately

Указывает, что уведомление должно быть выполнено немедленно для каждого уведомлённого ресурса.

Синтаксис для subscribes:

subscribes :action, 'resource[name]', :timer

Фильтры

Свойство фильтра может использоваться для оценки состояния узла во время фазы выполнения Chef Infra Client. Основываясь на результатах этой оценки, свойство фильтра сообщает Chef Infra Client, следует ли ему продолжать выполнение ресурса. Свойство фильтра принимает либо строковое значение, либо значение Ruby-блока:

  • Строка выполняется как командная оболочка. Если команда возвращает 0, фильтр применяется. Если команда возвращает любое другое значение, то свойство фильтра не применяется. Строковые фильтры в powershell_script выполняют команды Windows PowerShell и могут возвращать true в дополнение к 0.
  • Блок выполняется как Ruby-код, который должен возвращать либо true, либо false. Если блок возвращает true, свойство фильтра применяется. Если блок возвращает false, свойство фильтра не применяется.

Свойство фильтра полезно для обеспечения идемпотентности ресурса, позволяя этому ресурсу проверять желаемое состояние во время его выполнения, а затем, если желаемое состояние присутствует, Chef Infra Client ничего не делает.

Свойства

Следующие свойства могут использоваться для определения фильтра, который оценивается во время фазы выполнения Chef Infra Client:

not_if

Запрещает выполнение ресурса, когда условие возвращает true.

only_if

Разрешает выполнение ресурса только в том случае, если условие возвращает true.

Примеры


Следующие примеры демонстрируют различные подходы к использованию ресурса template в рецептах:

Настройка файла из шаблона

template '/tmp/config.conf' do
  source 'config.conf.erb'
end

Настройка файла из локального шаблона

template '/tmp/config.conf' do
  local true
  source '/tmp/config.conf.erb'
end

Настройка файла с использованием карты переменных

template '/tmp/config.conf' do
  source 'config.conf.erb'
  variables(
    :config_var => node['configs']['config_var']
  )
end

Использование условия not_if

Следующий пример демонстрирует, как использовать условие not_if для создания файла на основе шаблона и использования наличия значения атрибута на узле для указания условия:

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  not_if { node['some_value'] }
end

Следующий пример демонстрирует, как использовать условие not_if для создания файла на основе шаблона и затем Ruby-кода для указания условия:

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  not_if do
    File.exist?('/etc/passwd')
  end
end

Следующий пример демонстрирует, как использовать условие not_if для создания файла на основе шаблона и использования Ruby-блока (в фигурных скобках) для указания условия:

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  not_if { File.exist?('/etc/passwd') }
end

Следующий пример демонстрирует, как использовать условие not_if для создания файла на основе шаблона и использования строки для указания условия:

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  not_if 'test -f /etc/passwd'
end

Использование условия only_if

Следующий пример демонстрирует, как использовать условие only_if для создания файла на основе шаблона и использования наличия атрибута на узле для указания условия:

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  only_if { node['some_value'] }
end

Следующий пример демонстрирует, как использовать условие only_if для создания файла на основе шаблона, а затем использовать Ruby для указания условия:

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  only_if { ! ::File.exist?('/etc/passwd') }
end

Следующий пример демонстрирует, как использовать условие only_if для создания файла на основе шаблона и использования строки для указания условия:

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  only_if 'test -f /etc/passwd'
end

Использование массива пробельных символов (%w)

Следующий пример демонстрирует, как использовать массив пробельных символов Ruby для определения списка инструментов конфигурации, а затем использовать этот список инструментов в ресурсе template для обеспечения того, что все эти инструменты конфигурации используют один и тот же ключ RSA:

%w{openssl.cnf pkitool vars Rakefile}.each do |f|
  template "/etc/openvpn/easy-rsa/#{f}" do
    source "#{f}.erb"
    owner 'root'
    group 'root'
    mode '0755'
  end
end

Использование относительного пути

template "#{ENV['HOME']}/chef-getting-started.txt" do
  source 'chef-getting-started.txt.erb'
  mode '0755'
end

Задержка уведомлений

template '/etc/nagios3/configures-nagios.conf' do
  # other parameters
  notifies :run, 'execute[test-nagios-config]', :delayed
end

Немедленное уведомление

По умолчанию уведомления :delayed, то есть они помещаются в очередь по мере возникновения, а затем выполняются в самом конце выполнения Chef Infra Client. Чтобы выполнить действие немедленно, используйте :immediately:

template '/etc/nagios3/configures-nagios.conf' do
  # other parameters
  notifies :run, 'execute[test-nagios-config]', :immediately
end

и затем Chef Infra Client немедленно выполнит следующее:

execute 'test-nagios-config' do
  command 'nagios3 --verify-config'
  action :nothing
end

Уведомление нескольких ресурсов

template '/etc/chef/server.rb' do
  source 'server.rb.erb'
  owner 'root'
  group 'root'
  mode '0755'
  notifies :restart, 'service[chef-solr]', :delayed
  notifies :restart, 'service[chef-solr-indexer]', :delayed
  notifies :restart, 'service[chef-server]', :delayed
end

Перезагрузка сервиса

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  notifies :reload, 'service[apache]', :immediately
end

Перезапуск службы при изменении шаблона

template '/etc/www/configures-apache.conf' do
  notifies :restart, 'service[apache]', :immediately
end

Отправка уведомлений нескольким ресурсам

Чтобы отправить уведомления нескольким ресурсам, просто используйте несколько атрибутов. Несколько атрибутов будут отправлены уведомленным ресурсам в указанном порядке.

template '/etc/netatalk/netatalk.conf' do
  notifies :restart, 'service[afpd]', :immediately
  notifies :restart, 'service[cnid]', :immediately
end

service 'afpd'
service 'cnid'

Выполнение команды с помощью шаблона

Следующий пример показывает, как настроить IPv4 packet forwarding с помощью ресурса execute для выполнения команды forward_ipv4, которая использует шаблон, определённый ресурсом template:

execute 'forward_ipv4' do
  command 'echo > /proc/.../ipv4/ip_forward'
  action :nothing
end

template '/etc/file_name.conf' do
  source 'routing/file_name.conf.erb'
  notifies :run, 'execute[forward_ipv4]', :delayed
end

где свойство command ресурса execute содержит команду, которая должна быть выполнена, а свойство source ресурса template указывает, какой шаблон использовать. Свойство notifies для template указывает, что execute[forward_ipv4] (определённый ресурсом execute) должно быть помещено в очередь и выполнено в конце выполнения Chef Infra Client.

Установка IP-адреса с использованием переменных и шаблона

Следующий пример демонстрирует, как ресурс template может быть использован в рецепте для объединения настроек, хранящихся в файле атрибутов, переменных в рецепте и шаблона для установки IP-адресов, используемых службой Nginx. Файл атрибутов содержит следующее:

default['nginx']['dir'] = '/etc/nginx'

Затем рецепт выполняет следующие действия:

  • Объявляет две переменные в начале рецепта, одну для удалённого IP-адреса и другую для авторизованного IP-адреса
  • Использует ресурс service для перезапуска и перезагрузки сервиса Nginx
  • Загружает шаблон с именем authorized_ip.erb из каталога /templates, который используется для установки значений IP-адресов на основе переменных, указанных в рецепте
node.default['nginx']['remote_ip_var'] = 'remote_addr'
node.default['nginx']['authorized_ips'] = ['127.0.0.1/32']

service 'nginx' do
  supports :status => true, :restart => true, :reload => true
end

template 'authorized_ip' do
  path "#{node['nginx']['dir']}/authorized_ip"
  source 'modules/authorized_ip.erb'
  owner 'root'
  group 'root'
  mode '0755'
  variables(
    :remote_ip_var => node['nginx']['remote_ip_var'],
    :authorized_ips => node['nginx']['authorized_ips']
  )

  notifies :reload, 'service[nginx]', :immediately
end

где свойство variables сообщает шаблону использовать переменные, заданные в начале рецепта, а свойство source используется для вызова файла шаблона, расположенного в каталоге /templates кулинарной книги. Файл шаблона выглядит примерно так:

geo $<%= @remote_ip_var %> $authorized_ip {
  default no;
  <% @authorized_ips.each do |ip| %>
  <%= "#{ip} yes;" %>
  <% end %>
}

Добавление правила в таблицу IP

Следующий пример демонстрирует, как добавить правило с именем test_rule в таблицу IP с помощью ресурса execute для выполнения команды с помощью шаблона, определённого ресурсом template:

execute 'test_rule' do
  command 'command_to_run
    --option value
    ...
    --option value
    --source #{node[:name_of_node][:ipsec][:local][:subnet]}
    -j test_rule'
  action :nothing
end

template '/etc/file_name.local' do
  source 'routing/file_name.local.erb'
  notifies :run, 'execute[test_rule]', :delayed
end

где свойство command ресурса execute содержит команду, которая должна быть выполнена, а свойство source ресурса template указывает, какой шаблон использовать. Свойство notifies для template указывает, что execute[test_rule] (определённый ресурсом execute) должно быть помещено в очередь и выполнено в конце выполнения Chef Infra Client.

Согласованное применение настроек прокси по всей организации Chef

Следующий пример демонстрирует, как шаблон может использоваться для применения согласованных настроек прокси для всех узлов одного типа:

template "#{node['matching_node']['dir']}/sites-available/site_proxy.conf" do
  source 'site_proxy.matching_node.conf.erb'
  owner 'root'
  group 'root'
  mode '0755'
  variables(
    :ssl_certificate =>    "#{node['matching_node']['dir']}/shared/certificates/site_proxy.crt",
    :ssl_key =>            "#{node['matching_node']['dir']}/shared/certificates/site_proxy.key",
    :listen_port =>        node['site']['matching_node_proxy']['listen_port'],
    :server_name =>        node['site']['matching_node_proxy']['server_name'],
    :fqdn =>               node['fqdn'],
    :server_options =>     node[:site]['matching_node']['server']['options'],
    :proxy_options =>      node[:site]['matching_node']['proxy']['options']
  )
end

где matching_node представляет тип узла (например, Nginx), а site_proxy представляет тип прокси, используемого для этого типа узла (например, Nexus).

Получение настроек шаблона из локального файла

Ресурс шаблона можно использовать для рендеринга шаблона на основе настроек, содержащихся в локальном файле на диске, или для получения настроек из шаблона в кулинарной книге. Чаще всего настройки извлекаются из шаблона в кулинарной книге. Следующий пример демонстрирует, как ресурс шаблона может быть использован для получения этих настроек из локального файла.

Следующий пример основан на нескольких предположениях:

  • Среда — это приложение Ruby on Rails, которое необходимо отобразить файл, названный database.yml
  • Информация об приложении — пользователе, его пароле, сервере — хранится в пакете данных на сервере Chef.
  • Приложение уже развернуто на системе, и единственное требование в этом примере — отобразить файл database.yml

Дерево исходного кода приложения выглядит примерно так:

  myapp/
  -> config/
     -> database.yml.erb

Примечание

Не должно быть файла, названного database.yml (без .erb), так как файл database.yml будет отображен с помощью ресурса шаблона.

Развертывание приложения завершится в /srv, поэтому полный путь к этому шаблону будет примерно таким: /srv/myapp/current/config/database.yml.erb.

Содержание самого шаблона может выглядеть следующим образом:

<%= @rails_env %>:
   adapter: <%= @adapter %>
   host: <%= @host %>
   database: <%= @database %>
   username: <%= @username %>
   password: <%= @password %>
   encoding: 'utf8'
   reconnect: true

Рецепт будет похож на следующий:

results = search(:node, "role:myapp_database_master AND chef_environment:#{node.chef_environment}")
db_master = results[0]

template '/srv/myapp/shared/database.yml' do
  source '/srv/myapp/current/config/database.yml.erb'
  local true
  variables(
    :rails_env => node.chef_environment,
    :adapter => db_master['myapp']['db_adapter'],
    :host => db_master['fqdn'],
    :database => "myapp_#{node.chef_environment}",
    :username => "myapp",
    :password => "SUPERSECRET",
  )
end

где:

  • метод search в языке Chef Infra используется для поиска первого узла, являющегося мастером базы данных (которых должно быть только один)
  • свойство переменной :adapter также может потребовать, чтобы атрибут был задан в роли, которая затем определяет правильный адаптер

Шаблон будет отображен примерно так:

production:
  adapter: mysql
  host: domU-12-31-39-14-F1-C3.compute-1.internal
  database: myapp_production
  username: myapp
  password: SUPERSECRET
  encoding: utf8
  reconnect: true

Этот пример показал, как использовать ресурс шаблона для отображения шаблона на основе настроек, содержащихся в локальном файле. Некоторые другие проблемы, которые следует учитывать при использовании такого подхода, включают:

  • Должен ли файл database.yml находиться в файле .gitignore?
  • Как разработчики запускают приложение локально?
  • Работает ли это с chef-solo?

Передача значений из рецепта в шаблон

Следующий пример показывает, как передать значение в шаблон, используя свойство variables в ресурсе шаблона. Файл шаблона похож на:

[tcpout]
defaultGroup = splunk_indexers_<%= node['splunk']['receiver_port'] %>
disabled=false

[tcpout:splunk_indexers_<%= node['splunk']['receiver_port'] %>]
server=<% @splunk_servers.map  do |s| -%><%= s['ipaddress'] %>:<%= s['splunk']['receiver_port'] %> <% end.join(', ') -%>
<% @outputs_conf.each_pair do |name, value| -%>
<%= name %> = <%= value %>
<% end  -%>

Затем рецепт использует атрибут variables, чтобы найти значения для splunk_servers и outputs_conf, прежде чем передать их в шаблон:

template "#{splunk_dir}/etc/system/local/outputs.conf" do
  source 'outputs.conf.erb'
  mode '0755'
  variables :splunk_servers => splunk_servers, :outputs_conf => node['splunk']['outputs_conf']
  notifies :restart, 'service[splunk]'
end

Этот пример можно найти в рецепте client.rb и файлах шаблонов outputs.conf.erb, которые находятся в кулинарной книге chef-splunk, поддерживаемой 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/resources/template/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API