Общие возможности ресурсов
Все ресурсы (включая пользовательские ресурсы) используют набор общих действий, свойств, условных выполнений, уведомлений и опций относительных путей.
Действия
Следующие действия можно использовать с любым ресурсом:
:nothing-
Этот блок ресурса не выполняет действий, пока другой ресурс не уведомит его о необходимости выполнить действие. После уведомления, этот блок ресурса либо выполняется немедленно, либо добавляется в очередь для выполнения в конце выполнения Клиента Chef Infra.
Примеры
В следующих примерах показано, как использовать общие действия в рецепте.
Использование действия :nothing
service 'memcached' do
action :nothing
end
Свойства
Следующие свойства общие для всех ресурсов:
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.
Примеры
В следующих примерах показано, как использовать общие свойства в рецепте.
Использование общего свойства ignore_failure
gem_package 'syntax' do
action :install
ignore_failure true
end
Использование общих свойств retries и retry_delay
service 'apache' do
action [ :enable, :start ]
retries 3
retry_delay 5
end
Фильтры
Свойство фильтра может быть использовано для оценки состояния узла во время фазы выполнения работы Клиента Chef Infra. На основе результатов этой оценки свойство фильтра затем используется для указания Клиенту Chef Infra, следует ли продолжить выполнение ресурса. Свойство фильтра принимает либо строковое значение, либо значение блока Ruby:
- Строка выполняется как команда оболочки. Если команда возвращает
0, фильтр применяется. Если команда возвращает любое другое значение, то свойство фильтра не применяется. Строковые фильтры в powershell_script выполняют команды Windows PowerShell и могут возвращатьtrueв дополнение к0. - Блок выполняется как код Ruby, который должен возвращать либо
true, либоfalse. Если блок возвращаетtrue, свойство фильтра применяется. Если блок возвращаетfalse, свойство фильтра не применяется.
Свойство фильтра полезно для обеспечения идемпотентности ресурса, позволяя этому ресурсу проверять желаемое состояние по мере его выполнения, а затем, если желаемое состояние присутствует, Клиент Chef Infra ничего не делает.
Примечание
При использовании фильтров not_if и only_if с ресурсом execute среда фильтра наследуется из среды ресурса. Например:
execute 'bundle install' do
cwd '/myapp'
not_if 'bundle check' # This is run from /myapp
end
Свойства
Следующие свойства могут быть использованы для определения фильтра, который оценивается в фазе выполнения Клиента Chef Infra:
not_if-
Запретить выполнение ресурса, когда условие возвращает
true. only_if-
Разрешить выполнение ресурса только в том случае, если условие возвращает
true.
Аргументы
Следующие аргументы можно использовать со свойствами фильтра not_if или only_if:
:user-
Указывает пользователя, от имени которого будет выполняться команда. Например:
not_if 'grep adam /etc/passwd', user: 'adam' :group-
Указывает группу, от имени которой будет выполняться команда. Например:
not_if 'grep adam /etc/passwd', group: 'adam' :environment-
Указывает хэш переменных среды, которые необходимо установить. Например:
not_if 'grep adam /etc/passwd', environment: { 'HOME' => '/home/adam', } :cwd-
Устанавливает текущую рабочую директорию перед запуском команды. Например:
not_if 'grep adam passwd', cwd: '/etc' :timeout-
Устанавливает таймаут для команды. Например:
not_if 'sleep 10000', timeout: 10
Примеры not_if
Обновление, если еще не обновлено
Следующий пример демонстрирует, как использовать not_if для предотвращения выполнения команды apt-get-update, когда файл уже существует и совпадает с обновляемым файлом:
execute 'apt-get-update' do
command 'apt-get update'
ignore_failure true
not_if { ::File.exist?('/var/lib/apt/periodic/update-success-stamp') }
end
Убедиться, что узел может разрешить хост
Следующий пример демонстрирует, как использовать пользовательский блок кода Ruby для обеспечения того, что узел может разрешить хост. Если узел может разрешить хост, Клиент Chef Infra ничего не сделает. Если узел не может разрешить хост, Клиент Chef Infra сконфигурирует хост:
ruby_block 'ensure node can resolve API FQDN' do
block do
fe = Chef::Util::FileEdit.new('/etc/hosts')
fe.insert_line_if_no_match(/#{node['chef-server']['api_fqdn']}/,
"127.0.0.1 #{node['chef-server']['api_fqdn']}")
fe.write_file
end
not_if { Resolv.getaddress(node['chef-server']['api_fqdn']) rescue false }
end
Предотвращение установки на более старых версиях
Следующий пример демонстрирует, как использовать not_if для предотвращения установки ZeroMQ, когда узел имеет версию Red Hat Enterprise Linux, младше версии 6.0:
ark 'test_autogen' do
url 'https://github.com/zeromq/libzmq/tarball/master'
extension 'tar.gz'
action :configure
not_if { platform_family?('rhel') && node['platform_version'].to_f < 6.0 }
end
Установить администратора, если он еще не установлен
Следующий пример демонстрирует, как установить администратора для Nagios на нескольких узлах, за исключением случаев, когда пакет уже существует на узле:
%w(adminpassword adminpassword-repeat).each do |setting|
execute "debconf-set-selections::#{node['nagios']['server']['vname']}-cgi::#{node['nagios']['server']['vname']}/#{setting}" do
command "echo #{node['nagios']['server']['vname']}-cgi #{node['nagios']['server']['vname']}/#{setting} password #{random_initial_password} | debconf-set-selections"
not_if "dpkg -l #{node['nagios']['server']['vname']}"
end
end
Примеры only_if
Установка пакетов только при необходимости
Следующий пример демонстрирует, как использовать only_if с одним (или несколькими) атрибутами кулинарной книги, чтобы убедиться, что пакеты устанавливаются только при необходимости. В этом случае три атрибута существуют в файле /attributes/default.rb: use_openssl, use_pcre и use_zlib. Каждый из этих атрибутов определен как false по умолчанию. Атрибуты only_if используются для проверки наличия этих пакетов на целевом узле перед тем, как попросить Клиента Chef Infra выполнить процесс установки этих пакетов. Если пакеты уже присутствуют, Клиент Chef Infra ничего не сделает.
package 'libpcre3-dev' do
only_if { node['haproxy']['source']['use_pcre'] }
end
package 'libssl-dev' do
only_if { node['haproxy']['source']['use_openssl'] }
end
package 'zlib1g-dev' do
only_if { node['haproxy']['source']['use_zlib'] }
end
Удаление рецепта, если он принадлежит определенному списку запусков
Следующий пример демонстрирует, как использовать only_if для удаления только рецепта с именем recipe[ntp::undo], но только тогда, когда этот рецепт является частью списка запусков recipe[ntp::default]:
ruby_block 'remove ntp::undo from run list' do
block do
node.run_list.remove('recipe[ntp::undo]')
end
only_if { node.run_list.include?('recipe[ntp::default]') }
end
Повторная регистрация ASP.Net, если она уже установлена
Следующий пример демонстрирует, как использовать only_if для обеспечения того, что Клиент Chef Infra попытается зарегистрировать ASP.NET только в том случае, если исполняемый файл установлен в системе, как на 32-, так и на 64-разрядных системах:
aspnet_regiis = "#{ENV['WinDir']}\\Microsoft.NET\\Framework\\v4.0.30319\\aspnet_regiis.exe"
execute 'Register ASP.NET v4' do
command "#{aspnet_regiis} -i"
only_if { ::File.exist?(aspnet_regiis) }
action :nothing
end
aspnet_regiis64 = "#{ENV['WinDir']}\\Microsoft.NET\\Framework64\\v4.0.30319\\aspnet_regiis.exe"
execute 'Register ASP.NET v4 (x64)' do
command "#{aspnet_regiis64} -i"
only_if { ::File.exist?(aspnet_regiis64) }
action :nothing
end
Интерпретаторы фильтров
Любой ресурс, который передает строковую команду, также может указать интерпретатор, который будет использоваться для оценки этой строковой команды. Это делается с помощью свойства guard_interpreter для указания ресурса на основе script.
Атрибуты
Свойство guard_interpreter может быть установлено в любое из следующих значений:
:bash-
Оценивает строковую команду с использованием ресурса bash.
:batch-
Оценивает строковую команду с использованием ресурса batch. Значение по умолчанию (внутри блока ресурса batch):
:batch. :csh-
Оценивает строковую команду с использованием ресурса csh.
:default-
По умолчанию. Выполняет интерпретатор по умолчанию, как определено Клиентом Chef Infra.
:perl-
Оценивает строковую команду с использованием ресурса perl.
:powershell_script-
Оценивает строковую команду с использованием ресурса powershell_script. Значение по умолчанию (внутри блока ресурса powershell_script):
:powershell_script. :python-
Оценивает строковую команду с использованием ресурса python.
:ruby-
Оценивает строковую команду с использованием ресурса ruby.
Наследование
Свойство guard_interpreter по умолчанию установлено в :default для ресурсов bash, csh, perl, python и ruby. Когда свойство guard_interpreter установлено в :default, not_if или only_if операторы фильтра не наследуют свойства, определенные ресурсом на основе script.
Предупреждение
Ресурсы batch и powershell_script наследуют свойства по умолчанию. Свойство guard_interpreter устанавливается в :batch или :powershell_script автоматически при использовании операторов фильтра not_if или only_if внутри ресурсов batch или powershell_script соответственно.
Например, оператор фильтра not_if в следующем примере ресурса не наследует свойство environment:
bash 'javatooling' do
environment 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
code 'java-based-daemon-ctl.sh -start'
not_if 'java-based-daemon-ctl.sh -test-started'
end
и требует добавления свойства environment в инструкцию not_if, чтобы она могла использовать путь JAVA_HOME в качестве части своего вычисления:
bash 'javatooling' do
environment 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
code 'java-based-daemon-ctl.sh -start'
not_if 'java-based-daemon-ctl.sh -test-started', :environment => 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
end
Чтобы унаследовать свойства, добавьте свойство guard_interpreter в блок ресурса и установите его в соответствующее значение:
-
:bashдля bash -
:cshдля csh -
:perlдля perl -
:pythonдля python -
:rubyдля ruby
Например, используя тот же пример, что и выше, но на этот раз добавляя свойство guard_interpreter и устанавливая его в значение :bash:
bash 'javatooling' do
guard_interpreter :bash
environment 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
code 'java-based-daemon-ctl.sh -start'
not_if 'java-based-daemon-ctl.sh -test-started'
end
Инструкция not_if теперь наследует свойство environment и будет использовать путь JAVA_HOME в качестве части своего вычисления.
Примеры
Например, следующий блок кода гарантирует, что команда будет вычислена с использованием интерпретатора по умолчанию, определенного клиентом Chef Infra:
resource 'name' do
guard_interpreter :default
# code
end
Ленивое вычисление
В некоторых случаях значение свойства неизвестно до фазы выполнения работы клиента Chef Infra. В этой ситуации может быть полезно использовать ленивое вычисление значений свойств. Вместо присвоения значения свойству, можно присвоить блок кода. Синтаксис для использования ленивого вычисления следующий:
property_name lazy { code_block }
где lazy используется для указания клиенту Chef Infra выполнить содержимое блока кода позже в процессе оценки ресурса (а не сразу), а { code_block } — произвольный Ruby-код, предоставляющий значение.
Например, ресурс, который не использует ленивое вычисление:
template 'template_name' do
# some properties
path '/foo/bar'
end
и блок ресурса, использующий ленивое вычисление:
template 'template_name' do
# some properties
path lazy { ' some Ruby code ' }
end
В предыдущих примерах первый ресурс использует значение /foo/bar, а второй ресурс использует значение, предоставленное блоком кода, если содержимое этого блока кода является допустимым свойством ресурса.
Следующий пример показывает, как использовать ленивое вычисление с переменными шаблонов:
template '/tmp/canvey_island.txt' do
source 'canvey_island.txt.erb'
variables(
lazy do
{ canvey_island: node.run_state['sea_power'] }
end
)
end
Уведомления
Уведомление — это свойство ресурса, которое отслеживает другие ресурсы в коллекции ресурсов, а затем выполняет действия на основе типа уведомления (notifies или subscribes).
Таймеры
Таймер определяет момент во время выполнения клиента Chef Infra, в котором выполняется уведомление. Доступны следующие таймеры:
:before-
Указывает, что действие над уведомленным ресурсом должно быть выполнено до обработки блока ресурса, в котором находится уведомление.
:delayed-
По умолчанию. Указывает, что уведомление должно быть помещено в очередь и затем выполнено в конце выполнения клиента Chef Infra.
-
:immediate,:immediately -
Указывает, что уведомление должно быть выполнено немедленно, по каждому уведомленному ресурсу.
Уведомления
Ресурс может уведомить другой ресурс о выполнении действия при изменении его состояния. Укажите 'resource[name]', действие, которое должен выполнить ресурс, а затем :timer для этого действия. Ресурс может уведомить более одного ресурса; используйте инструкцию notifies для каждого уведомляемого ресурса.
Если указанный ресурс отсутствует, возникает ошибка. В отличие от этого, subscribes не завершится ошибкой, если исходный ресурс не найден.
Синтаксис для notifies:
notifies :action, 'resource[name]', :timer
Изменено в Chef Client 12.6 на использование таймера :before со свойствами notifies и subscribes, чтобы указать, что действие над уведомленным ресурсом должно быть выполнено до обработки блока ресурса, в котором находится уведомление.
Примеры
Следующие примеры показывают, как использовать уведомление notifies в рецепте.
Задержка уведомлений
template '/etc/nagios3/configures-nagios.conf' do
# other parameters
notifies :run, 'execute[test-nagios-config]', :delayed
end
Немедленное уведомление
По умолчанию уведомления :delayed, то есть они помещаются в очередь по мере возникновения, а затем выполняются в самом конце выполнения клиента Chef Infra. Чтобы выполнить действие немедленно, используйте :immediately:
template '/etc/nagios3/configures-nagios.conf' do
# other parameters
notifies :run, 'execute[test-nagios-config]', :immediately
end
и затем клиент Chef Infra немедленно выполнит следующее:
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-elasticsearch]', :delayed
notifies :restart, 'service[chef-server]', :delayed
end
Уведомление в определенном порядке
Чтобы уведомить несколько ресурсов и затем выполнить эти ресурсы в определенном порядке, сделайте следующее:
execute 'foo' do
command '...'
notifies :create, 'template[baz]', :immediately
notifies :install, 'package[bar]', :immediately
notifies :run, 'execute[final]', :immediately
end
template 'baz' do
...
notifies :run, 'execute[restart_baz]', :immediately
end
package 'bar'
execute 'restart_baz'
execute 'final' do
command '...'
end
где порядок будет таким же, как порядок ресурсов в рецепте: execute 'foo', template 'baz', execute [restart_baz], package 'bar' и execute 'final'.
Перезагрузка сервиса
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-пересылку пакетов с использованием ресурса 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.
Перезапуск службы, а затем уведомление другой службы
Следующий пример показывает, как запустить службу example_service и немедленно уведомить службу Nginx о перезапуске.
service 'example_service' do
action :start
notifies :restart, 'service[nginx]', :immediately
end
Перезапуск одной службы до перезапуска другой
В этом примере уведомление :before используется для перезапуска службы php-fpm перед перезапуском службы nginx:
service 'nginx' do
action :restart
notifies :restart, 'service[php-fpm]', :before
end
С уведомлением :before действие, указанное для ресурса nginx, не будет выполнено до тех пор, пока не будет выполнено действие над уведомленным ресурсом (php-fpm).
Уведомление при изменении удаленного источника
remote_file '/tmp/couch.png' do
source 'http://couchdb.apache.org/img/sketch.png'
action :nothing
end
http_request 'HEAD http://couchdb.apache.org/img/sketch.png' do
message ''
url 'http://couchdb.apache.org/img/sketch.png'
action :head
if ::File.exist?('/tmp/couch.png')
headers 'If-Modified-Since' => File.mtime('/tmp/couch.png').httpdate
end
notifies :create, 'remote_file[/tmp/couch.png]', :immediately
end
Подписки
Ресурс может отслеживать другой ресурс и затем предпринимать действия, если состояние отслеживаемого ресурса изменится. Укажите 'resource[name]', действие, которое необходимо выполнить, и затем :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 вызовет ошибку, если другой ресурс не существует.
Синтаксис для subscribes:
subscribes :action, 'resource[name]', :timer
Примеры
Следующие примеры показывают, как использовать уведомление subscribes в рецепте.
Проверка обновления конфигурации
Используйте действие :nothing (общее для всех ресурсов) для предотвращения автоматического запуска теста, а затем уведомление subscribes для выполнения теста конфигурации при обнаружении изменений в шаблоне:
execute 'test-nagios-config' do
command 'nagios3 --verify-config'
action :nothing
subscribes :run, 'template[/etc/nagios3/configures-nagios.conf]', :immediately
end
Перезагрузка сервиса при обновлении шаблона
Чтобы перезагрузить службу, основанную на шаблоне, используйте ресурсы template и service вместе в одном рецепте, примерно так:
template '/tmp/somefile' do
mode '0755'
source 'somefile.erb'
end
service 'apache' do
action :enable
subscribes :reload, 'template[/tmp/somefile]', :immediately
end
где уведомление subscribes используется для перезагрузки службы всякий раз, когда шаблон изменяется.
Относительные пути
Следующие относительные пути могут использоваться с любым ресурсом:
#{ENV['HOME']}-
Используется для возвращения пути
~в Linux и macOS или пути%HOMEPATH%в Microsoft Windows.
Примеры
template "#{ENV['HOME']}/chef-getting-started.txt" do
source 'chef-getting-started.txt.erb'
mode '0755'
end
Выполнение в фазе компиляции
Клиент Chef Infra обрабатывает рецепты в двух фазах:
- Сначала каждый ресурс в объекте узла идентифицируется, и создается коллекция ресурсов. Все рецепты загружаются в определенном порядке, а затем определяются действия, указанные в каждом из них. Это также называется «фазой компиляции».
- Затем клиент Chef Infra настраивает систему в соответствии с порядком ресурсов в коллекции ресурсов. Каждый ресурс затем проверяет узел и выполняет необходимые шаги для завершения действия. Это также называется «фазой выполнения».
Обычно действия обрабатываются во время фазы выполнения работы клиента Chef Infra. Однако иногда необходимо выполнить действие во время фазы компиляции. Например, ресурс может быть настроен на установку пакета во время фазы компиляции, чтобы убедиться, что приложение доступно другим ресурсам во время фазы выполнения.
Примечание
Используйте ресурс chef_gem для установки необходимых gem для Chef Infra Client во время фазы выполнения.
Использование свойства compile_time
Используйте .run_action(:some_action) в конце блока ресурса для запуска указанного действия во время компиляции. Например:
build_essential 'Install compilers' do
action :nothing
end.run_action(:install)
где action установлено в значение :nothing, чтобы гарантировать, что run_action будет запущен во время компиляции, а не позже во время выполнения.
Это можно упростить, используя флаг compile_time в Chef Infra Client 16 и более поздних версиях:
build_essential 'Install compilers' do
compile_time true
end
Этот флаг одновременно принуждает ресурс к запуску во время компиляции и устанавливает действие конвергенции в :nothing.
Следующие примеры показывают, когда (и когда не) использовать run_action.
Использование пользовательских ресурсов предпочтительнее принудительного запуска во время компиляции
Выполнение во время компиляции часто используется для установки gem перед их использованием в коде рецепта.
Это плохая практика, так как gem могут зависеть от нативных gem, которые могут потребовать установки компиляторов во время компиляции.
build_essential 'Install compilers' do
compile_time true
end
chef_gem 'aws-dsk' do
compile_time true
end
require 'aws-sdk'
Лучшая стратегия — перенести код, требующий gem, в пользовательский ресурс. Поскольку все действия пользовательских ресурсов выполняются во время конвергенции, это откладывает требование к gem до более позднего этапа выполнения Chef Infra Client. Режим унификации также может быть использован в ресурсе для полного устранения проблем с режимами компиляции/конвергенции:
unified_mode true
action :run do
build_essential 'Install compilers'
chef_gem 'aws-sdk'
require 'aws-sdk'
end
Загрузка и обработка файла конфигурации
Распространённый случай — загрузка файла конфигурации, его обработка и использование значений в шаблонах и для управления другими конфигурациями.
Важно отметить, что загруженный файл конфигурации существует только в временном состоянии для использования Chef Infra Client. Он не будет использоваться непосредственно системой или приложениями, управляемыми Chef Infra Client.
Для загрузки и обработки JSON-файла и его рендеринга в шаблоне целесообразно загрузить файл во время компиляции:
# the remote_file is being downloaded to a temporary file
remote_file "#{Chef::Config[:file_cache_path]}/users.json" do
source "https://jsonplaceholder.typicode.com/users"
compile_time true
end
# this parsing needs to happen after the remote_file is downloaded, but will
# be executed at compile time.
array = JSON.parse(IO.read("#{Chef::Config[:file_cache_path]}/users.json")
# the `array.last["phone"]` expression here will also be evaluated at compile
# time and must be lazied via wrapping the expresssion in `lazy {}`
file "/tmp/phone_number.txt" do
content array.last["phone"]
end
Это значительно чище, чем альтернативный вариант ленивой оценки как обработки JSON, так и рендеринга данных в шаблон файла, что произойдёт, если ресурс remote_file не запускается во время компиляции:
# the execution of this is now deferred
remote_file "#{Chef::Config[:file_cache_path]}/users.json" do
source "https://jsonplaceholder.typicode.com/users"
end
# it is necessary due to lexical scoping issues to create this variable here
array = nil
# the parsing of the JSON is now deferred due to the ruby_block
ruby_block "parse JSON" do
block do
array = JSON.parse(IO.read("#{Chef::Config[:file_cache_path]}/users.json")
end
end
# the argument to the content property must now also be deferred
file "/tmp/phone_number.txt" do
content lazy { array.last["phone"] }
end
Это пример кода, который чрезмерно использует отложенное выполнение, использует больше «ленивых» вычислений и значительно сложнее для понимания и правильного написания.
Уведомления не будут работать
Ресурсы, которые выполняются во время компиляции, не могут уведомлять другие ресурсы. Например:
execute 'ifconfig'
package 'vim-enhanced' do
compile_time true
notifies :run, 'execute[ifconfig]', :immediately
end
Лучший подход в такой ситуации — установить пакет до построения коллекции ресурсов, чтобы убедиться, что он доступен другим ресурсам позже.
Лучший подход к этой проблеме — использование unified mode, которое устраняет различие между фазами компиляции и конвергенции, позволяя уведомлениям работать корректно.
Ресурсы, которые по умолчанию принудительно выполняются во время компиляции
Ресурсы ohai_hint и hostname по умолчанию выполняются во время компиляции.
Это связано с тем, что последующие ресурсы могут использовать атрибуты узла, которые устанавливаются этими ресурсами, что приводит к чрезмерному использованию lazy в последующих ресурсах (и аналогичным проблемам с примером remote_file выше).
Ресурс chef_gem ранее выполнялся во время компиляции по умолчанию, но сейчас рекомендуется пользователям переносить код, выполняющийся во время компиляции, в пользовательские ресурсы.
Безопасность файлов 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, что гарантирует, что настройки безопасности существующих файлов останутся неизменными.
© 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/resource_common/